diff --git a/openvidu-browser/static/js/openvidu-browser-1.1.1-dev.js b/openvidu-browser/static/js/openvidu-browser-1.1.1-dev.js index b129098c..da53b2a4 100644 --- a/openvidu-browser/static/js/openvidu-browser-1.1.1-dev.js +++ b/openvidu-browser/static/js/openvidu-browser-1.1.1-dev.js @@ -447,7 +447,10 @@ function getMaxVolume (analyser, fftBins) { } -var audioContextType = window.AudioContext || window.webkitAudioContext; +var audioContextType; +if (typeof window !== 'undefined') { + audioContextType = window.AudioContext || window.webkitAudioContext; +} // use a single audio context due to hardware limits var audioContext = null; module.exports = function(stream, options) { @@ -475,7 +478,7 @@ module.exports = function(stream, options) { analyser = audioContext.createAnalyser(); analyser.fftSize = 512; analyser.smoothingTimeConstant = smoothing; - fftBins = new Float32Array(analyser.fftSize); + fftBins = new Float32Array(analyser.frequencyBinCount); if (stream.jquery) stream = stream[0]; if (stream instanceof HTMLAudioElement || stream instanceof HTMLVideoElement) { @@ -501,7 +504,7 @@ module.exports = function(stream, options) { harker.setInterval = function(i) { interval = i; }; - + harker.stop = function() { running = false; harker.emit('volume_change', -100, threshold); @@ -509,6 +512,8 @@ module.exports = function(stream, options) { harker.speaking = false; harker.emit('stopped_speaking'); } + analyser.disconnect(); + sourceNode.disconnect(); }; harker.speakingHistory = []; for (var i = 0; i < history; i++) { @@ -519,12 +524,12 @@ module.exports = function(stream, options) { // and emit events if changed var looper = function() { setTimeout(function() { - + //check if stop has been called if(!running) { return; } - + var currentVolume = getMaxVolume(analyser, fftBins); harker.emit('volume_change', currentVolume, threshold); @@ -560,7 +565,7 @@ module.exports = function(stream, options) { return harker; } -},{"wildemitter":33}],6:[function(require,module,exports){ +},{"wildemitter":31}],6:[function(require,module,exports){ if (typeof Object.create === 'function') { // implementation from standard node.js 'util' module module.exports = function inherits(ctor, superCtor) { @@ -824,1566 +829,6 @@ module.exports = function(input) { }; },{}],9:[function(require,module,exports){ -/* - * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. - */ - /* eslint-env node */ -'use strict'; - -var SDPUtils = require('sdp'); - -function writeMediaSection(transceiver, caps, type, stream, dtlsRole) { - var sdp = SDPUtils.writeRtpDescription(transceiver.kind, caps); - - // Map ICE parameters (ufrag, pwd) to SDP. - sdp += SDPUtils.writeIceParameters( - transceiver.iceGatherer.getLocalParameters()); - - // Map DTLS parameters to SDP. - sdp += SDPUtils.writeDtlsParameters( - transceiver.dtlsTransport.getLocalParameters(), - type === 'offer' ? 'actpass' : dtlsRole || 'active'); - - sdp += 'a=mid:' + transceiver.mid + '\r\n'; - - if (transceiver.direction) { - sdp += 'a=' + transceiver.direction + '\r\n'; - } else if (transceiver.rtpSender && transceiver.rtpReceiver) { - sdp += 'a=sendrecv\r\n'; - } else if (transceiver.rtpSender) { - sdp += 'a=sendonly\r\n'; - } else if (transceiver.rtpReceiver) { - sdp += 'a=recvonly\r\n'; - } else { - sdp += 'a=inactive\r\n'; - } - - if (transceiver.rtpSender) { - // spec. - var msid = 'msid:' + stream.id + ' ' + - transceiver.rtpSender.track.id + '\r\n'; - sdp += 'a=' + msid; - - // for Chrome. - sdp += 'a=ssrc:' + transceiver.sendEncodingParameters[0].ssrc + - ' ' + msid; - if (transceiver.sendEncodingParameters[0].rtx) { - sdp += 'a=ssrc:' + transceiver.sendEncodingParameters[0].rtx.ssrc + - ' ' + msid; - sdp += 'a=ssrc-group:FID ' + - transceiver.sendEncodingParameters[0].ssrc + ' ' + - transceiver.sendEncodingParameters[0].rtx.ssrc + - '\r\n'; - } - } - // FIXME: this should be written by writeRtpDescription. - sdp += 'a=ssrc:' + transceiver.sendEncodingParameters[0].ssrc + - ' cname:' + SDPUtils.localCName + '\r\n'; - if (transceiver.rtpSender && transceiver.sendEncodingParameters[0].rtx) { - sdp += 'a=ssrc:' + transceiver.sendEncodingParameters[0].rtx.ssrc + - ' cname:' + SDPUtils.localCName + '\r\n'; - } - return sdp; -} - -// Edge does not like -// 1) stun: filtered after 14393 unless ?transport=udp is present -// 2) turn: that does not have all of turn:host:port?transport=udp -// 3) turn: with ipv6 addresses -// 4) turn: occurring muliple times -function filterIceServers(iceServers, edgeVersion) { - var hasTurn = false; - iceServers = JSON.parse(JSON.stringify(iceServers)); - return iceServers.filter(function(server) { - if (server && (server.urls || server.url)) { - var urls = server.urls || server.url; - if (server.url && !server.urls) { - console.warn('RTCIceServer.url is deprecated! Use urls instead.'); - } - var isString = typeof urls === 'string'; - if (isString) { - urls = [urls]; - } - urls = urls.filter(function(url) { - var validTurn = url.indexOf('turn:') === 0 && - url.indexOf('transport=udp') !== -1 && - url.indexOf('turn:[') === -1 && - !hasTurn; - - if (validTurn) { - hasTurn = true; - return true; - } - return url.indexOf('stun:') === 0 && edgeVersion >= 14393 && - url.indexOf('?transport=udp') === -1; - }); - - delete server.url; - server.urls = isString ? urls[0] : urls; - return !!urls.length; - } - return false; - }); -} - -// Determines the intersection of local and remote capabilities. -function getCommonCapabilities(localCapabilities, remoteCapabilities) { - var commonCapabilities = { - codecs: [], - headerExtensions: [], - fecMechanisms: [] - }; - - var findCodecByPayloadType = function(pt, codecs) { - pt = parseInt(pt, 10); - for (var i = 0; i < codecs.length; i++) { - if (codecs[i].payloadType === pt || - codecs[i].preferredPayloadType === pt) { - return codecs[i]; - } - } - }; - - var rtxCapabilityMatches = function(lRtx, rRtx, lCodecs, rCodecs) { - var lCodec = findCodecByPayloadType(lRtx.parameters.apt, lCodecs); - var rCodec = findCodecByPayloadType(rRtx.parameters.apt, rCodecs); - return lCodec && rCodec && - lCodec.name.toLowerCase() === rCodec.name.toLowerCase(); - }; - - localCapabilities.codecs.forEach(function(lCodec) { - for (var i = 0; i < remoteCapabilities.codecs.length; i++) { - var rCodec = remoteCapabilities.codecs[i]; - if (lCodec.name.toLowerCase() === rCodec.name.toLowerCase() && - lCodec.clockRate === rCodec.clockRate) { - if (lCodec.name.toLowerCase() === 'rtx' && - lCodec.parameters && rCodec.parameters.apt) { - // for RTX we need to find the local rtx that has a apt - // which points to the same local codec as the remote one. - if (!rtxCapabilityMatches(lCodec, rCodec, - localCapabilities.codecs, remoteCapabilities.codecs)) { - continue; - } - } - rCodec = JSON.parse(JSON.stringify(rCodec)); // deepcopy - // number of channels is the highest common number of channels - rCodec.numChannels = Math.min(lCodec.numChannels, - rCodec.numChannels); - // push rCodec so we reply with offerer payload type - commonCapabilities.codecs.push(rCodec); - - // determine common feedback mechanisms - rCodec.rtcpFeedback = rCodec.rtcpFeedback.filter(function(fb) { - for (var j = 0; j < lCodec.rtcpFeedback.length; j++) { - if (lCodec.rtcpFeedback[j].type === fb.type && - lCodec.rtcpFeedback[j].parameter === fb.parameter) { - return true; - } - } - return false; - }); - // FIXME: also need to determine .parameters - // see https://github.com/openpeer/ortc/issues/569 - break; - } - } - }); - - localCapabilities.headerExtensions.forEach(function(lHeaderExtension) { - for (var i = 0; i < remoteCapabilities.headerExtensions.length; - i++) { - var rHeaderExtension = remoteCapabilities.headerExtensions[i]; - if (lHeaderExtension.uri === rHeaderExtension.uri) { - commonCapabilities.headerExtensions.push(rHeaderExtension); - break; - } - } - }); - - // FIXME: fecMechanisms - return commonCapabilities; -} - -// is action=setLocalDescription with type allowed in signalingState -function isActionAllowedInSignalingState(action, type, signalingState) { - return { - offer: { - setLocalDescription: ['stable', 'have-local-offer'], - setRemoteDescription: ['stable', 'have-remote-offer'] - }, - answer: { - setLocalDescription: ['have-remote-offer', 'have-local-pranswer'], - setRemoteDescription: ['have-local-offer', 'have-remote-pranswer'] - } - }[type][action].indexOf(signalingState) !== -1; -} - -function maybeAddCandidate(iceTransport, candidate) { - // Edge's internal representation adds some fields therefore - // not all fieldѕ are taken into account. - var alreadyAdded = iceTransport.getRemoteCandidates() - .find(function(remoteCandidate) { - return candidate.foundation === remoteCandidate.foundation && - candidate.ip === remoteCandidate.ip && - candidate.port === remoteCandidate.port && - candidate.priority === remoteCandidate.priority && - candidate.protocol === remoteCandidate.protocol && - candidate.type === remoteCandidate.type; - }); - if (!alreadyAdded) { - iceTransport.addRemoteCandidate(candidate); - } - return !alreadyAdded; -} - -module.exports = function(window, edgeVersion) { - var RTCPeerConnection = function(config) { - var self = this; - - var _eventTarget = document.createDocumentFragment(); - ['addEventListener', 'removeEventListener', 'dispatchEvent'] - .forEach(function(method) { - self[method] = _eventTarget[method].bind(_eventTarget); - }); - - this.onicecandidate = null; - this.onaddstream = null; - this.ontrack = null; - this.onremovestream = null; - this.onsignalingstatechange = null; - this.oniceconnectionstatechange = null; - this.onicegatheringstatechange = null; - this.onnegotiationneeded = null; - this.ondatachannel = null; - this.canTrickleIceCandidates = null; - - this.needNegotiation = false; - - this.localStreams = []; - this.remoteStreams = []; - - this.localDescription = null; - this.remoteDescription = null; - - this.signalingState = 'stable'; - this.iceConnectionState = 'new'; - this.iceGatheringState = 'new'; - - config = JSON.parse(JSON.stringify(config || {})); - - this.usingBundle = config.bundlePolicy === 'max-bundle'; - if (config.rtcpMuxPolicy === 'negotiate') { - var e = new Error('rtcpMuxPolicy \'negotiate\' is not supported'); - e.name = 'NotSupportedError'; - throw(e); - } else if (!config.rtcpMuxPolicy) { - config.rtcpMuxPolicy = 'require'; - } - - switch (config.iceTransportPolicy) { - case 'all': - case 'relay': - break; - default: - config.iceTransportPolicy = 'all'; - break; - } - - switch (config.bundlePolicy) { - case 'balanced': - case 'max-compat': - case 'max-bundle': - break; - default: - config.bundlePolicy = 'balanced'; - break; - } - - config.iceServers = filterIceServers(config.iceServers || [], edgeVersion); - - this._iceGatherers = []; - if (config.iceCandidatePoolSize) { - for (var i = config.iceCandidatePoolSize; i > 0; i--) { - this._iceGatherers = new window.RTCIceGatherer({ - iceServers: config.iceServers, - gatherPolicy: config.iceTransportPolicy - }); - } - } else { - config.iceCandidatePoolSize = 0; - } - - this._config = config; - - // per-track iceGathers, iceTransports, dtlsTransports, rtpSenders, ... - // everything that is needed to describe a SDP m-line. - this.transceivers = []; - - this._sdpSessionId = SDPUtils.generateSessionId(); - this._sdpSessionVersion = 0; - - this._dtlsRole = undefined; // role for a=setup to use in answers. - }; - - RTCPeerConnection.prototype._emitGatheringStateChange = function() { - var event = new Event('icegatheringstatechange'); - this.dispatchEvent(event); - if (typeof this.onicegatheringstatechange === 'function') { - this.onicegatheringstatechange(event); - } - }; - - RTCPeerConnection.prototype.getConfiguration = function() { - return this._config; - }; - - RTCPeerConnection.prototype.getLocalStreams = function() { - return this.localStreams; - }; - - RTCPeerConnection.prototype.getRemoteStreams = function() { - return this.remoteStreams; - }; - - // internal helper to create a transceiver object. - // (whih is not yet the same as the WebRTC 1.0 transceiver) - RTCPeerConnection.prototype._createTransceiver = function(kind) { - var hasBundleTransport = this.transceivers.length > 0; - var transceiver = { - track: null, - iceGatherer: null, - iceTransport: null, - dtlsTransport: null, - localCapabilities: null, - remoteCapabilities: null, - rtpSender: null, - rtpReceiver: null, - kind: kind, - mid: null, - sendEncodingParameters: null, - recvEncodingParameters: null, - stream: null, - wantReceive: true - }; - if (this.usingBundle && hasBundleTransport) { - transceiver.iceTransport = this.transceivers[0].iceTransport; - transceiver.dtlsTransport = this.transceivers[0].dtlsTransport; - } else { - var transports = this._createIceAndDtlsTransports(); - transceiver.iceTransport = transports.iceTransport; - transceiver.dtlsTransport = transports.dtlsTransport; - } - this.transceivers.push(transceiver); - return transceiver; - }; - - RTCPeerConnection.prototype.addTrack = function(track, stream) { - var transceiver; - for (var i = 0; i < this.transceivers.length; i++) { - if (!this.transceivers[i].track && - this.transceivers[i].kind === track.kind) { - transceiver = this.transceivers[i]; - } - } - if (!transceiver) { - transceiver = this._createTransceiver(track.kind); - } - - this._maybeFireNegotiationNeeded(); - - if (this.localStreams.indexOf(stream) === -1) { - this.localStreams.push(stream); - } - - transceiver.track = track; - transceiver.stream = stream; - transceiver.rtpSender = new window.RTCRtpSender(track, - transceiver.dtlsTransport); - return transceiver.rtpSender; - }; - - RTCPeerConnection.prototype.addStream = function(stream) { - var self = this; - if (edgeVersion >= 15025) { - stream.getTracks().forEach(function(track) { - self.addTrack(track, stream); - }); - } else { - // Clone is necessary for local demos mostly, attaching directly - // to two different senders does not work (build 10547). - // Fixed in 15025 (or earlier) - var clonedStream = stream.clone(); - stream.getTracks().forEach(function(track, idx) { - var clonedTrack = clonedStream.getTracks()[idx]; - track.addEventListener('enabled', function(event) { - clonedTrack.enabled = event.enabled; - }); - }); - clonedStream.getTracks().forEach(function(track) { - self.addTrack(track, clonedStream); - }); - } - }; - - RTCPeerConnection.prototype.removeStream = function(stream) { - var idx = this.localStreams.indexOf(stream); - if (idx > -1) { - this.localStreams.splice(idx, 1); - this._maybeFireNegotiationNeeded(); - } - }; - - RTCPeerConnection.prototype.getSenders = function() { - return this.transceivers.filter(function(transceiver) { - return !!transceiver.rtpSender; - }) - .map(function(transceiver) { - return transceiver.rtpSender; - }); - }; - - RTCPeerConnection.prototype.getReceivers = function() { - return this.transceivers.filter(function(transceiver) { - return !!transceiver.rtpReceiver; - }) - .map(function(transceiver) { - return transceiver.rtpReceiver; - }); - }; - - - RTCPeerConnection.prototype._createIceGatherer = function(sdpMLineIndex, - usingBundle) { - var self = this; - if (usingBundle && sdpMLineIndex > 0) { - return this.transceivers[0].iceGatherer; - } else if (this._iceGatherers.length) { - return this._iceGatherers.shift(); - } - var iceGatherer = new window.RTCIceGatherer({ - iceServers: this._config.iceServers, - gatherPolicy: this._config.iceTransportPolicy - }); - Object.defineProperty(iceGatherer, 'state', - {value: 'new', writable: true} - ); - - this.transceivers[sdpMLineIndex].candidates = []; - this.transceivers[sdpMLineIndex].bufferCandidates = function(event) { - var end = !event.candidate || Object.keys(event.candidate).length === 0; - // polyfill since RTCIceGatherer.state is not implemented in - // Edge 10547 yet. - iceGatherer.state = end ? 'completed' : 'gathering'; - if (self.transceivers[sdpMLineIndex].candidates !== null) { - self.transceivers[sdpMLineIndex].candidates.push(event.candidate); - } - }; - iceGatherer.addEventListener('localcandidate', - this.transceivers[sdpMLineIndex].bufferCandidates); - return iceGatherer; - }; - - // start gathering from an RTCIceGatherer. - RTCPeerConnection.prototype._gather = function(mid, sdpMLineIndex) { - var self = this; - var iceGatherer = this.transceivers[sdpMLineIndex].iceGatherer; - if (iceGatherer.onlocalcandidate) { - return; - } - var candidates = this.transceivers[sdpMLineIndex].candidates; - this.transceivers[sdpMLineIndex].candidates = null; - iceGatherer.removeEventListener('localcandidate', - this.transceivers[sdpMLineIndex].bufferCandidates); - iceGatherer.onlocalcandidate = function(evt) { - if (self.usingBundle && sdpMLineIndex > 0) { - // if we know that we use bundle we can drop candidates with - // ѕdpMLineIndex > 0. If we don't do this then our state gets - // confused since we dispose the extra ice gatherer. - return; - } - var event = new Event('icecandidate'); - event.candidate = {sdpMid: mid, sdpMLineIndex: sdpMLineIndex}; - - var cand = evt.candidate; - // Edge emits an empty object for RTCIceCandidateComplete‥ - var end = !cand || Object.keys(cand).length === 0; - if (end) { - // polyfill since RTCIceGatherer.state is not implemented in - // Edge 10547 yet. - if (iceGatherer.state === 'new' || iceGatherer.state === 'gathering') { - iceGatherer.state = 'completed'; - } - } else { - if (iceGatherer.state === 'new') { - iceGatherer.state = 'gathering'; - } - // RTCIceCandidate doesn't have a component, needs to be added - cand.component = 1; - event.candidate.candidate = SDPUtils.writeCandidate(cand); - } - - // update local description. - var sections = SDPUtils.splitSections(self.localDescription.sdp); - if (!end) { - sections[event.candidate.sdpMLineIndex + 1] += - 'a=' + event.candidate.candidate + '\r\n'; - } else { - sections[event.candidate.sdpMLineIndex + 1] += - 'a=end-of-candidates\r\n'; - } - self.localDescription.sdp = sections.join(''); - var complete = self.transceivers.every(function(transceiver) { - return transceiver.iceGatherer && - transceiver.iceGatherer.state === 'completed'; - }); - - if (self.iceGatheringState !== 'gathering') { - self.iceGatheringState = 'gathering'; - self._emitGatheringStateChange(); - } - - // Emit candidate. Also emit null candidate when all gatherers are - // complete. - if (!end) { - self.dispatchEvent(event); - if (typeof self.onicecandidate === 'function') { - self.onicecandidate(event); - } - } - if (complete) { - self.dispatchEvent(new Event('icecandidate')); - if (typeof self.onicecandidate === 'function') { - self.onicecandidate(new Event('icecandidate')); - } - self.iceGatheringState = 'complete'; - self._emitGatheringStateChange(); - } - }; - - // emit already gathered candidates. - window.setTimeout(function() { - candidates.forEach(function(candidate) { - var e = new Event('RTCIceGatherEvent'); - e.candidate = candidate; - iceGatherer.onlocalcandidate(e); - }); - }, 0); - }; - - // Create ICE transport and DTLS transport. - RTCPeerConnection.prototype._createIceAndDtlsTransports = function() { - var self = this; - var iceTransport = new window.RTCIceTransport(null); - iceTransport.onicestatechange = function() { - self._updateConnectionState(); - }; - - var dtlsTransport = new window.RTCDtlsTransport(iceTransport); - dtlsTransport.ondtlsstatechange = function() { - self._updateConnectionState(); - }; - dtlsTransport.onerror = function() { - // onerror does not set state to failed by itself. - Object.defineProperty(dtlsTransport, 'state', - {value: 'failed', writable: true}); - self._updateConnectionState(); - }; - - return { - iceTransport: iceTransport, - dtlsTransport: dtlsTransport - }; - }; - - // Destroy ICE gatherer, ICE transport and DTLS transport. - // Without triggering the callbacks. - RTCPeerConnection.prototype._disposeIceAndDtlsTransports = function( - sdpMLineIndex) { - var iceGatherer = this.transceivers[sdpMLineIndex].iceGatherer; - if (iceGatherer) { - delete iceGatherer.onlocalcandidate; - delete this.transceivers[sdpMLineIndex].iceGatherer; - } - var iceTransport = this.transceivers[sdpMLineIndex].iceTransport; - if (iceTransport) { - delete iceTransport.onicestatechange; - delete this.transceivers[sdpMLineIndex].iceTransport; - } - var dtlsTransport = this.transceivers[sdpMLineIndex].dtlsTransport; - if (dtlsTransport) { - delete dtlsTransport.ondtlsstatechange; - delete dtlsTransport.onerror; - delete this.transceivers[sdpMLineIndex].dtlsTransport; - } - }; - - // Start the RTP Sender and Receiver for a transceiver. - RTCPeerConnection.prototype._transceive = function(transceiver, - send, recv) { - var params = getCommonCapabilities(transceiver.localCapabilities, - transceiver.remoteCapabilities); - if (send && transceiver.rtpSender) { - params.encodings = transceiver.sendEncodingParameters; - params.rtcp = { - cname: SDPUtils.localCName, - compound: transceiver.rtcpParameters.compound - }; - if (transceiver.recvEncodingParameters.length) { - params.rtcp.ssrc = transceiver.recvEncodingParameters[0].ssrc; - } - transceiver.rtpSender.send(params); - } - if (recv && transceiver.rtpReceiver && params.codecs.length > 0) { - // remove RTX field in Edge 14942 - if (transceiver.kind === 'video' - && transceiver.recvEncodingParameters - && edgeVersion < 15019) { - transceiver.recvEncodingParameters.forEach(function(p) { - delete p.rtx; - }); - } - params.encodings = transceiver.recvEncodingParameters; - params.rtcp = { - cname: transceiver.rtcpParameters.cname, - compound: transceiver.rtcpParameters.compound - }; - if (transceiver.sendEncodingParameters.length) { - params.rtcp.ssrc = transceiver.sendEncodingParameters[0].ssrc; - } - transceiver.rtpReceiver.receive(params); - } - }; - - RTCPeerConnection.prototype.setLocalDescription = function(description) { - var self = this; - var args = arguments; - - if (!isActionAllowedInSignalingState('setLocalDescription', - description.type, this.signalingState)) { - return new Promise(function(resolve, reject) { - var e = new Error('Can not set local ' + description.type + - ' in state ' + self.signalingState); - e.name = 'InvalidStateError'; - if (args.length > 2 && typeof args[2] === 'function') { - args[2].apply(null, [e]); - } - reject(e); - }); - } - - var sections; - var sessionpart; - if (description.type === 'offer') { - // VERY limited support for SDP munging. Limited to: - // * changing the order of codecs - sections = SDPUtils.splitSections(description.sdp); - sessionpart = sections.shift(); - sections.forEach(function(mediaSection, sdpMLineIndex) { - var caps = SDPUtils.parseRtpParameters(mediaSection); - self.transceivers[sdpMLineIndex].localCapabilities = caps; - }); - - this.transceivers.forEach(function(transceiver, sdpMLineIndex) { - self._gather(transceiver.mid, sdpMLineIndex); - }); - } else if (description.type === 'answer') { - sections = SDPUtils.splitSections(self.remoteDescription.sdp); - sessionpart = sections.shift(); - var isIceLite = SDPUtils.matchPrefix(sessionpart, - 'a=ice-lite').length > 0; - sections.forEach(function(mediaSection, sdpMLineIndex) { - var transceiver = self.transceivers[sdpMLineIndex]; - var iceGatherer = transceiver.iceGatherer; - var iceTransport = transceiver.iceTransport; - var dtlsTransport = transceiver.dtlsTransport; - var localCapabilities = transceiver.localCapabilities; - var remoteCapabilities = transceiver.remoteCapabilities; - - // treat bundle-only as not-rejected. - var rejected = SDPUtils.isRejected(mediaSection) && - !SDPUtils.matchPrefix(mediaSection, 'a=bundle-only').length === 1; - - if (!rejected && !transceiver.isDatachannel) { - var remoteIceParameters = SDPUtils.getIceParameters( - mediaSection, sessionpart); - var remoteDtlsParameters = SDPUtils.getDtlsParameters( - mediaSection, sessionpart); - if (isIceLite) { - remoteDtlsParameters.role = 'server'; - } - - if (!self.usingBundle || sdpMLineIndex === 0) { - self._gather(transceiver.mid, sdpMLineIndex); - if (iceTransport.state === 'new') { - iceTransport.start(iceGatherer, remoteIceParameters, - isIceLite ? 'controlling' : 'controlled'); - } - if (dtlsTransport.state === 'new') { - dtlsTransport.start(remoteDtlsParameters); - } - } - - // Calculate intersection of capabilities. - var params = getCommonCapabilities(localCapabilities, - remoteCapabilities); - - // Start the RTCRtpSender. The RTCRtpReceiver for this - // transceiver has already been started in setRemoteDescription. - self._transceive(transceiver, - params.codecs.length > 0, - false); - } - }); - } - - this.localDescription = { - type: description.type, - sdp: description.sdp - }; - switch (description.type) { - case 'offer': - this._updateSignalingState('have-local-offer'); - break; - case 'answer': - this._updateSignalingState('stable'); - break; - default: - throw new TypeError('unsupported type "' + description.type + - '"'); - } - - // If a success callback was provided, emit ICE candidates after it - // has been executed. Otherwise, emit callback after the Promise is - // resolved. - var cb = arguments.length > 1 && typeof arguments[1] === 'function' && - arguments[1]; - return new Promise(function(resolve) { - if (cb) { - cb.apply(null); - } - resolve(); - }); - }; - - RTCPeerConnection.prototype.setRemoteDescription = function(description) { - var self = this; - var args = arguments; - - if (!isActionAllowedInSignalingState('setRemoteDescription', - description.type, this.signalingState)) { - return new Promise(function(resolve, reject) { - var e = new Error('Can not set remote ' + description.type + - ' in state ' + self.signalingState); - e.name = 'InvalidStateError'; - if (args.length > 2 && typeof args[2] === 'function') { - args[2].apply(null, [e]); - } - reject(e); - }); - } - - var streams = {}; - this.remoteStreams.forEach(function(stream) { - streams[stream.id] = stream; - }); - var receiverList = []; - var sections = SDPUtils.splitSections(description.sdp); - var sessionpart = sections.shift(); - var isIceLite = SDPUtils.matchPrefix(sessionpart, - 'a=ice-lite').length > 0; - var usingBundle = SDPUtils.matchPrefix(sessionpart, - 'a=group:BUNDLE ').length > 0; - this.usingBundle = usingBundle; - var iceOptions = SDPUtils.matchPrefix(sessionpart, - 'a=ice-options:')[0]; - if (iceOptions) { - this.canTrickleIceCandidates = iceOptions.substr(14).split(' ') - .indexOf('trickle') >= 0; - } else { - this.canTrickleIceCandidates = false; - } - - sections.forEach(function(mediaSection, sdpMLineIndex) { - var lines = SDPUtils.splitLines(mediaSection); - var kind = SDPUtils.getKind(mediaSection); - // treat bundle-only as not-rejected. - var rejected = SDPUtils.isRejected(mediaSection) && - !SDPUtils.matchPrefix(mediaSection, 'a=bundle-only').length === 1; - var protocol = lines[0].substr(2).split(' ')[2]; - - var direction = SDPUtils.getDirection(mediaSection, sessionpart); - var remoteMsid = SDPUtils.parseMsid(mediaSection); - - var mid = SDPUtils.getMid(mediaSection) || SDPUtils.generateIdentifier(); - - // Reject datachannels which are not implemented yet. - if (kind === 'application' && protocol === 'DTLS/SCTP') { - self.transceivers[sdpMLineIndex] = { - mid: mid, - isDatachannel: true - }; - return; - } - - var transceiver; - var iceGatherer; - var iceTransport; - var dtlsTransport; - var rtpReceiver; - var sendEncodingParameters; - var recvEncodingParameters; - var localCapabilities; - - var track; - // FIXME: ensure the mediaSection has rtcp-mux set. - var remoteCapabilities = SDPUtils.parseRtpParameters(mediaSection); - var remoteIceParameters; - var remoteDtlsParameters; - if (!rejected) { - remoteIceParameters = SDPUtils.getIceParameters(mediaSection, - sessionpart); - remoteDtlsParameters = SDPUtils.getDtlsParameters(mediaSection, - sessionpart); - remoteDtlsParameters.role = 'client'; - } - recvEncodingParameters = - SDPUtils.parseRtpEncodingParameters(mediaSection); - - var rtcpParameters = SDPUtils.parseRtcpParameters(mediaSection); - - var isComplete = SDPUtils.matchPrefix(mediaSection, - 'a=end-of-candidates', sessionpart).length > 0; - var cands = SDPUtils.matchPrefix(mediaSection, 'a=candidate:') - .map(function(cand) { - return SDPUtils.parseCandidate(cand); - }) - .filter(function(cand) { - return cand.component === 1; - }); - - // Check if we can use BUNDLE and dispose transports. - if ((description.type === 'offer' || description.type === 'answer') && - !rejected && usingBundle && sdpMLineIndex > 0 && - self.transceivers[sdpMLineIndex]) { - self._disposeIceAndDtlsTransports(sdpMLineIndex); - self.transceivers[sdpMLineIndex].iceGatherer = - self.transceivers[0].iceGatherer; - self.transceivers[sdpMLineIndex].iceTransport = - self.transceivers[0].iceTransport; - self.transceivers[sdpMLineIndex].dtlsTransport = - self.transceivers[0].dtlsTransport; - if (self.transceivers[sdpMLineIndex].rtpSender) { - self.transceivers[sdpMLineIndex].rtpSender.setTransport( - self.transceivers[0].dtlsTransport); - } - if (self.transceivers[sdpMLineIndex].rtpReceiver) { - self.transceivers[sdpMLineIndex].rtpReceiver.setTransport( - self.transceivers[0].dtlsTransport); - } - } - if (description.type === 'offer' && !rejected) { - transceiver = self.transceivers[sdpMLineIndex] || - self._createTransceiver(kind); - transceiver.mid = mid; - - if (!transceiver.iceGatherer) { - transceiver.iceGatherer = self._createIceGatherer(sdpMLineIndex, - usingBundle); - } - - if (cands.length && transceiver.iceTransport.state === 'new') { - if (isComplete && (!usingBundle || sdpMLineIndex === 0)) { - transceiver.iceTransport.setRemoteCandidates(cands); - } else { - cands.forEach(function(candidate) { - maybeAddCandidate(transceiver.iceTransport, candidate); - }); - } - } - - localCapabilities = window.RTCRtpReceiver.getCapabilities(kind); - - // filter RTX until additional stuff needed for RTX is implemented - // in adapter.js - if (edgeVersion < 15019) { - localCapabilities.codecs = localCapabilities.codecs.filter( - function(codec) { - return codec.name !== 'rtx'; - }); - } - - sendEncodingParameters = transceiver.sendEncodingParameters || [{ - ssrc: (2 * sdpMLineIndex + 2) * 1001 - }]; - - var isNewTrack = false; - if (direction === 'sendrecv' || direction === 'sendonly') { - isNewTrack = !transceiver.rtpReceiver; - rtpReceiver = transceiver.rtpReceiver || - new window.RTCRtpReceiver(transceiver.dtlsTransport, kind); - - if (isNewTrack) { - var stream; - track = rtpReceiver.track; - // FIXME: does not work with Plan B. - if (remoteMsid) { - if (!streams[remoteMsid.stream]) { - streams[remoteMsid.stream] = new window.MediaStream(); - Object.defineProperty(streams[remoteMsid.stream], 'id', { - get: function() { - return remoteMsid.stream; - } - }); - } - Object.defineProperty(track, 'id', { - get: function() { - return remoteMsid.track; - } - }); - stream = streams[remoteMsid.stream]; - } else { - if (!streams.default) { - streams.default = new window.MediaStream(); - } - stream = streams.default; - } - stream.addTrack(track); - receiverList.push([track, rtpReceiver, stream]); - } - } - - transceiver.localCapabilities = localCapabilities; - transceiver.remoteCapabilities = remoteCapabilities; - transceiver.rtpReceiver = rtpReceiver; - transceiver.rtcpParameters = rtcpParameters; - transceiver.sendEncodingParameters = sendEncodingParameters; - transceiver.recvEncodingParameters = recvEncodingParameters; - - // Start the RTCRtpReceiver now. The RTPSender is started in - // setLocalDescription. - self._transceive(self.transceivers[sdpMLineIndex], - false, - isNewTrack); - } else if (description.type === 'answer' && !rejected) { - transceiver = self.transceivers[sdpMLineIndex]; - iceGatherer = transceiver.iceGatherer; - iceTransport = transceiver.iceTransport; - dtlsTransport = transceiver.dtlsTransport; - rtpReceiver = transceiver.rtpReceiver; - sendEncodingParameters = transceiver.sendEncodingParameters; - localCapabilities = transceiver.localCapabilities; - - self.transceivers[sdpMLineIndex].recvEncodingParameters = - recvEncodingParameters; - self.transceivers[sdpMLineIndex].remoteCapabilities = - remoteCapabilities; - self.transceivers[sdpMLineIndex].rtcpParameters = rtcpParameters; - - if (cands.length && iceTransport.state === 'new') { - if ((isIceLite || isComplete) && - (!usingBundle || sdpMLineIndex === 0)) { - iceTransport.setRemoteCandidates(cands); - } else { - cands.forEach(function(candidate) { - maybeAddCandidate(transceiver.iceTransport, candidate); - }); - } - } - - if (!usingBundle || sdpMLineIndex === 0) { - if (iceTransport.state === 'new') { - iceTransport.start(iceGatherer, remoteIceParameters, - 'controlling'); - } - if (dtlsTransport.state === 'new') { - dtlsTransport.start(remoteDtlsParameters); - } - } - - self._transceive(transceiver, - direction === 'sendrecv' || direction === 'recvonly', - direction === 'sendrecv' || direction === 'sendonly'); - - if (rtpReceiver && - (direction === 'sendrecv' || direction === 'sendonly')) { - track = rtpReceiver.track; - if (remoteMsid) { - if (!streams[remoteMsid.stream]) { - streams[remoteMsid.stream] = new window.MediaStream(); - } - streams[remoteMsid.stream].addTrack(track); - receiverList.push([track, rtpReceiver, streams[remoteMsid.stream]]); - } else { - if (!streams.default) { - streams.default = new window.MediaStream(); - } - streams.default.addTrack(track); - receiverList.push([track, rtpReceiver, streams.default]); - } - } else { - // FIXME: actually the receiver should be created later. - delete transceiver.rtpReceiver; - } - } - }); - - if (this._dtlsRole === undefined) { - this._dtlsRole = description.type === 'offer' ? 'active' : 'passive'; - } - - this.remoteDescription = { - type: description.type, - sdp: description.sdp - }; - switch (description.type) { - case 'offer': - this._updateSignalingState('have-remote-offer'); - break; - case 'answer': - this._updateSignalingState('stable'); - break; - default: - throw new TypeError('unsupported type "' + description.type + - '"'); - } - Object.keys(streams).forEach(function(sid) { - var stream = streams[sid]; - if (stream.getTracks().length) { - if (self.remoteStreams.indexOf(stream) === -1) { - self.remoteStreams.push(stream); - var event = new Event('addstream'); - event.stream = stream; - window.setTimeout(function() { - self.dispatchEvent(event); - if (typeof self.onaddstream === 'function') { - self.onaddstream(event); - } - }); - } - - receiverList.forEach(function(item) { - var track = item[0]; - var receiver = item[1]; - if (stream.id !== item[2].id) { - return; - } - var trackEvent = new Event('track'); - trackEvent.track = track; - trackEvent.receiver = receiver; - trackEvent.transceiver = {receiver: receiver}; - trackEvent.streams = [stream]; - window.setTimeout(function() { - self.dispatchEvent(trackEvent); - if (typeof self.ontrack === 'function') { - self.ontrack(trackEvent); - } - }); - }); - } - }); - - // check whether addIceCandidate({}) was called within four seconds after - // setRemoteDescription. - window.setTimeout(function() { - if (!(self && self.transceivers)) { - return; - } - self.transceivers.forEach(function(transceiver) { - if (transceiver.iceTransport && - transceiver.iceTransport.state === 'new' && - transceiver.iceTransport.getRemoteCandidates().length > 0) { - console.warn('Timeout for addRemoteCandidate. Consider sending ' + - 'an end-of-candidates notification'); - transceiver.iceTransport.addRemoteCandidate({}); - } - }); - }, 4000); - - return new Promise(function(resolve) { - if (args.length > 1 && typeof args[1] === 'function') { - args[1].apply(null); - } - resolve(); - }); - }; - - RTCPeerConnection.prototype.close = function() { - this.transceivers.forEach(function(transceiver) { - /* not yet - if (transceiver.iceGatherer) { - transceiver.iceGatherer.close(); - } - */ - if (transceiver.iceTransport) { - transceiver.iceTransport.stop(); - } - if (transceiver.dtlsTransport) { - transceiver.dtlsTransport.stop(); - } - if (transceiver.rtpSender) { - transceiver.rtpSender.stop(); - } - if (transceiver.rtpReceiver) { - transceiver.rtpReceiver.stop(); - } - }); - // FIXME: clean up tracks, local streams, remote streams, etc - this._updateSignalingState('closed'); - }; - - // Update the signaling state. - RTCPeerConnection.prototype._updateSignalingState = function(newState) { - this.signalingState = newState; - var event = new Event('signalingstatechange'); - this.dispatchEvent(event); - if (typeof this.onsignalingstatechange === 'function') { - this.onsignalingstatechange(event); - } - }; - - // Determine whether to fire the negotiationneeded event. - RTCPeerConnection.prototype._maybeFireNegotiationNeeded = function() { - var self = this; - if (this.signalingState !== 'stable' || this.needNegotiation === true) { - return; - } - this.needNegotiation = true; - window.setTimeout(function() { - if (self.needNegotiation === false) { - return; - } - self.needNegotiation = false; - var event = new Event('negotiationneeded'); - self.dispatchEvent(event); - if (typeof self.onnegotiationneeded === 'function') { - self.onnegotiationneeded(event); - } - }, 0); - }; - - // Update the connection state. - RTCPeerConnection.prototype._updateConnectionState = function() { - var newState; - var states = { - 'new': 0, - closed: 0, - connecting: 0, - checking: 0, - connected: 0, - completed: 0, - disconnected: 0, - failed: 0 - }; - this.transceivers.forEach(function(transceiver) { - states[transceiver.iceTransport.state]++; - states[transceiver.dtlsTransport.state]++; - }); - // ICETransport.completed and connected are the same for this purpose. - states.connected += states.completed; - - newState = 'new'; - if (states.failed > 0) { - newState = 'failed'; - } else if (states.connecting > 0 || states.checking > 0) { - newState = 'connecting'; - } else if (states.disconnected > 0) { - newState = 'disconnected'; - } else if (states.new > 0) { - newState = 'new'; - } else if (states.connected > 0 || states.completed > 0) { - newState = 'connected'; - } - - if (newState !== this.iceConnectionState) { - this.iceConnectionState = newState; - var event = new Event('iceconnectionstatechange'); - this.dispatchEvent(event); - if (typeof this.oniceconnectionstatechange === 'function') { - this.oniceconnectionstatechange(event); - } - } - }; - - RTCPeerConnection.prototype.createOffer = function() { - var self = this; - var args = arguments; - - var offerOptions; - if (arguments.length === 1 && typeof arguments[0] !== 'function') { - offerOptions = arguments[0]; - } else if (arguments.length === 3) { - offerOptions = arguments[2]; - } - - var numAudioTracks = this.transceivers.filter(function(t) { - return t.kind === 'audio'; - }).length; - var numVideoTracks = this.transceivers.filter(function(t) { - return t.kind === 'video'; - }).length; - - // Determine number of audio and video tracks we need to send/recv. - if (offerOptions) { - // Reject Chrome legacy constraints. - if (offerOptions.mandatory || offerOptions.optional) { - throw new TypeError( - 'Legacy mandatory/optional constraints not supported.'); - } - if (offerOptions.offerToReceiveAudio !== undefined) { - if (offerOptions.offerToReceiveAudio === true) { - numAudioTracks = 1; - } else if (offerOptions.offerToReceiveAudio === false) { - numAudioTracks = 0; - } else { - numAudioTracks = offerOptions.offerToReceiveAudio; - } - } - if (offerOptions.offerToReceiveVideo !== undefined) { - if (offerOptions.offerToReceiveVideo === true) { - numVideoTracks = 1; - } else if (offerOptions.offerToReceiveVideo === false) { - numVideoTracks = 0; - } else { - numVideoTracks = offerOptions.offerToReceiveVideo; - } - } - } - - this.transceivers.forEach(function(transceiver) { - if (transceiver.kind === 'audio') { - numAudioTracks--; - if (numAudioTracks < 0) { - transceiver.wantReceive = false; - } - } else if (transceiver.kind === 'video') { - numVideoTracks--; - if (numVideoTracks < 0) { - transceiver.wantReceive = false; - } - } - }); - - // Create M-lines for recvonly streams. - while (numAudioTracks > 0 || numVideoTracks > 0) { - if (numAudioTracks > 0) { - this._createTransceiver('audio'); - numAudioTracks--; - } - if (numVideoTracks > 0) { - this._createTransceiver('video'); - numVideoTracks--; - } - } - - var sdp = SDPUtils.writeSessionBoilerplate(this._sdpSessionId, - this._sdpSessionVersion++); - this.transceivers.forEach(function(transceiver, sdpMLineIndex) { - // For each track, create an ice gatherer, ice transport, - // dtls transport, potentially rtpsender and rtpreceiver. - var track = transceiver.track; - var kind = transceiver.kind; - var mid = SDPUtils.generateIdentifier(); - transceiver.mid = mid; - - if (!transceiver.iceGatherer) { - transceiver.iceGatherer = self._createIceGatherer(sdpMLineIndex, - self.usingBundle); - } - - var localCapabilities = window.RTCRtpSender.getCapabilities(kind); - // filter RTX until additional stuff needed for RTX is implemented - // in adapter.js - if (edgeVersion < 15019) { - localCapabilities.codecs = localCapabilities.codecs.filter( - function(codec) { - return codec.name !== 'rtx'; - }); - } - localCapabilities.codecs.forEach(function(codec) { - // work around https://bugs.chromium.org/p/webrtc/issues/detail?id=6552 - // by adding level-asymmetry-allowed=1 - if (codec.name === 'H264' && - codec.parameters['level-asymmetry-allowed'] === undefined) { - codec.parameters['level-asymmetry-allowed'] = '1'; - } - }); - - // generate an ssrc now, to be used later in rtpSender.send - var sendEncodingParameters = transceiver.sendEncodingParameters || [{ - ssrc: (2 * sdpMLineIndex + 1) * 1001 - }]; - if (track) { - // add RTX - if (edgeVersion >= 15019 && kind === 'video' && - !sendEncodingParameters[0].rtx) { - sendEncodingParameters[0].rtx = { - ssrc: sendEncodingParameters[0].ssrc + 1 - }; - } - } - - if (transceiver.wantReceive) { - transceiver.rtpReceiver = new window.RTCRtpReceiver( - transceiver.dtlsTransport, kind); - } - - transceiver.localCapabilities = localCapabilities; - transceiver.sendEncodingParameters = sendEncodingParameters; - }); - - // always offer BUNDLE and dispose on return if not supported. - if (this._config.bundlePolicy !== 'max-compat') { - sdp += 'a=group:BUNDLE ' + this.transceivers.map(function(t) { - return t.mid; - }).join(' ') + '\r\n'; - } - sdp += 'a=ice-options:trickle\r\n'; - - this.transceivers.forEach(function(transceiver, sdpMLineIndex) { - sdp += writeMediaSection(transceiver, transceiver.localCapabilities, - 'offer', transceiver.stream, self._dtlsRole); - sdp += 'a=rtcp-rsize\r\n'; - - if (transceiver.iceGatherer && self.iceGatheringState !== 'new' && - (sdpMLineIndex === 0 || !self.usingBundle)) { - transceiver.iceGatherer.getLocalCandidates().forEach(function(cand) { - cand.component = 1; - sdp += 'a=' + SDPUtils.writeCandidate(cand) + '\r\n'; - }); - - if (transceiver.iceGatherer.state === 'completed') { - sdp += 'a=end-of-candidates\r\n'; - } - } - }); - - var desc = new window.RTCSessionDescription({ - type: 'offer', - sdp: sdp - }); - return new Promise(function(resolve) { - if (args.length > 0 && typeof args[0] === 'function') { - args[0].apply(null, [desc]); - resolve(); - return; - } - resolve(desc); - }); - }; - - RTCPeerConnection.prototype.createAnswer = function() { - var self = this; - var args = arguments; - - var sdp = SDPUtils.writeSessionBoilerplate(this._sdpSessionId, - this._sdpSessionVersion++); - if (this.usingBundle) { - sdp += 'a=group:BUNDLE ' + this.transceivers.map(function(t) { - return t.mid; - }).join(' ') + '\r\n'; - } - var mediaSectionsInOffer = SDPUtils.splitSections( - this.remoteDescription.sdp).length - 1; - this.transceivers.forEach(function(transceiver, sdpMLineIndex) { - if (sdpMLineIndex + 1 > mediaSectionsInOffer) { - return; - } - if (transceiver.isDatachannel) { - sdp += 'm=application 0 DTLS/SCTP 5000\r\n' + - 'c=IN IP4 0.0.0.0\r\n' + - 'a=mid:' + transceiver.mid + '\r\n'; - return; - } - - // FIXME: look at direction. - if (transceiver.stream) { - var localTrack; - if (transceiver.kind === 'audio') { - localTrack = transceiver.stream.getAudioTracks()[0]; - } else if (transceiver.kind === 'video') { - localTrack = transceiver.stream.getVideoTracks()[0]; - } - if (localTrack) { - // add RTX - if (edgeVersion >= 15019 && transceiver.kind === 'video' && - !transceiver.sendEncodingParameters[0].rtx) { - transceiver.sendEncodingParameters[0].rtx = { - ssrc: transceiver.sendEncodingParameters[0].ssrc + 1 - }; - } - } - } - - // Calculate intersection of capabilities. - var commonCapabilities = getCommonCapabilities( - transceiver.localCapabilities, - transceiver.remoteCapabilities); - - var hasRtx = commonCapabilities.codecs.filter(function(c) { - return c.name.toLowerCase() === 'rtx'; - }).length; - if (!hasRtx && transceiver.sendEncodingParameters[0].rtx) { - delete transceiver.sendEncodingParameters[0].rtx; - } - - sdp += writeMediaSection(transceiver, commonCapabilities, - 'answer', transceiver.stream, self._dtlsRole); - if (transceiver.rtcpParameters && - transceiver.rtcpParameters.reducedSize) { - sdp += 'a=rtcp-rsize\r\n'; - } - }); - - var desc = new window.RTCSessionDescription({ - type: 'answer', - sdp: sdp - }); - return new Promise(function(resolve) { - if (args.length > 0 && typeof args[0] === 'function') { - args[0].apply(null, [desc]); - resolve(); - return; - } - resolve(desc); - }); - }; - - RTCPeerConnection.prototype.addIceCandidate = function(candidate) { - var err; - var sections; - if (!candidate || candidate.candidate === '') { - for (var j = 0; j < this.transceivers.length; j++) { - if (this.transceivers[j].isDatachannel) { - continue; - } - this.transceivers[j].iceTransport.addRemoteCandidate({}); - sections = SDPUtils.splitSections(this.remoteDescription.sdp); - sections[j + 1] += 'a=end-of-candidates\r\n'; - this.remoteDescription.sdp = sections.join(''); - if (this.usingBundle) { - break; - } - } - } else if (!(candidate.sdpMLineIndex !== undefined || candidate.sdpMid)) { - throw new TypeError('sdpMLineIndex or sdpMid required'); - } else if (!this.remoteDescription) { - err = new Error('Can not add ICE candidate without ' + - 'a remote description'); - err.name = 'InvalidStateError'; - } else { - var sdpMLineIndex = candidate.sdpMLineIndex; - if (candidate.sdpMid) { - for (var i = 0; i < this.transceivers.length; i++) { - if (this.transceivers[i].mid === candidate.sdpMid) { - sdpMLineIndex = i; - break; - } - } - } - var transceiver = this.transceivers[sdpMLineIndex]; - if (transceiver) { - if (transceiver.isDatachannel) { - return Promise.resolve(); - } - var cand = Object.keys(candidate.candidate).length > 0 ? - SDPUtils.parseCandidate(candidate.candidate) : {}; - // Ignore Chrome's invalid candidates since Edge does not like them. - if (cand.protocol === 'tcp' && (cand.port === 0 || cand.port === 9)) { - return Promise.resolve(); - } - // Ignore RTCP candidates, we assume RTCP-MUX. - if (cand.component && cand.component !== 1) { - return Promise.resolve(); - } - // when using bundle, avoid adding candidates to the wrong - // ice transport. And avoid adding candidates added in the SDP. - if (sdpMLineIndex === 0 || (sdpMLineIndex > 0 && - transceiver.iceTransport !== this.transceivers[0].iceTransport)) { - if (!maybeAddCandidate(transceiver.iceTransport, cand)) { - err = new Error('Can not add ICE candidate'); - err.name = 'OperationError'; - } - } - - if (!err) { - // update the remoteDescription. - var candidateString = candidate.candidate.trim(); - if (candidateString.indexOf('a=') === 0) { - candidateString = candidateString.substr(2); - } - sections = SDPUtils.splitSections(this.remoteDescription.sdp); - sections[sdpMLineIndex + 1] += 'a=' + - (cand.type ? candidateString : 'end-of-candidates') - + '\r\n'; - this.remoteDescription.sdp = sections.join(''); - } - } else { - err = new Error('Can not add ICE candidate'); - err.name = 'OperationError'; - } - } - var args = arguments; - return new Promise(function(resolve, reject) { - if (err) { - if (args.length > 2 && typeof args[2] === 'function') { - args[2].apply(null, [err]); - } - reject(err); - } else { - if (args.length > 1 && typeof args[1] === 'function') { - args[1].apply(null); - } - resolve(); - } - }); - }; - - RTCPeerConnection.prototype.getStats = function() { - var promises = []; - this.transceivers.forEach(function(transceiver) { - ['rtpSender', 'rtpReceiver', 'iceGatherer', 'iceTransport', - 'dtlsTransport'].forEach(function(method) { - if (transceiver[method]) { - promises.push(transceiver[method].getStats()); - } - }); - }); - var cb = arguments.length > 1 && typeof arguments[1] === 'function' && - arguments[1]; - var fixStatsType = function(stat) { - return { - inboundrtp: 'inbound-rtp', - outboundrtp: 'outbound-rtp', - candidatepair: 'candidate-pair', - localcandidate: 'local-candidate', - remotecandidate: 'remote-candidate' - }[stat.type] || stat.type; - }; - return new Promise(function(resolve) { - // shim getStats with maplike support - var results = new Map(); - Promise.all(promises).then(function(res) { - res.forEach(function(result) { - Object.keys(result).forEach(function(id) { - result[id].type = fixStatsType(result[id]); - results.set(id, result[id]); - }); - }); - if (cb) { - cb.apply(null, results); - } - resolve(results); - }); - }); - }; - return RTCPeerConnection; -}; - -},{"sdp":18}],10:[function(require,module,exports){ var grammar = module.exports = { v: [{ name: 'version', @@ -2642,7 +1087,7 @@ Object.keys(grammar).forEach(function (key) { }); }); -},{}],11:[function(require,module,exports){ +},{}],10:[function(require,module,exports){ var parser = require('./parser'); var writer = require('./writer'); @@ -2652,7 +1097,7 @@ exports.parseFmtpConfig = parser.parseFmtpConfig; exports.parsePayloads = parser.parsePayloads; exports.parseRemoteCandidates = parser.parseRemoteCandidates; -},{"./parser":12,"./writer":13}],12:[function(require,module,exports){ +},{"./parser":11,"./writer":12}],11:[function(require,module,exports){ var toIntIfInt = function (v) { return String(Number(v)) === v ? Number(v) : v; }; @@ -2747,7 +1192,7 @@ exports.parseRemoteCandidates = function (str) { return candidates; }; -},{"./grammar":10}],13:[function(require,module,exports){ +},{"./grammar":9}],12:[function(require,module,exports){ var grammar = require('./grammar'); // customized util.format - discards excess arguments and can void middle ones @@ -2863,7 +1308,7 @@ module.exports = function (session, opts) { return sdp.join('\r\n') + '\r\n'; }; -},{"./grammar":10}],14:[function(require,module,exports){ +},{"./grammar":9}],13:[function(require,module,exports){ /* Copyright @ 2015 Atlassian Pty Ltd * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -2904,7 +1349,7 @@ module.exports = function arrayEquals(array) { }; -},{}],15:[function(require,module,exports){ +},{}],14:[function(require,module,exports){ /* Copyright @ 2015 Atlassian Pty Ltd * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -2922,7 +1367,7 @@ module.exports = function arrayEquals(array) { exports.Interop = require('./interop'); -},{"./interop":16}],16:[function(require,module,exports){ +},{"./interop":15}],15:[function(require,module,exports){ /* Copyright @ 2015 Atlassian Pty Ltd * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -3807,7 +2252,7 @@ Interop.prototype.toUnifiedPlan = function(desc) { //#endregion }; -},{"./array-equals":14,"./transform":17}],17:[function(require,module,exports){ +},{"./array-equals":13,"./transform":16}],16:[function(require,module,exports){ /* Copyright @ 2015 Atlassian Pty Ltd * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -3921,7 +2366,7 @@ exports.parse = function(sdp) { }; -},{"sdp-transform":11}],18:[function(require,module,exports){ +},{"sdp-transform":10}],17:[function(require,module,exports){ /* eslint-env node */ 'use strict'; @@ -3972,7 +2417,7 @@ SDPUtils.parseCandidate = function(line) { var candidate = { foundation: parts[0], - component: parseInt(parts[1], 10), + component: parts[1], protocol: parts[2].toLowerCase(), priority: parseInt(parts[3], 10), ip: parts[4], @@ -3992,10 +2437,6 @@ SDPUtils.parseCandidate = function(line) { case 'tcptype': candidate.tcpType = parts[i + 1]; break; - case 'ufrag': - candidate.ufrag = parts[i + 1]; // for backward compability. - candidate.usernameFragment = parts[i + 1]; - break; default: // extension handling, in particular ufrag candidate[parts[i]] = parts[i + 1]; break; @@ -4028,10 +2469,6 @@ SDPUtils.writeCandidate = function(candidate) { sdp.push('tcptype'); sdp.push(candidate.tcpType); } - if (candidate.ufrag) { - sdp.push('ufrag'); - sdp.push(candidate.ufrag); - } return 'candidate:' + sdp.join(' '); }; @@ -4377,11 +2814,7 @@ SDPUtils.parseRtpEncodingParameters = function(mediaSection) { if (bandwidth[0].indexOf('b=TIAS:') === 0) { bandwidth = parseInt(bandwidth[0].substr(7), 10); } else if (bandwidth[0].indexOf('b=AS:') === 0) { - // use formula from JSEP to convert b=AS to TIAS value. - bandwidth = parseInt(bandwidth[0].substr(5), 10) * 1000 * 0.95 - - (50 * 40 * 8); - } else { - bandwidth = undefined; + bandwidth = parseInt(bandwidth[0].substr(5), 10); } encodingParameters.forEach(function(params) { params.maxBitrate = bandwidth; @@ -4445,29 +2878,10 @@ SDPUtils.parseMsid = function(mediaSection) { } }; -// Generate a session ID for SDP. -// https://tools.ietf.org/html/draft-ietf-rtcweb-jsep-20#section-5.2.1 -// recommends using a cryptographically random +ve 64-bit value -// but right now this should be acceptable and within the right range -SDPUtils.generateSessionId = function() { - return Math.random().toString().substr(2, 21); -}; - -// Write boilder plate for start of SDP -// sessId argument is optional - if not supplied it will -// be generated randomly -// sessVersion is optional and defaults to 2 -SDPUtils.writeSessionBoilerplate = function(sessId, sessVer) { - var sessionId; - var version = sessVer !== undefined ? sessVer : 2; - if (sessId) { - sessionId = sessId; - } else { - sessionId = SDPUtils.generateSessionId(); - } +SDPUtils.writeSessionBoilerplate = function() { // FIXME: sess-id should be an NTP timestamp. return 'v=0\r\n' + - 'o=thisisadapterortc ' + sessionId + ' ' + version + ' IN IP4 127.0.0.1\r\n' + + 'o=thisisadapterortc 8169639915646943137 2 IN IP4 127.0.0.1\r\n' + 's=-\r\n' + 't=0 0\r\n'; }; @@ -4557,23 +2971,10 @@ SDPUtils.isRejected = function(mediaSection) { return mediaSection.split(' ', 2)[1] === '0'; }; -SDPUtils.parseMLine = function(mediaSection) { - var lines = SDPUtils.splitLines(mediaSection); - var mline = lines[0].split(' '); - return { - kind: mline[0].substr(2), - port: parseInt(mline[1], 10), - protocol: mline[2], - fmt: mline.slice(3).join(' ') - }; -}; - // Expose public methods. -if (typeof module === 'object') { - module.exports = SDPUtils; -} +module.exports = SDPUtils; -},{}],19:[function(require,module,exports){ +},{}],18:[function(require,module,exports){ /** * UAParser.js v0.7.14 * Lightweight JavaScript-based User-Agent string parser @@ -5608,7 +4009,7 @@ if (typeof module === 'object') { })(typeof window === 'object' ? window : this); -},{}],20:[function(require,module,exports){ +},{}],19:[function(require,module,exports){ (function (global){ var rng; @@ -5645,7 +4046,7 @@ module.exports = rng; }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{}],21:[function(require,module,exports){ +},{}],20:[function(require,module,exports){ // uuid.js // // Copyright (c) 2010-2012 Robert Kieffer @@ -5830,8 +4231,7 @@ uuid.unparse = unparse; module.exports = uuid; -},{"./rng":20}],22:[function(require,module,exports){ -(function (global){ +},{"./rng":19}],21:[function(require,module,exports){ /* * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. * @@ -5843,52 +4243,16 @@ module.exports = uuid; 'use strict'; -var adapterFactory = require('./adapter_factory.js'); -module.exports = adapterFactory({window: global.window}); - -}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) - -},{"./adapter_factory.js":23}],23:[function(require,module,exports){ -/* - * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. - */ - /* eslint-env node */ - -'use strict'; - -var utils = require('./utils'); // Shimming starts here. -module.exports = function(dependencies, opts) { - var window = dependencies && dependencies.window; - - var options = { - shimChrome: true, - shimFirefox: true, - shimEdge: true, - shimSafari: true, - }; - - for (var key in opts) { - if (hasOwnProperty.call(opts, key)) { - options[key] = opts[key]; - } - } - +(function() { // Utils. + var utils = require('./utils'); var logging = utils.log; - var browserDetails = utils.detectBrowser(window); - + var browserDetails = utils.browserDetails; // Export to the adapter global object visible in the browser. - var adapter = { - browserDetails: browserDetails, - extractVersion: utils.extractVersion, - disableLog: utils.disableLog, - disableWarnings: utils.disableWarnings - }; + module.exports.browserDetails = browserDetails; + module.exports.extractVersion = utils.extractVersion; + module.exports.disableLog = utils.disableLog; // Uncomment the line below if you want logging to occur, including logging // for the switch statement below. Can also be turned on in the browser via @@ -5901,93 +4265,73 @@ module.exports = function(dependencies, opts) { var edgeShim = require('./edge/edge_shim') || null; var firefoxShim = require('./firefox/firefox_shim') || null; var safariShim = require('./safari/safari_shim') || null; - var commonShim = require('./common_shim') || null; // Shim browser if found. switch (browserDetails.browser) { case 'chrome': - if (!chromeShim || !chromeShim.shimPeerConnection || - !options.shimChrome) { + if (!chromeShim || !chromeShim.shimPeerConnection) { logging('Chrome shim is not included in this adapter release.'); - return adapter; + return; } logging('adapter.js shimming chrome.'); // Export to the adapter global object visible in the browser. - adapter.browserShim = chromeShim; - commonShim.shimCreateObjectURL(window); + module.exports.browserShim = chromeShim; - chromeShim.shimGetUserMedia(window); - chromeShim.shimMediaStream(window); - chromeShim.shimSourceObject(window); - chromeShim.shimPeerConnection(window); - chromeShim.shimOnTrack(window); - chromeShim.shimAddTrackRemoveTrack(window); - chromeShim.shimGetSendersWithDtmf(window); - - commonShim.shimRTCIceCandidate(window); + chromeShim.shimGetUserMedia(); + chromeShim.shimMediaStream(); + utils.shimCreateObjectURL(); + chromeShim.shimSourceObject(); + chromeShim.shimPeerConnection(); + chromeShim.shimOnTrack(); + chromeShim.shimGetSendersWithDtmf(); break; case 'firefox': - if (!firefoxShim || !firefoxShim.shimPeerConnection || - !options.shimFirefox) { + if (!firefoxShim || !firefoxShim.shimPeerConnection) { logging('Firefox shim is not included in this adapter release.'); - return adapter; + return; } logging('adapter.js shimming firefox.'); // Export to the adapter global object visible in the browser. - adapter.browserShim = firefoxShim; - commonShim.shimCreateObjectURL(window); + module.exports.browserShim = firefoxShim; - firefoxShim.shimGetUserMedia(window); - firefoxShim.shimSourceObject(window); - firefoxShim.shimPeerConnection(window); - firefoxShim.shimOnTrack(window); - - commonShim.shimRTCIceCandidate(window); + firefoxShim.shimGetUserMedia(); + utils.shimCreateObjectURL(); + firefoxShim.shimSourceObject(); + firefoxShim.shimPeerConnection(); + firefoxShim.shimOnTrack(); break; case 'edge': - if (!edgeShim || !edgeShim.shimPeerConnection || !options.shimEdge) { + if (!edgeShim || !edgeShim.shimPeerConnection) { logging('MS edge shim is not included in this adapter release.'); - return adapter; + return; } logging('adapter.js shimming edge.'); // Export to the adapter global object visible in the browser. - adapter.browserShim = edgeShim; - commonShim.shimCreateObjectURL(window); + module.exports.browserShim = edgeShim; - edgeShim.shimGetUserMedia(window); - edgeShim.shimPeerConnection(window); - edgeShim.shimReplaceTrack(window); - - // the edge shim implements the full RTCIceCandidate object. + edgeShim.shimGetUserMedia(); + utils.shimCreateObjectURL(); + edgeShim.shimPeerConnection(); + edgeShim.shimReplaceTrack(); break; case 'safari': - if (!safariShim || !options.shimSafari) { + if (!safariShim) { logging('Safari shim is not included in this adapter release.'); - return adapter; + return; } logging('adapter.js shimming safari.'); // Export to the adapter global object visible in the browser. - adapter.browserShim = safariShim; - commonShim.shimCreateObjectURL(window); + module.exports.browserShim = safariShim; - safariShim.shimRTCIceServerUrls(window); - safariShim.shimCallbacksAPI(window); - safariShim.shimLocalStreamsAPI(window); - safariShim.shimRemoteStreamsAPI(window); - safariShim.shimTrackEventTransceiver(window); - safariShim.shimGetUserMedia(window); - - commonShim.shimRTCIceCandidate(window); + safariShim.shimOnAddStream(); + safariShim.shimGetUserMedia(); break; default: logging('Unsupported browser!'); - break; } +})(); - return adapter; -}; - -},{"./chrome/chrome_shim":24,"./common_shim":26,"./edge/edge_shim":27,"./firefox/firefox_shim":29,"./safari/safari_shim":31,"./utils":32}],24:[function(require,module,exports){ +},{"./chrome/chrome_shim":22,"./edge/edge_shim":24,"./firefox/firefox_shim":27,"./safari/safari_shim":29,"./utils":30}],22:[function(require,module,exports){ /* * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. @@ -5998,15 +4342,15 @@ module.exports = function(dependencies, opts) { */ /* eslint-env node */ 'use strict'; -var utils = require('../utils.js'); -var logging = utils.log; +var logging = require('../utils.js').log; +var browserDetails = require('../utils.js').browserDetails; var chromeShim = { - shimMediaStream: function(window) { + shimMediaStream: function() { window.MediaStream = window.MediaStream || window.webkitMediaStream; }, - shimOnTrack: function(window) { + shimOnTrack: function() { if (typeof window === 'object' && window.RTCPeerConnection && !('ontrack' in window.RTCPeerConnection.prototype)) { Object.defineProperty(window.RTCPeerConnection.prototype, 'ontrack', { @@ -6014,126 +4358,70 @@ var chromeShim = { return this._ontrack; }, set: function(f) { + var self = this; if (this._ontrack) { this.removeEventListener('track', this._ontrack); + this.removeEventListener('addstream', this._ontrackpoly); } this.addEventListener('track', this._ontrack = f); - } - }); - var origSetRemoteDescription = - window.RTCPeerConnection.prototype.setRemoteDescription; - window.RTCPeerConnection.prototype.setRemoteDescription = function() { - var pc = this; - if (!pc._ontrackpoly) { - pc._ontrackpoly = function(e) { + this.addEventListener('addstream', this._ontrackpoly = function(e) { // onaddstream does not fire when a track is added to an existing // stream. But stream.onaddtrack is implemented so we use that. e.stream.addEventListener('addtrack', function(te) { - var receiver; - if (window.RTCPeerConnection.prototype.getReceivers) { - receiver = pc.getReceivers().find(function(r) { - return r.track && r.track.id === te.track.id; - }); - } else { - receiver = {track: te.track}; - } - var event = new Event('track'); event.track = te.track; - event.receiver = receiver; - event.transceiver = {receiver: receiver}; + event.receiver = {track: te.track}; event.streams = [e.stream]; - pc.dispatchEvent(event); + self.dispatchEvent(event); }); e.stream.getTracks().forEach(function(track) { - var receiver; - if (window.RTCPeerConnection.prototype.getReceivers) { - receiver = pc.getReceivers().find(function(r) { - return r.track && r.track.id === track.id; - }); - } else { - receiver = {track: track}; - } var event = new Event('track'); event.track = track; - event.receiver = receiver; - event.transceiver = {receiver: receiver}; + event.receiver = {track: track}; event.streams = [e.stream]; - pc.dispatchEvent(event); - }); - }; - pc.addEventListener('addstream', pc._ontrackpoly); + this.dispatchEvent(event); + }.bind(this)); + }.bind(this)); } - return origSetRemoteDescription.apply(pc, arguments); - }; + }); } }, - shimGetSendersWithDtmf: function(window) { - // Overrides addTrack/removeTrack, depends on shimAddTrackRemoveTrack. + shimGetSendersWithDtmf: function() { if (typeof window === 'object' && window.RTCPeerConnection && - !('getSenders' in window.RTCPeerConnection.prototype) && - 'createDTMFSender' in window.RTCPeerConnection.prototype) { - var shimSenderWithDtmf = function(pc, track) { - return { - track: track, - get dtmf() { - if (this._dtmf === undefined) { - if (track.kind === 'audio') { - this._dtmf = pc.createDTMFSender(track); - } else { - this._dtmf = null; - } - } - return this._dtmf; - }, - _pc: pc - }; + !('getSenders' in RTCPeerConnection.prototype) && + 'createDTMFSender' in RTCPeerConnection.prototype) { + RTCPeerConnection.prototype.getSenders = function() { + return this._senders; }; + var origAddStream = RTCPeerConnection.prototype.addStream; + var origRemoveStream = RTCPeerConnection.prototype.removeStream; - // augment addTrack when getSenders is not available. - if (!window.RTCPeerConnection.prototype.getSenders) { - window.RTCPeerConnection.prototype.getSenders = function() { - this._senders = this._senders || []; - return this._senders.slice(); // return a copy of the internal state. - }; - var origAddTrack = window.RTCPeerConnection.prototype.addTrack; - window.RTCPeerConnection.prototype.addTrack = function(track, stream) { - var pc = this; - var sender = origAddTrack.apply(pc, arguments); - if (!sender) { - sender = shimSenderWithDtmf(pc, track); - pc._senders.push(sender); - } - return sender; - }; - - var origRemoveTrack = window.RTCPeerConnection.prototype.removeTrack; - window.RTCPeerConnection.prototype.removeTrack = function(sender) { - var pc = this; - origRemoveTrack.apply(pc, arguments); - var idx = pc._senders.indexOf(sender); - if (idx !== -1) { - pc._senders.splice(idx, 1); - } - }; - } - var origAddStream = window.RTCPeerConnection.prototype.addStream; - window.RTCPeerConnection.prototype.addStream = function(stream) { + RTCPeerConnection.prototype.addStream = function(stream) { var pc = this; pc._senders = pc._senders || []; origAddStream.apply(pc, [stream]); stream.getTracks().forEach(function(track) { - pc._senders.push(shimSenderWithDtmf(pc, track)); + pc._senders.push({ + track: track, + get dtmf() { + if (this._dtmf === undefined) { + if (track.kind === 'audio') { + this._dtmf = pc.createDTMFSender(track); + } else { + this._dtmf = null; + } + } + return this._dtmf; + } + }); }); }; - var origRemoveStream = window.RTCPeerConnection.prototype.removeStream; - window.RTCPeerConnection.prototype.removeStream = function(stream) { + RTCPeerConnection.prototype.removeStream = function(stream) { var pc = this; pc._senders = pc._senders || []; - origRemoveStream.apply(pc, [(pc._streams[stream.id] || stream)]); - + origRemoveStream.apply(pc, [stream]); stream.getTracks().forEach(function(track) { var sender = pc._senders.find(function(s) { return s.track === track; @@ -6143,39 +4431,10 @@ var chromeShim = { } }); }; - } else if (typeof window === 'object' && window.RTCPeerConnection && - 'getSenders' in window.RTCPeerConnection.prototype && - 'createDTMFSender' in window.RTCPeerConnection.prototype && - window.RTCRtpSender && - !('dtmf' in window.RTCRtpSender.prototype)) { - var origGetSenders = window.RTCPeerConnection.prototype.getSenders; - window.RTCPeerConnection.prototype.getSenders = function() { - var pc = this; - var senders = origGetSenders.apply(pc, []); - senders.forEach(function(sender) { - sender._pc = pc; - }); - return senders; - }; - - Object.defineProperty(window.RTCRtpSender.prototype, 'dtmf', { - get: function() { - if (this._dtmf === undefined) { - if (this.track.kind === 'audio') { - this._dtmf = this._pc.createDTMFSender(this.track); - } else { - this._dtmf = null; - } - } - return this._dtmf; - } - }); } }, - shimSourceObject: function(window) { - var URL = window && window.URL; - + shimSourceObject: function() { if (typeof window === 'object') { if (window.HTMLMediaElement && !('srcObject' in window.HTMLMediaElement.prototype)) { @@ -6217,248 +4476,7 @@ var chromeShim = { } }, - shimAddTrackRemoveTrack: function(window) { - var browserDetails = utils.detectBrowser(window); - // shim addTrack and removeTrack. - if (window.RTCPeerConnection.prototype.addTrack && - browserDetails.version >= 62) { - return; - } - - // also shim pc.getLocalStreams when addTrack is shimmed - // to return the original streams. - var origGetLocalStreams = window.RTCPeerConnection.prototype - .getLocalStreams; - window.RTCPeerConnection.prototype.getLocalStreams = function() { - var self = this; - var nativeStreams = origGetLocalStreams.apply(this); - self._reverseStreams = self._reverseStreams || {}; - return nativeStreams.map(function(stream) { - return self._reverseStreams[stream.id]; - }); - }; - - var origAddStream = window.RTCPeerConnection.prototype.addStream; - window.RTCPeerConnection.prototype.addStream = function(stream) { - var pc = this; - pc._streams = pc._streams || {}; - pc._reverseStreams = pc._reverseStreams || {}; - - stream.getTracks().forEach(function(track) { - var alreadyExists = pc.getSenders().find(function(s) { - return s.track === track; - }); - if (alreadyExists) { - throw new DOMException('Track already exists.', - 'InvalidAccessError'); - } - }); - // Add identity mapping for consistency with addTrack. - // Unless this is being used with a stream from addTrack. - if (!pc._reverseStreams[stream.id]) { - var newStream = new window.MediaStream(stream.getTracks()); - pc._streams[stream.id] = newStream; - pc._reverseStreams[newStream.id] = stream; - stream = newStream; - } - origAddStream.apply(pc, [stream]); - }; - - var origRemoveStream = window.RTCPeerConnection.prototype.removeStream; - window.RTCPeerConnection.prototype.removeStream = function(stream) { - var pc = this; - pc._streams = pc._streams || {}; - pc._reverseStreams = pc._reverseStreams || {}; - - origRemoveStream.apply(pc, [(pc._streams[stream.id] || stream)]); - delete pc._reverseStreams[(pc._streams[stream.id] ? - pc._streams[stream.id].id : stream.id)]; - delete pc._streams[stream.id]; - }; - - window.RTCPeerConnection.prototype.addTrack = function(track, stream) { - var pc = this; - if (pc.signalingState === 'closed') { - throw new DOMException( - 'The RTCPeerConnection\'s signalingState is \'closed\'.', - 'InvalidStateError'); - } - var streams = [].slice.call(arguments, 1); - if (streams.length !== 1 || - !streams[0].getTracks().find(function(t) { - return t === track; - })) { - // this is not fully correct but all we can manage without - // [[associated MediaStreams]] internal slot. - throw new DOMException( - 'The adapter.js addTrack polyfill only supports a single ' + - ' stream which is associated with the specified track.', - 'NotSupportedError'); - } - - var alreadyExists = pc.getSenders().find(function(s) { - return s.track === track; - }); - if (alreadyExists) { - throw new DOMException('Track already exists.', - 'InvalidAccessError'); - } - - pc._streams = pc._streams || {}; - pc._reverseStreams = pc._reverseStreams || {}; - var oldStream = pc._streams[stream.id]; - if (oldStream) { - // this is using odd Chrome behaviour, use with caution: - // https://bugs.chromium.org/p/webrtc/issues/detail?id=7815 - // Note: we rely on the high-level addTrack/dtmf shim to - // create the sender with a dtmf sender. - oldStream.addTrack(track); - - // Trigger ONN async. - Promise.resolve().then(function() { - pc.dispatchEvent(new Event('negotiationneeded')); - }); - } else { - var newStream = new window.MediaStream([track]); - pc._streams[stream.id] = newStream; - pc._reverseStreams[newStream.id] = stream; - pc.addStream(newStream); - } - return pc.getSenders().find(function(s) { - return s.track === track; - }); - }; - - // replace the internal stream id with the external one and - // vice versa. - function replaceInternalStreamId(pc, description) { - var sdp = description.sdp; - Object.keys(pc._reverseStreams || []).forEach(function(internalId) { - var externalStream = pc._reverseStreams[internalId]; - var internalStream = pc._streams[externalStream.id]; - sdp = sdp.replace(new RegExp(internalStream.id, 'g'), - externalStream.id); - }); - return new RTCSessionDescription({ - type: description.type, - sdp: sdp - }); - } - function replaceExternalStreamId(pc, description) { - var sdp = description.sdp; - Object.keys(pc._reverseStreams || []).forEach(function(internalId) { - var externalStream = pc._reverseStreams[internalId]; - var internalStream = pc._streams[externalStream.id]; - sdp = sdp.replace(new RegExp(externalStream.id, 'g'), - internalStream.id); - }); - return new RTCSessionDescription({ - type: description.type, - sdp: sdp - }); - } - ['createOffer', 'createAnswer'].forEach(function(method) { - var nativeMethod = window.RTCPeerConnection.prototype[method]; - window.RTCPeerConnection.prototype[method] = function() { - var pc = this; - var args = arguments; - var isLegacyCall = arguments.length && - typeof arguments[0] === 'function'; - if (isLegacyCall) { - return nativeMethod.apply(pc, [ - function(description) { - var desc = replaceInternalStreamId(pc, description); - args[0].apply(null, [desc]); - }, - function(err) { - if (args[1]) { - args[1].apply(null, err); - } - }, arguments[2] - ]); - } - return nativeMethod.apply(pc, arguments) - .then(function(description) { - return replaceInternalStreamId(pc, description); - }); - }; - }); - - var origSetLocalDescription = - window.RTCPeerConnection.prototype.setLocalDescription; - window.RTCPeerConnection.prototype.setLocalDescription = function() { - var pc = this; - if (!arguments.length || !arguments[0].type) { - return origSetLocalDescription.apply(pc, arguments); - } - arguments[0] = replaceExternalStreamId(pc, arguments[0]); - return origSetLocalDescription.apply(pc, arguments); - }; - - // TODO: mangle getStats: https://w3c.github.io/webrtc-stats/#dom-rtcmediastreamstats-streamidentifier - - var origLocalDescription = Object.getOwnPropertyDescriptor( - window.RTCPeerConnection.prototype, 'localDescription'); - Object.defineProperty(window.RTCPeerConnection.prototype, - 'localDescription', { - get: function() { - var pc = this; - var description = origLocalDescription.get.apply(this); - if (description.type === '') { - return description; - } - return replaceInternalStreamId(pc, description); - } - }); - - window.RTCPeerConnection.prototype.removeTrack = function(sender) { - var pc = this; - if (pc.signalingState === 'closed') { - throw new DOMException( - 'The RTCPeerConnection\'s signalingState is \'closed\'.', - 'InvalidStateError'); - } - // We can not yet check for sender instanceof RTCRtpSender - // since we shim RTPSender. So we check if sender._pc is set. - if (!sender._pc) { - throw new DOMException('Argument 1 of RTCPeerConnection.removeTrack ' + - 'does not implement interface RTCRtpSender.', 'TypeError'); - } - var isLocal = sender._pc === pc; - if (!isLocal) { - throw new DOMException('Sender was not created by this connection.', - 'InvalidAccessError'); - } - - // Search for the native stream the senders track belongs to. - pc._streams = pc._streams || {}; - var stream; - Object.keys(pc._streams).forEach(function(streamid) { - var hasTrack = pc._streams[streamid].getTracks().find(function(track) { - return sender.track === track; - }); - if (hasTrack) { - stream = pc._streams[streamid]; - } - }); - - if (stream) { - if (stream.getTracks().length === 1) { - // if this is the last track of the stream, remove the stream. This - // takes care of any shimmed _senders. - pc.removeStream(stream); - } else { - // relying on the same odd chrome behaviour as above. - stream.removeTrack(sender.track); - } - pc.dispatchEvent(new Event('negotiationneeded')); - } - }; - }, - - shimPeerConnection: function(window) { - var browserDetails = utils.detectBrowser(window); - + shimPeerConnection: function() { // The RTCPeerConnection object. if (!window.RTCPeerConnection) { window.RTCPeerConnection = function(pcConfig, pcConstraints) { @@ -6470,21 +4488,20 @@ var chromeShim = { pcConfig.iceTransports = pcConfig.iceTransportPolicy; } - return new window.webkitRTCPeerConnection(pcConfig, pcConstraints); + return new webkitRTCPeerConnection(pcConfig, pcConstraints); }; - window.RTCPeerConnection.prototype = - window.webkitRTCPeerConnection.prototype; + window.RTCPeerConnection.prototype = webkitRTCPeerConnection.prototype; // wrap static methods. Currently just generateCertificate. - if (window.webkitRTCPeerConnection.generateCertificate) { + if (webkitRTCPeerConnection.generateCertificate) { Object.defineProperty(window.RTCPeerConnection, 'generateCertificate', { get: function() { - return window.webkitRTCPeerConnection.generateCertificate; + return webkitRTCPeerConnection.generateCertificate; } }); } } else { // migrate from non-spec RTCIceServer.url to RTCIceServer.urls - var OrigPeerConnection = window.RTCPeerConnection; + var OrigPeerConnection = RTCPeerConnection; window.RTCPeerConnection = function(pcConfig, pcConstraints) { if (pcConfig && pcConfig.iceServers) { var newIceServers = []; @@ -6492,7 +4509,7 @@ var chromeShim = { var server = pcConfig.iceServers[i]; if (!server.hasOwnProperty('urls') && server.hasOwnProperty('url')) { - utils.deprecated('RTCIceServer.url', 'RTCIceServer.urls'); + console.warn('RTCIceServer.url is deprecated! Use urls instead.'); server = JSON.parse(JSON.stringify(server)); server.urls = server.url; newIceServers.push(server); @@ -6513,8 +4530,8 @@ var chromeShim = { }); } - var origGetStats = window.RTCPeerConnection.prototype.getStats; - window.RTCPeerConnection.prototype.getStats = function(selector, + var origGetStats = RTCPeerConnection.prototype.getStats; + RTCPeerConnection.prototype.getStats = function(selector, successCallback, errorCallback) { var self = this; var args = arguments; @@ -6556,7 +4573,7 @@ var chromeShim = { // shim getStats with maplike support var makeMapStats = function(stats) { return new Map(Object.keys(stats).map(function(key) { - return [key, stats[key]]; + return[key, stats[key]]; })); }; @@ -6566,7 +4583,7 @@ var chromeShim = { }; return origGetStats.apply(this, [successCallbackWrapper_, - arguments[0]]); + arguments[0]]); } // promise-support @@ -6582,8 +4599,8 @@ var chromeShim = { if (browserDetails.version < 51) { ['setLocalDescription', 'setRemoteDescription', 'addIceCandidate'] .forEach(function(method) { - var nativeMethod = window.RTCPeerConnection.prototype[method]; - window.RTCPeerConnection.prototype[method] = function() { + var nativeMethod = RTCPeerConnection.prototype[method]; + RTCPeerConnection.prototype[method] = function() { var args = arguments; var self = this; var promise = new Promise(function(resolve, reject) { @@ -6608,8 +4625,8 @@ var chromeShim = { // bugs) since M52: crbug/619289 if (browserDetails.version < 52) { ['createOffer', 'createAnswer'].forEach(function(method) { - var nativeMethod = window.RTCPeerConnection.prototype[method]; - window.RTCPeerConnection.prototype[method] = function() { + var nativeMethod = RTCPeerConnection.prototype[method]; + RTCPeerConnection.prototype[method] = function() { var self = this; if (arguments.length < 1 || (arguments.length === 1 && typeof arguments[0] === 'object')) { @@ -6626,19 +4643,18 @@ var chromeShim = { // shim implicit creation of RTCSessionDescription/RTCIceCandidate ['setLocalDescription', 'setRemoteDescription', 'addIceCandidate'] .forEach(function(method) { - var nativeMethod = window.RTCPeerConnection.prototype[method]; - window.RTCPeerConnection.prototype[method] = function() { + var nativeMethod = RTCPeerConnection.prototype[method]; + RTCPeerConnection.prototype[method] = function() { arguments[0] = new ((method === 'addIceCandidate') ? - window.RTCIceCandidate : - window.RTCSessionDescription)(arguments[0]); + RTCIceCandidate : RTCSessionDescription)(arguments[0]); return nativeMethod.apply(this, arguments); }; }); // support for addIceCandidate(null or undefined) var nativeAddIceCandidate = - window.RTCPeerConnection.prototype.addIceCandidate; - window.RTCPeerConnection.prototype.addIceCandidate = function() { + RTCPeerConnection.prototype.addIceCandidate; + RTCPeerConnection.prototype.addIceCandidate = function() { if (!arguments[0]) { if (arguments[1]) { arguments[1].apply(null); @@ -6655,14 +4671,13 @@ var chromeShim = { module.exports = { shimMediaStream: chromeShim.shimMediaStream, shimOnTrack: chromeShim.shimOnTrack, - shimAddTrackRemoveTrack: chromeShim.shimAddTrackRemoveTrack, shimGetSendersWithDtmf: chromeShim.shimGetSendersWithDtmf, shimSourceObject: chromeShim.shimSourceObject, shimPeerConnection: chromeShim.shimPeerConnection, shimGetUserMedia: require('./getusermedia') }; -},{"../utils.js":32,"./getusermedia":25}],25:[function(require,module,exports){ +},{"../utils.js":30,"./getusermedia":23}],23:[function(require,module,exports){ /* * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. * @@ -6672,14 +4687,11 @@ module.exports = { */ /* eslint-env node */ 'use strict'; -var utils = require('../utils.js'); -var logging = utils.log; +var logging = require('../utils.js').log; +var browserDetails = require('../utils.js').browserDetails; // Expose public methods. -module.exports = function(window) { - var browserDetails = utils.detectBrowser(window); - var navigator = window && window.navigator; - +module.exports = function() { var constraintsToChrome_ = function(c) { if (typeof c !== 'object' || c.mandatory || c.optional) { return c; @@ -6733,16 +4745,7 @@ module.exports = function(window) { var shimConstraints_ = function(constraints, func) { constraints = JSON.parse(JSON.stringify(constraints)); - if (constraints && typeof constraints.audio === 'object') { - var remap = function(obj, a, b) { - if (a in obj && !(b in obj)) { - obj[b] = obj[a]; - delete obj[a]; - } - }; - constraints = JSON.parse(JSON.stringify(constraints)); - remap(constraints.audio, 'autoGainControl', 'googAutoGainControl'); - remap(constraints.audio, 'noiseSuppression', 'googNoiseSuppression'); + if (constraints && constraints.audio) { constraints.audio = constraintsToChrome_(constraints.audio); } if (constraints && typeof constraints.video === 'object') { @@ -6798,12 +4801,7 @@ module.exports = function(window) { return { name: { PermissionDeniedError: 'NotAllowedError', - InvalidStateError: 'NotReadableError', - DevicesNotFoundError: 'NotFoundError', - ConstraintNotSatisfiedError: 'OverconstrainedError', - TrackStartError: 'NotReadableError', - MediaDeviceFailedDueToShutdown: 'NotReadableError', - MediaDeviceKillSwitchOn: 'NotReadableError' + ConstraintNotSatisfiedError: 'OverconstrainedError' }[e.name] || e.name, message: e.message, constraint: e.constraintName, @@ -6816,9 +4814,7 @@ module.exports = function(window) { var getUserMedia_ = function(constraints, onSuccess, onError) { shimConstraints_(constraints, function(c) { navigator.webkitGetUserMedia(c, onSuccess, function(e) { - if (onError) { - onError(shimError_(e)); - } + onError(shimError_(e)); }); }); }; @@ -6838,12 +4834,12 @@ module.exports = function(window) { enumerateDevices: function() { return new Promise(function(resolve) { var kinds = {audio: 'audioinput', video: 'videoinput'}; - return window.MediaStreamTrack.getSources(function(devices) { + return MediaStreamTrack.getSources(function(devices) { resolve(devices.map(function(device) { return {label: device.label, - kind: kinds[device.kind], - deviceId: device.id, - groupId: ''}; + kind: kinds[device.kind], + deviceId: device.id, + groupId: ''}; })); }); }); @@ -6901,175 +4897,7 @@ module.exports = function(window) { } }; -},{"../utils.js":32}],26:[function(require,module,exports){ -/* - * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. - */ - /* eslint-env node */ -'use strict'; - -var SDPUtils = require('sdp'); -var utils = require('./utils'); - -// Wraps the peerconnection event eventNameToWrap in a function -// which returns the modified event object. -function wrapPeerConnectionEvent(window, eventNameToWrap, wrapper) { - if (!window.RTCPeerConnection) { - return; - } - var proto = window.RTCPeerConnection.prototype; - var nativeAddEventListener = proto.addEventListener; - proto.addEventListener = function(nativeEventName, cb) { - if (nativeEventName !== eventNameToWrap) { - return nativeAddEventListener.apply(this, arguments); - } - var wrappedCallback = function(e) { - cb(wrapper(e)); - }; - this._eventMap = this._eventMap || {}; - this._eventMap[cb] = wrappedCallback; - return nativeAddEventListener.apply(this, [nativeEventName, - wrappedCallback]); - }; - - var nativeRemoveEventListener = proto.removeEventListener; - proto.removeEventListener = function(nativeEventName, cb) { - if (nativeEventName !== eventNameToWrap || !this._eventMap - || !this._eventMap[cb]) { - return nativeRemoveEventListener.apply(this, arguments); - } - var unwrappedCb = this._eventMap[cb]; - delete this._eventMap[cb]; - return nativeRemoveEventListener.apply(this, [nativeEventName, - unwrappedCb]); - }; - - Object.defineProperty(proto, 'on' + eventNameToWrap, { - get: function() { - return this['_on' + eventNameToWrap]; - }, - set: function(cb) { - if (this['_on' + eventNameToWrap]) { - this.removeEventListener(eventNameToWrap, - this['_on' + eventNameToWrap]); - delete this['_on' + eventNameToWrap]; - } - if (cb) { - this.addEventListener(eventNameToWrap, - this['_on' + eventNameToWrap] = cb); - } - } - }); -} - -module.exports = { - shimRTCIceCandidate: function(window) { - // foundation is arbitrarily chosen as an indicator for full support for - // https://w3c.github.io/webrtc-pc/#rtcicecandidate-interface - if (window.RTCIceCandidate && 'foundation' in - window.RTCIceCandidate.prototype) { - return; - } - - var NativeRTCIceCandidate = window.RTCIceCandidate; - window.RTCIceCandidate = function(args) { - // Remove the a= which shouldn't be part of the candidate string. - if (typeof args === 'object' && args.candidate && - args.candidate.indexOf('a=') === 0) { - args = JSON.parse(JSON.stringify(args)); - args.candidate = args.candidate.substr(2); - } - - // Augment the native candidate with the parsed fields. - var nativeCandidate = new NativeRTCIceCandidate(args); - var parsedCandidate = SDPUtils.parseCandidate(args.candidate); - var augmentedCandidate = Object.assign(nativeCandidate, - parsedCandidate); - - // Add a serializer that does not serialize the extra attributes. - augmentedCandidate.toJSON = function() { - return { - candidate: augmentedCandidate.candidate, - sdpMid: augmentedCandidate.sdpMid, - sdpMLineIndex: augmentedCandidate.sdpMLineIndex, - usernameFragment: augmentedCandidate.usernameFragment, - }; - }; - return augmentedCandidate; - }; - - // Hook up the augmented candidate in onicecandidate and - // addEventListener('icecandidate', ...) - wrapPeerConnectionEvent(window, 'icecandidate', function(e) { - if (e.candidate) { - Object.defineProperty(e, 'candidate', { - value: new window.RTCIceCandidate(e.candidate), - writable: 'false' - }); - } - return e; - }); - }, - - // shimCreateObjectURL must be called before shimSourceObject to avoid loop. - - shimCreateObjectURL: function(window) { - var URL = window && window.URL; - - if (!(typeof window === 'object' && window.HTMLMediaElement && - 'srcObject' in window.HTMLMediaElement.prototype && - URL.createObjectURL && URL.revokeObjectURL)) { - // Only shim CreateObjectURL using srcObject if srcObject exists. - return undefined; - } - - var nativeCreateObjectURL = URL.createObjectURL.bind(URL); - var nativeRevokeObjectURL = URL.revokeObjectURL.bind(URL); - var streams = new Map(), newId = 0; - - URL.createObjectURL = function(stream) { - if ('getTracks' in stream) { - var url = 'polyblob:' + (++newId); - streams.set(url, stream); - utils.deprecated('URL.createObjectURL(stream)', - 'elem.srcObject = stream'); - return url; - } - return nativeCreateObjectURL(stream); - }; - URL.revokeObjectURL = function(url) { - nativeRevokeObjectURL(url); - streams.delete(url); - }; - - var dsc = Object.getOwnPropertyDescriptor(window.HTMLMediaElement.prototype, - 'src'); - Object.defineProperty(window.HTMLMediaElement.prototype, 'src', { - get: function() { - return dsc.get.apply(this); - }, - set: function(url) { - this.srcObject = streams.get(url) || null; - return dsc.set.apply(this, [url]); - } - }); - - var nativeSetAttribute = window.HTMLMediaElement.prototype.setAttribute; - window.HTMLMediaElement.prototype.setAttribute = function() { - if (arguments.length === 2 && - ('' + arguments[0]).toLowerCase() === 'src') { - this.srcObject = streams.get(arguments[1]) || null; - } - return nativeSetAttribute.apply(this, arguments); - }; - } -}; - -},{"./utils":32,"sdp":18}],27:[function(require,module,exports){ +},{"../utils.js":30}],24:[function(require,module,exports){ /* * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. * @@ -7080,14 +4908,12 @@ module.exports = { /* eslint-env node */ 'use strict'; -var utils = require('../utils'); -var shimRTCPeerConnection = require('rtcpeerconnection-shim'); +var browserDetails = require('../utils').browserDetails; +var shimRTCPeerConnection = require('./rtcpeerconnection_shim'); module.exports = { shimGetUserMedia: require('./getusermedia'), - shimPeerConnection: function(window) { - var browserDetails = utils.detectBrowser(window); - + shimPeerConnection: function() { if (window.RTCIceGatherer) { // ORTC defines an RTCIceCandidate object but no constructor. // Not implemented in Edge. @@ -7109,8 +4935,8 @@ module.exports = { // addStream, see below. No longer required in 15025+ if (browserDetails.version < 15025) { var origMSTEnabled = Object.getOwnPropertyDescriptor( - window.MediaStreamTrack.prototype, 'enabled'); - Object.defineProperty(window.MediaStreamTrack.prototype, 'enabled', { + MediaStreamTrack.prototype, 'enabled'); + Object.defineProperty(MediaStreamTrack.prototype, 'enabled', { set: function(value) { origMSTEnabled.set.call(this, value); var ev = new Event('enabled'); @@ -7120,38 +4946,17 @@ module.exports = { }); } } - - // ORTC defines the DTMF sender a bit different. - // https://github.com/w3c/ortc/issues/714 - if (window.RTCRtpSender && !('dtmf' in window.RTCRtpSender.prototype)) { - Object.defineProperty(window.RTCRtpSender.prototype, 'dtmf', { - get: function() { - if (this._dtmf === undefined) { - if (this.track.kind === 'audio') { - this._dtmf = new window.RTCDtmfSender(this); - } else if (this.track.kind === 'video') { - this._dtmf = null; - } - } - return this._dtmf; - } - }); - } - - window.RTCPeerConnection = - shimRTCPeerConnection(window, browserDetails.version); + window.RTCPeerConnection = shimRTCPeerConnection(browserDetails.version); }, - shimReplaceTrack: function(window) { + shimReplaceTrack: function() { // ORTC has replaceTrack -- https://github.com/w3c/ortc/issues/614 - if (window.RTCRtpSender && - !('replaceTrack' in window.RTCRtpSender.prototype)) { - window.RTCRtpSender.prototype.replaceTrack = - window.RTCRtpSender.prototype.setTrack; + if (window.RTCRtpSender && !('replaceTrack' in RTCRtpSender.prototype)) { + RTCRtpSender.prototype.replaceTrack = RTCRtpSender.prototype.setTrack; } } }; -},{"../utils":32,"./getusermedia":28,"rtcpeerconnection-shim":9}],28:[function(require,module,exports){ +},{"../utils":30,"./getusermedia":25,"./rtcpeerconnection_shim":26}],25:[function(require,module,exports){ /* * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. * @@ -7163,9 +4968,7 @@ module.exports = { 'use strict'; // Expose public methods. -module.exports = function(window) { - var navigator = window && window.navigator; - +module.exports = function() { var shimError_ = function(e) { return { name: {PermissionDeniedError: 'NotAllowedError'}[e.name] || e.name, @@ -7187,7 +4990,1286 @@ module.exports = function(window) { }; }; -},{}],29:[function(require,module,exports){ +},{}],26:[function(require,module,exports){ +/* + * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. + */ + /* eslint-env node */ +'use strict'; + +var SDPUtils = require('sdp'); + +// sort tracks such that they follow an a-v-a-v... +// pattern. +function sortTracks(tracks) { + var audioTracks = tracks.filter(function(track) { + return track.kind === 'audio'; + }); + var videoTracks = tracks.filter(function(track) { + return track.kind === 'video'; + }); + tracks = []; + while (audioTracks.length || videoTracks.length) { + if (audioTracks.length) { + tracks.push(audioTracks.shift()); + } + if (videoTracks.length) { + tracks.push(videoTracks.shift()); + } + } + return tracks; +} + +// Edge does not like +// 1) stun: +// 2) turn: that does not have all of turn:host:port?transport=udp +// 3) turn: with ipv6 addresses +// 4) turn: occurring muliple times +function filterIceServers(iceServers, edgeVersion) { + var hasTurn = false; + iceServers = JSON.parse(JSON.stringify(iceServers)); + return iceServers.filter(function(server) { + if (server && (server.urls || server.url)) { + var urls = server.urls || server.url; + if (server.url && !server.urls) { + console.warn('RTCIceServer.url is deprecated! Use urls instead.'); + } + var isString = typeof urls === 'string'; + if (isString) { + urls = [urls]; + } + urls = urls.filter(function(url) { + var validTurn = url.indexOf('turn:') === 0 && + url.indexOf('transport=udp') !== -1 && + url.indexOf('turn:[') === -1 && + !hasTurn; + + if (validTurn) { + hasTurn = true; + return true; + } + return url.indexOf('stun:') === 0 && edgeVersion >= 14393; + }); + + delete server.url; + server.urls = isString ? urls[0] : urls; + return !!urls.length; + } + return false; + }); +} + +module.exports = function(edgeVersion) { + var RTCPeerConnection = function(config) { + var self = this; + + var _eventTarget = document.createDocumentFragment(); + ['addEventListener', 'removeEventListener', 'dispatchEvent'] + .forEach(function(method) { + self[method] = _eventTarget[method].bind(_eventTarget); + }); + + this.onicecandidate = null; + this.onaddstream = null; + this.ontrack = null; + this.onremovestream = null; + this.onsignalingstatechange = null; + this.oniceconnectionstatechange = null; + this.onicegatheringstatechange = null; + this.onnegotiationneeded = null; + this.ondatachannel = null; + this.canTrickleIceCandidates = null; + + this.localStreams = []; + this.remoteStreams = []; + this.getLocalStreams = function() { + return self.localStreams; + }; + this.getRemoteStreams = function() { + return self.remoteStreams; + }; + + this.localDescription = new RTCSessionDescription({ + type: '', + sdp: '' + }); + this.remoteDescription = new RTCSessionDescription({ + type: '', + sdp: '' + }); + this.signalingState = 'stable'; + this.iceConnectionState = 'new'; + this.iceGatheringState = 'new'; + + this.iceOptions = { + gatherPolicy: 'all', + iceServers: [] + }; + if (config && config.iceTransportPolicy) { + switch (config.iceTransportPolicy) { + case 'all': + case 'relay': + this.iceOptions.gatherPolicy = config.iceTransportPolicy; + break; + default: + // don't set iceTransportPolicy. + break; + } + } + this.usingBundle = config && config.bundlePolicy === 'max-bundle'; + + if (config && config.iceServers) { + this.iceOptions.iceServers = filterIceServers(config.iceServers, + edgeVersion); + } + this._config = config || {}; + + // per-track iceGathers, iceTransports, dtlsTransports, rtpSenders, ... + // everything that is needed to describe a SDP m-line. + this.transceivers = []; + + // since the iceGatherer is currently created in createOffer but we + // must not emit candidates until after setLocalDescription we buffer + // them in this array. + this._localIceCandidatesBuffer = []; + }; + + RTCPeerConnection.prototype._emitGatheringStateChange = function() { + var event = new Event('icegatheringstatechange'); + this.dispatchEvent(event); + if (this.onicegatheringstatechange !== null) { + this.onicegatheringstatechange(event); + } + }; + + RTCPeerConnection.prototype._emitBufferedCandidates = function() { + var self = this; + var sections = SDPUtils.splitSections(self.localDescription.sdp); + // FIXME: need to apply ice candidates in a way which is async but + // in-order + this._localIceCandidatesBuffer.forEach(function(event) { + var end = !event.candidate || Object.keys(event.candidate).length === 0; + if (end) { + for (var j = 1; j < sections.length; j++) { + if (sections[j].indexOf('\r\na=end-of-candidates\r\n') === -1) { + sections[j] += 'a=end-of-candidates\r\n'; + } + } + } else { + sections[event.candidate.sdpMLineIndex + 1] += + 'a=' + event.candidate.candidate + '\r\n'; + } + self.localDescription.sdp = sections.join(''); + self.dispatchEvent(event); + if (self.onicecandidate !== null) { + self.onicecandidate(event); + } + if (!event.candidate && self.iceGatheringState !== 'complete') { + var complete = self.transceivers.every(function(transceiver) { + return transceiver.iceGatherer && + transceiver.iceGatherer.state === 'completed'; + }); + if (complete && self.iceGatheringStateChange !== 'complete') { + self.iceGatheringState = 'complete'; + self._emitGatheringStateChange(); + } + } + }); + this._localIceCandidatesBuffer = []; + }; + + RTCPeerConnection.prototype.getConfiguration = function() { + return this._config; + }; + + RTCPeerConnection.prototype.addStream = function(stream) { + if (edgeVersion >= 15025) { + this.localStreams.push(stream); + } else { + // Clone is necessary for local demos mostly, attaching directly + // to two different senders does not work (build 10547). + // Fixed in 15025 (or earlier) + var clonedStream = stream.clone(); + stream.getTracks().forEach(function(track, idx) { + var clonedTrack = clonedStream.getTracks()[idx]; + track.addEventListener('enabled', function(event) { + clonedTrack.enabled = event.enabled; + }); + }); + this.localStreams.push(clonedStream); + } + this._maybeFireNegotiationNeeded(); + }; + + RTCPeerConnection.prototype.removeStream = function(stream) { + var idx = this.localStreams.indexOf(stream); + if (idx > -1) { + this.localStreams.splice(idx, 1); + this._maybeFireNegotiationNeeded(); + } + }; + + RTCPeerConnection.prototype.getSenders = function() { + return this.transceivers.filter(function(transceiver) { + return !!transceiver.rtpSender; + }) + .map(function(transceiver) { + return transceiver.rtpSender; + }); + }; + + RTCPeerConnection.prototype.getReceivers = function() { + return this.transceivers.filter(function(transceiver) { + return !!transceiver.rtpReceiver; + }) + .map(function(transceiver) { + return transceiver.rtpReceiver; + }); + }; + + // Determines the intersection of local and remote capabilities. + RTCPeerConnection.prototype._getCommonCapabilities = function( + localCapabilities, remoteCapabilities) { + var commonCapabilities = { + codecs: [], + headerExtensions: [], + fecMechanisms: [] + }; + + var findCodecByPayloadType = function(pt, codecs) { + pt = parseInt(pt, 10); + for (var i = 0; i < codecs.length; i++) { + if (codecs[i].payloadType === pt || + codecs[i].preferredPayloadType === pt) { + return codecs[i]; + } + } + }; + + var rtxCapabilityMatches = function(lRtx, rRtx, lCodecs, rCodecs) { + var lCodec = findCodecByPayloadType(lRtx.parameters.apt, lCodecs); + var rCodec = findCodecByPayloadType(rRtx.parameters.apt, rCodecs); + return lCodec && rCodec && + lCodec.name.toLowerCase() === rCodec.name.toLowerCase(); + }; + + localCapabilities.codecs.forEach(function(lCodec) { + for (var i = 0; i < remoteCapabilities.codecs.length; i++) { + var rCodec = remoteCapabilities.codecs[i]; + if (lCodec.name.toLowerCase() === rCodec.name.toLowerCase() && + lCodec.clockRate === rCodec.clockRate) { + if (lCodec.name.toLowerCase() === 'rtx' && + lCodec.parameters && rCodec.parameters.apt) { + // for RTX we need to find the local rtx that has a apt + // which points to the same local codec as the remote one. + if (!rtxCapabilityMatches(lCodec, rCodec, + localCapabilities.codecs, remoteCapabilities.codecs)) { + continue; + } + } + rCodec = JSON.parse(JSON.stringify(rCodec)); // deepcopy + // number of channels is the highest common number of channels + rCodec.numChannels = Math.min(lCodec.numChannels, + rCodec.numChannels); + // push rCodec so we reply with offerer payload type + commonCapabilities.codecs.push(rCodec); + + // determine common feedback mechanisms + rCodec.rtcpFeedback = rCodec.rtcpFeedback.filter(function(fb) { + for (var j = 0; j < lCodec.rtcpFeedback.length; j++) { + if (lCodec.rtcpFeedback[j].type === fb.type && + lCodec.rtcpFeedback[j].parameter === fb.parameter) { + return true; + } + } + return false; + }); + // FIXME: also need to determine .parameters + // see https://github.com/openpeer/ortc/issues/569 + break; + } + } + }); + + localCapabilities.headerExtensions + .forEach(function(lHeaderExtension) { + for (var i = 0; i < remoteCapabilities.headerExtensions.length; + i++) { + var rHeaderExtension = remoteCapabilities.headerExtensions[i]; + if (lHeaderExtension.uri === rHeaderExtension.uri) { + commonCapabilities.headerExtensions.push(rHeaderExtension); + break; + } + } + }); + + // FIXME: fecMechanisms + return commonCapabilities; + }; + + // Create ICE gatherer, ICE transport and DTLS transport. + RTCPeerConnection.prototype._createIceAndDtlsTransports = function(mid, + sdpMLineIndex) { + var self = this; + var iceGatherer = new RTCIceGatherer(self.iceOptions); + var iceTransport = new RTCIceTransport(iceGatherer); + iceGatherer.onlocalcandidate = function(evt) { + var event = new Event('icecandidate'); + event.candidate = {sdpMid: mid, sdpMLineIndex: sdpMLineIndex}; + + var cand = evt.candidate; + var end = !cand || Object.keys(cand).length === 0; + // Edge emits an empty object for RTCIceCandidateComplete‥ + if (end) { + // polyfill since RTCIceGatherer.state is not implemented in + // Edge 10547 yet. + if (iceGatherer.state === undefined) { + iceGatherer.state = 'completed'; + } + } else { + // RTCIceCandidate doesn't have a component, needs to be added + cand.component = iceTransport.component === 'RTCP' ? 2 : 1; + event.candidate.candidate = SDPUtils.writeCandidate(cand); + } + + // update local description. + var sections = SDPUtils.splitSections(self.localDescription.sdp); + if (!end) { + sections[event.candidate.sdpMLineIndex + 1] += + 'a=' + event.candidate.candidate + '\r\n'; + } else { + sections[event.candidate.sdpMLineIndex + 1] += + 'a=end-of-candidates\r\n'; + } + self.localDescription.sdp = sections.join(''); + var transceivers = self._pendingOffer ? self._pendingOffer : + self.transceivers; + var complete = transceivers.every(function(transceiver) { + return transceiver.iceGatherer && + transceiver.iceGatherer.state === 'completed'; + }); + + // Emit candidate if localDescription is set. + // Also emits null candidate when all gatherers are complete. + switch (self.iceGatheringState) { + case 'new': + if (!end) { + self._localIceCandidatesBuffer.push(event); + } + if (end && complete) { + self._localIceCandidatesBuffer.push( + new Event('icecandidate')); + } + break; + case 'gathering': + self._emitBufferedCandidates(); + if (!end) { + self.dispatchEvent(event); + if (self.onicecandidate !== null) { + self.onicecandidate(event); + } + } + if (complete) { + self.dispatchEvent(new Event('icecandidate')); + if (self.onicecandidate !== null) { + self.onicecandidate(new Event('icecandidate')); + } + self.iceGatheringState = 'complete'; + self._emitGatheringStateChange(); + } + break; + case 'complete': + // should not happen... currently! + break; + default: // no-op. + break; + } + }; + iceTransport.onicestatechange = function() { + self._updateConnectionState(); + }; + + var dtlsTransport = new RTCDtlsTransport(iceTransport); + dtlsTransport.ondtlsstatechange = function() { + self._updateConnectionState(); + }; + dtlsTransport.onerror = function() { + // onerror does not set state to failed by itself. + dtlsTransport.state = 'failed'; + self._updateConnectionState(); + }; + + return { + iceGatherer: iceGatherer, + iceTransport: iceTransport, + dtlsTransport: dtlsTransport + }; + }; + + // Destroy ICE gatherer, ICE transport and DTLS transport. + // Without triggering the callbacks. + RTCPeerConnection.prototype._disposeIceAndDtlsTransports = function( + sdpMLineIndex) { + var iceGatherer = this.transceivers[sdpMLineIndex].iceGatherer; + if (iceGatherer) { + delete iceGatherer.onlocalcandidate; + delete this.transceivers[sdpMLineIndex].iceGatherer; + } + var iceTransport = this.transceivers[sdpMLineIndex].iceTransport; + if (iceTransport) { + delete iceTransport.onicestatechange; + delete this.transceivers[sdpMLineIndex].iceTransport; + } + var dtlsTransport = this.transceivers[sdpMLineIndex].dtlsTransport; + if (dtlsTransport) { + delete dtlsTransport.ondtlssttatechange; + delete dtlsTransport.onerror; + delete this.transceivers[sdpMLineIndex].dtlsTransport; + } + }; + + // Start the RTP Sender and Receiver for a transceiver. + RTCPeerConnection.prototype._transceive = function(transceiver, + send, recv) { + var params = this._getCommonCapabilities(transceiver.localCapabilities, + transceiver.remoteCapabilities); + if (send && transceiver.rtpSender) { + params.encodings = transceiver.sendEncodingParameters; + params.rtcp = { + cname: SDPUtils.localCName, + compound: transceiver.rtcpParameters.compound + }; + if (transceiver.recvEncodingParameters.length) { + params.rtcp.ssrc = transceiver.recvEncodingParameters[0].ssrc; + } + transceiver.rtpSender.send(params); + } + if (recv && transceiver.rtpReceiver) { + // remove RTX field in Edge 14942 + if (transceiver.kind === 'video' + && transceiver.recvEncodingParameters + && edgeVersion < 15019) { + transceiver.recvEncodingParameters.forEach(function(p) { + delete p.rtx; + }); + } + params.encodings = transceiver.recvEncodingParameters; + params.rtcp = { + cname: transceiver.rtcpParameters.cname, + compound: transceiver.rtcpParameters.compound + }; + if (transceiver.sendEncodingParameters.length) { + params.rtcp.ssrc = transceiver.sendEncodingParameters[0].ssrc; + } + transceiver.rtpReceiver.receive(params); + } + }; + + RTCPeerConnection.prototype.setLocalDescription = function(description) { + var self = this; + var sections; + var sessionpart; + if (description.type === 'offer') { + // FIXME: What was the purpose of this empty if statement? + // if (!this._pendingOffer) { + // } else { + if (this._pendingOffer) { + // VERY limited support for SDP munging. Limited to: + // * changing the order of codecs + sections = SDPUtils.splitSections(description.sdp); + sessionpart = sections.shift(); + sections.forEach(function(mediaSection, sdpMLineIndex) { + var caps = SDPUtils.parseRtpParameters(mediaSection); + self._pendingOffer[sdpMLineIndex].localCapabilities = caps; + }); + this.transceivers = this._pendingOffer; + delete this._pendingOffer; + } + } else if (description.type === 'answer') { + sections = SDPUtils.splitSections(self.remoteDescription.sdp); + sessionpart = sections.shift(); + var isIceLite = SDPUtils.matchPrefix(sessionpart, + 'a=ice-lite').length > 0; + sections.forEach(function(mediaSection, sdpMLineIndex) { + var transceiver = self.transceivers[sdpMLineIndex]; + var iceGatherer = transceiver.iceGatherer; + var iceTransport = transceiver.iceTransport; + var dtlsTransport = transceiver.dtlsTransport; + var localCapabilities = transceiver.localCapabilities; + var remoteCapabilities = transceiver.remoteCapabilities; + + var rejected = mediaSection.split('\n', 1)[0] + .split(' ', 2)[1] === '0'; + + if (!rejected && !transceiver.isDatachannel) { + var remoteIceParameters = SDPUtils.getIceParameters( + mediaSection, sessionpart); + var remoteDtlsParameters = SDPUtils.getDtlsParameters( + mediaSection, sessionpart); + if (isIceLite) { + remoteDtlsParameters.role = 'server'; + } + + if (!self.usingBundle || sdpMLineIndex === 0) { + iceTransport.start(iceGatherer, remoteIceParameters, + isIceLite ? 'controlling' : 'controlled'); + dtlsTransport.start(remoteDtlsParameters); + } + + // Calculate intersection of capabilities. + var params = self._getCommonCapabilities(localCapabilities, + remoteCapabilities); + + // Start the RTCRtpSender. The RTCRtpReceiver for this + // transceiver has already been started in setRemoteDescription. + self._transceive(transceiver, + params.codecs.length > 0, + false); + } + }); + } + + this.localDescription = { + type: description.type, + sdp: description.sdp + }; + switch (description.type) { + case 'offer': + this._updateSignalingState('have-local-offer'); + break; + case 'answer': + this._updateSignalingState('stable'); + break; + default: + throw new TypeError('unsupported type "' + description.type + + '"'); + } + + // If a success callback was provided, emit ICE candidates after it + // has been executed. Otherwise, emit callback after the Promise is + // resolved. + var hasCallback = arguments.length > 1 && + typeof arguments[1] === 'function'; + if (hasCallback) { + var cb = arguments[1]; + window.setTimeout(function() { + cb(); + if (self.iceGatheringState === 'new') { + self.iceGatheringState = 'gathering'; + self._emitGatheringStateChange(); + } + self._emitBufferedCandidates(); + }, 0); + } + var p = Promise.resolve(); + p.then(function() { + if (!hasCallback) { + if (self.iceGatheringState === 'new') { + self.iceGatheringState = 'gathering'; + self._emitGatheringStateChange(); + } + // Usually candidates will be emitted earlier. + window.setTimeout(self._emitBufferedCandidates.bind(self), 500); + } + }); + return p; + }; + + RTCPeerConnection.prototype.setRemoteDescription = function(description) { + var self = this; + var streams = {}; + var receiverList = []; + var sections = SDPUtils.splitSections(description.sdp); + var sessionpart = sections.shift(); + var isIceLite = SDPUtils.matchPrefix(sessionpart, + 'a=ice-lite').length > 0; + var usingBundle = SDPUtils.matchPrefix(sessionpart, + 'a=group:BUNDLE ').length > 0; + var iceOptions = SDPUtils.matchPrefix(sessionpart, + 'a=ice-options:')[0]; + if (iceOptions) { + this.canTrickleIceCandidates = iceOptions.substr(14).split(' ') + .indexOf('trickle') >= 0; + } else { + this.canTrickleIceCandidates = false; + } + + sections.forEach(function(mediaSection, sdpMLineIndex) { + var lines = SDPUtils.splitLines(mediaSection); + var mline = lines[0].substr(2).split(' '); + var kind = mline[0]; + var rejected = mline[1] === '0'; + var direction = SDPUtils.getDirection(mediaSection, sessionpart); + var remoteMsid = SDPUtils.parseMsid(mediaSection); + + var mid = SDPUtils.matchPrefix(mediaSection, 'a=mid:'); + if (mid.length) { + mid = mid[0].substr(6); + } else { + mid = SDPUtils.generateIdentifier(); + } + + // Reject datachannels which are not implemented yet. + if (kind === 'application' && mline[2] === 'DTLS/SCTP') { + self.transceivers[sdpMLineIndex] = { + mid: mid, + isDatachannel: true + }; + return; + } + + var transceiver; + var iceGatherer; + var iceTransport; + var dtlsTransport; + var rtpSender; + var rtpReceiver; + var sendEncodingParameters; + var recvEncodingParameters; + var localCapabilities; + + var track; + // FIXME: ensure the mediaSection has rtcp-mux set. + var remoteCapabilities = SDPUtils.parseRtpParameters(mediaSection); + var remoteIceParameters; + var remoteDtlsParameters; + if (!rejected) { + remoteIceParameters = SDPUtils.getIceParameters(mediaSection, + sessionpart); + remoteDtlsParameters = SDPUtils.getDtlsParameters(mediaSection, + sessionpart); + remoteDtlsParameters.role = 'client'; + } + recvEncodingParameters = + SDPUtils.parseRtpEncodingParameters(mediaSection); + + var rtcpParameters = SDPUtils.parseRtcpParameters(mediaSection); + + var isComplete = SDPUtils.matchPrefix(mediaSection, + 'a=end-of-candidates', sessionpart).length > 0; + var cands = SDPUtils.matchPrefix(mediaSection, 'a=candidate:') + .map(function(cand) { + return SDPUtils.parseCandidate(cand); + }) + .filter(function(cand) { + return cand.component === '1'; + }); + if (description.type === 'offer' && !rejected) { + var transports = usingBundle && sdpMLineIndex > 0 ? { + iceGatherer: self.transceivers[0].iceGatherer, + iceTransport: self.transceivers[0].iceTransport, + dtlsTransport: self.transceivers[0].dtlsTransport + } : self._createIceAndDtlsTransports(mid, sdpMLineIndex); + + if (isComplete && (!usingBundle || sdpMLineIndex === 0)) { + transports.iceTransport.setRemoteCandidates(cands); + } + + localCapabilities = RTCRtpReceiver.getCapabilities(kind); + + // filter RTX until additional stuff needed for RTX is implemented + // in adapter.js + if (edgeVersion < 15019) { + localCapabilities.codecs = localCapabilities.codecs.filter( + function(codec) { + return codec.name !== 'rtx'; + }); + } + + sendEncodingParameters = [{ + ssrc: (2 * sdpMLineIndex + 2) * 1001 + }]; + + if (direction === 'sendrecv' || direction === 'sendonly') { + rtpReceiver = new RTCRtpReceiver(transports.dtlsTransport, + kind); + + track = rtpReceiver.track; + // FIXME: does not work with Plan B. + if (remoteMsid) { + if (!streams[remoteMsid.stream]) { + streams[remoteMsid.stream] = new MediaStream(); + Object.defineProperty(streams[remoteMsid.stream], 'id', { + get: function() { + return remoteMsid.stream; + } + }); + } + Object.defineProperty(track, 'id', { + get: function() { + return remoteMsid.track; + } + }); + streams[remoteMsid.stream].addTrack(track); + receiverList.push([track, rtpReceiver, + streams[remoteMsid.stream]]); + } else { + if (!streams.default) { + streams.default = new MediaStream(); + } + streams.default.addTrack(track); + receiverList.push([track, rtpReceiver, streams.default]); + } + } + + // FIXME: look at direction. + if (self.localStreams.length > 0 && + self.localStreams[0].getTracks().length >= sdpMLineIndex) { + var localTrack; + if (kind === 'audio') { + localTrack = self.localStreams[0].getAudioTracks()[0]; + } else if (kind === 'video') { + localTrack = self.localStreams[0].getVideoTracks()[0]; + } + if (localTrack) { + // add RTX + if (edgeVersion >= 15019 && kind === 'video') { + sendEncodingParameters[0].rtx = { + ssrc: (2 * sdpMLineIndex + 2) * 1001 + 1 + }; + } + rtpSender = new RTCRtpSender(localTrack, + transports.dtlsTransport); + } + } + + self.transceivers[sdpMLineIndex] = { + iceGatherer: transports.iceGatherer, + iceTransport: transports.iceTransport, + dtlsTransport: transports.dtlsTransport, + localCapabilities: localCapabilities, + remoteCapabilities: remoteCapabilities, + rtpSender: rtpSender, + rtpReceiver: rtpReceiver, + kind: kind, + mid: mid, + rtcpParameters: rtcpParameters, + sendEncodingParameters: sendEncodingParameters, + recvEncodingParameters: recvEncodingParameters + }; + // Start the RTCRtpReceiver now. The RTPSender is started in + // setLocalDescription. + self._transceive(self.transceivers[sdpMLineIndex], + false, + direction === 'sendrecv' || direction === 'sendonly'); + } else if (description.type === 'answer' && !rejected) { + if (usingBundle && sdpMLineIndex > 0) { + self._disposeIceAndDtlsTransports(sdpMLineIndex); + self.transceivers[sdpMLineIndex].iceGatherer = + self.transceivers[0].iceGatherer; + self.transceivers[sdpMLineIndex].iceTransport = + self.transceivers[0].iceTransport; + self.transceivers[sdpMLineIndex].dtlsTransport = + self.transceivers[0].dtlsTransport; + if (self.transceivers[sdpMLineIndex].rtpSender) { + self.transceivers[sdpMLineIndex].rtpSender.setTransport( + self.transceivers[0].dtlsTransport); + } + if (self.transceivers[sdpMLineIndex].rtpReceiver) { + self.transceivers[sdpMLineIndex].rtpReceiver.setTransport( + self.transceivers[0].dtlsTransport); + } + } + transceiver = self.transceivers[sdpMLineIndex]; + iceGatherer = transceiver.iceGatherer; + iceTransport = transceiver.iceTransport; + dtlsTransport = transceiver.dtlsTransport; + rtpSender = transceiver.rtpSender; + rtpReceiver = transceiver.rtpReceiver; + sendEncodingParameters = transceiver.sendEncodingParameters; + localCapabilities = transceiver.localCapabilities; + + self.transceivers[sdpMLineIndex].recvEncodingParameters = + recvEncodingParameters; + self.transceivers[sdpMLineIndex].remoteCapabilities = + remoteCapabilities; + self.transceivers[sdpMLineIndex].rtcpParameters = rtcpParameters; + + if ((isIceLite || isComplete) && cands.length) { + iceTransport.setRemoteCandidates(cands); + } + if (!usingBundle || sdpMLineIndex === 0) { + iceTransport.start(iceGatherer, remoteIceParameters, + 'controlling'); + dtlsTransport.start(remoteDtlsParameters); + } + + self._transceive(transceiver, + direction === 'sendrecv' || direction === 'recvonly', + direction === 'sendrecv' || direction === 'sendonly'); + + if (rtpReceiver && + (direction === 'sendrecv' || direction === 'sendonly')) { + track = rtpReceiver.track; + receiverList.push([track, rtpReceiver]); + if (remoteMsid) { + if (!streams[remoteMsid.stream]) { + streams[remoteMsid.stream] = new MediaStream(); + } + streams[remoteMsid.stream].addTrack(track); + } else { + if (!streams.default) { + streams.default = new MediaStream(); + } + streams.default.addTrack(track); + } + } else { + // FIXME: actually the receiver should be created later. + delete transceiver.rtpReceiver; + } + } + }); + this.usingBundle = usingBundle; + + this.remoteDescription = { + type: description.type, + sdp: description.sdp + }; + switch (description.type) { + case 'offer': + this._updateSignalingState('have-remote-offer'); + break; + case 'answer': + this._updateSignalingState('stable'); + break; + default: + throw new TypeError('unsupported type "' + description.type + + '"'); + } + Object.keys(streams).forEach(function(sid) { + var stream = streams[sid]; + if (stream.getTracks().length) { + self.remoteStreams.push(stream); + var event = new Event('addstream'); + event.stream = stream; + self.dispatchEvent(event); + if (self.onaddstream !== null) { + window.setTimeout(function() { + self.onaddstream(event); + }, 0); + } + + receiverList.forEach(function(item) { + var track = item[0]; + var receiver = item[1]; + if (stream.id !== item[2].id) { + return; + } + var trackEvent = new Event('track'); + trackEvent.track = track; + trackEvent.receiver = receiver; + trackEvent.streams = [stream]; + self.dispatchEvent(trackEvent); + if (self.ontrack !== null) { + window.setTimeout(function() { + self.ontrack(trackEvent); + }, 0); + } + }); + } + }); + if (arguments.length > 1 && typeof arguments[1] === 'function') { + window.setTimeout(arguments[1], 0); + } + return Promise.resolve(); + }; + + RTCPeerConnection.prototype.close = function() { + this.transceivers.forEach(function(transceiver) { + /* not yet + if (transceiver.iceGatherer) { + transceiver.iceGatherer.close(); + } + */ + if (transceiver.iceTransport) { + transceiver.iceTransport.stop(); + } + if (transceiver.dtlsTransport) { + transceiver.dtlsTransport.stop(); + } + if (transceiver.rtpSender) { + transceiver.rtpSender.stop(); + } + if (transceiver.rtpReceiver) { + transceiver.rtpReceiver.stop(); + } + }); + // FIXME: clean up tracks, local streams, remote streams, etc + this._updateSignalingState('closed'); + }; + + // Update the signaling state. + RTCPeerConnection.prototype._updateSignalingState = function(newState) { + this.signalingState = newState; + var event = new Event('signalingstatechange'); + this.dispatchEvent(event); + if (this.onsignalingstatechange !== null) { + this.onsignalingstatechange(event); + } + }; + + // Determine whether to fire the negotiationneeded event. + RTCPeerConnection.prototype._maybeFireNegotiationNeeded = function() { + // Fire away (for now). + var event = new Event('negotiationneeded'); + this.dispatchEvent(event); + if (this.onnegotiationneeded !== null) { + this.onnegotiationneeded(event); + } + }; + + // Update the connection state. + RTCPeerConnection.prototype._updateConnectionState = function() { + var self = this; + var newState; + var states = { + 'new': 0, + closed: 0, + connecting: 0, + checking: 0, + connected: 0, + completed: 0, + failed: 0 + }; + this.transceivers.forEach(function(transceiver) { + states[transceiver.iceTransport.state]++; + states[transceiver.dtlsTransport.state]++; + }); + // ICETransport.completed and connected are the same for this purpose. + states.connected += states.completed; + + newState = 'new'; + if (states.failed > 0) { + newState = 'failed'; + } else if (states.connecting > 0 || states.checking > 0) { + newState = 'connecting'; + } else if (states.disconnected > 0) { + newState = 'disconnected'; + } else if (states.new > 0) { + newState = 'new'; + } else if (states.connected > 0 || states.completed > 0) { + newState = 'connected'; + } + + if (newState !== self.iceConnectionState) { + self.iceConnectionState = newState; + var event = new Event('iceconnectionstatechange'); + this.dispatchEvent(event); + if (this.oniceconnectionstatechange !== null) { + this.oniceconnectionstatechange(event); + } + } + }; + + RTCPeerConnection.prototype.createOffer = function() { + var self = this; + if (this._pendingOffer) { + throw new Error('createOffer called while there is a pending offer.'); + } + var offerOptions; + if (arguments.length === 1 && typeof arguments[0] !== 'function') { + offerOptions = arguments[0]; + } else if (arguments.length === 3) { + offerOptions = arguments[2]; + } + + var tracks = []; + var numAudioTracks = 0; + var numVideoTracks = 0; + // Default to sendrecv. + if (this.localStreams.length) { + numAudioTracks = this.localStreams.reduce(function(numTracks, stream) { + return numTracks + stream.getAudioTracks().length; + }, 0); + numVideoTracks = this.localStreams.reduce(function(numTracks, stream) { + return numTracks + stream.getVideoTracks().length; + }, 0); + } + // Determine number of audio and video tracks we need to send/recv. + if (offerOptions) { + // Reject Chrome legacy constraints. + if (offerOptions.mandatory || offerOptions.optional) { + throw new TypeError( + 'Legacy mandatory/optional constraints not supported.'); + } + if (offerOptions.offerToReceiveAudio !== undefined) { + numAudioTracks = offerOptions.offerToReceiveAudio; + } + if (offerOptions.offerToReceiveVideo !== undefined) { + numVideoTracks = offerOptions.offerToReceiveVideo; + } + } + + // Push local streams. + this.localStreams.forEach(function(localStream) { + localStream.getTracks().forEach(function(track) { + tracks.push({ + kind: track.kind, + track: track, + stream: localStream, + wantReceive: track.kind === 'audio' ? + numAudioTracks > 0 : numVideoTracks > 0 + }); + if (track.kind === 'audio') { + numAudioTracks--; + } else if (track.kind === 'video') { + numVideoTracks--; + } + }); + }); + + // Create M-lines for recvonly streams. + while (numAudioTracks > 0 || numVideoTracks > 0) { + if (numAudioTracks > 0) { + tracks.push({ + kind: 'audio', + wantReceive: true + }); + numAudioTracks--; + } + if (numVideoTracks > 0) { + tracks.push({ + kind: 'video', + wantReceive: true + }); + numVideoTracks--; + } + } + // reorder tracks + tracks = sortTracks(tracks); + + var sdp = SDPUtils.writeSessionBoilerplate(); + var transceivers = []; + tracks.forEach(function(mline, sdpMLineIndex) { + // For each track, create an ice gatherer, ice transport, + // dtls transport, potentially rtpsender and rtpreceiver. + var track = mline.track; + var kind = mline.kind; + var mid = SDPUtils.generateIdentifier(); + + var transports = self.usingBundle && sdpMLineIndex > 0 ? { + iceGatherer: transceivers[0].iceGatherer, + iceTransport: transceivers[0].iceTransport, + dtlsTransport: transceivers[0].dtlsTransport + } : self._createIceAndDtlsTransports(mid, sdpMLineIndex); + + var localCapabilities = RTCRtpSender.getCapabilities(kind); + // filter RTX until additional stuff needed for RTX is implemented + // in adapter.js + if (edgeVersion < 15019) { + localCapabilities.codecs = localCapabilities.codecs.filter( + function(codec) { + return codec.name !== 'rtx'; + }); + } + localCapabilities.codecs.forEach(function(codec) { + // work around https://bugs.chromium.org/p/webrtc/issues/detail?id=6552 + // by adding level-asymmetry-allowed=1 + if (codec.name === 'H264' && + codec.parameters['level-asymmetry-allowed'] === undefined) { + codec.parameters['level-asymmetry-allowed'] = '1'; + } + }); + + var rtpSender; + var rtpReceiver; + + // generate an ssrc now, to be used later in rtpSender.send + var sendEncodingParameters = [{ + ssrc: (2 * sdpMLineIndex + 1) * 1001 + }]; + if (track) { + // add RTX + if (edgeVersion >= 15019 && kind === 'video') { + sendEncodingParameters[0].rtx = { + ssrc: (2 * sdpMLineIndex + 1) * 1001 + 1 + }; + } + rtpSender = new RTCRtpSender(track, transports.dtlsTransport); + } + + if (mline.wantReceive) { + rtpReceiver = new RTCRtpReceiver(transports.dtlsTransport, kind); + } + + transceivers[sdpMLineIndex] = { + iceGatherer: transports.iceGatherer, + iceTransport: transports.iceTransport, + dtlsTransport: transports.dtlsTransport, + localCapabilities: localCapabilities, + remoteCapabilities: null, + rtpSender: rtpSender, + rtpReceiver: rtpReceiver, + kind: kind, + mid: mid, + sendEncodingParameters: sendEncodingParameters, + recvEncodingParameters: null + }; + }); + + // always offer BUNDLE and dispose on return if not supported. + if (this._config.bundlePolicy !== 'max-compat') { + sdp += 'a=group:BUNDLE ' + transceivers.map(function(t) { + return t.mid; + }).join(' ') + '\r\n'; + } + sdp += 'a=ice-options:trickle\r\n'; + + tracks.forEach(function(mline, sdpMLineIndex) { + var transceiver = transceivers[sdpMLineIndex]; + sdp += SDPUtils.writeMediaSection(transceiver, + transceiver.localCapabilities, 'offer', mline.stream); + sdp += 'a=rtcp-rsize\r\n'; + }); + + this._pendingOffer = transceivers; + var desc = new RTCSessionDescription({ + type: 'offer', + sdp: sdp + }); + if (arguments.length && typeof arguments[0] === 'function') { + window.setTimeout(arguments[0], 0, desc); + } + return Promise.resolve(desc); + }; + + RTCPeerConnection.prototype.createAnswer = function() { + var self = this; + + var sdp = SDPUtils.writeSessionBoilerplate(); + if (this.usingBundle) { + sdp += 'a=group:BUNDLE ' + this.transceivers.map(function(t) { + return t.mid; + }).join(' ') + '\r\n'; + } + this.transceivers.forEach(function(transceiver) { + if (transceiver.isDatachannel) { + sdp += 'm=application 0 DTLS/SCTP 5000\r\n' + + 'c=IN IP4 0.0.0.0\r\n' + + 'a=mid:' + transceiver.mid + '\r\n'; + return; + } + // Calculate intersection of capabilities. + var commonCapabilities = self._getCommonCapabilities( + transceiver.localCapabilities, + transceiver.remoteCapabilities); + + var hasRtx = commonCapabilities.codecs.filter(function(c) { + return c.name.toLowerCase() === 'rtx'; + }).length; + if (!hasRtx && transceiver.sendEncodingParameters[0].rtx) { + delete transceiver.sendEncodingParameters[0].rtx; + } + + sdp += SDPUtils.writeMediaSection(transceiver, commonCapabilities, + 'answer', self.localStreams[0]); + if (transceiver.rtcpParameters && + transceiver.rtcpParameters.reducedSize) { + sdp += 'a=rtcp-rsize\r\n'; + } + }); + + var desc = new RTCSessionDescription({ + type: 'answer', + sdp: sdp + }); + if (arguments.length && typeof arguments[0] === 'function') { + window.setTimeout(arguments[0], 0, desc); + } + return Promise.resolve(desc); + }; + + RTCPeerConnection.prototype.addIceCandidate = function(candidate) { + if (!candidate) { + for (var j = 0; j < this.transceivers.length; j++) { + this.transceivers[j].iceTransport.addRemoteCandidate({}); + if (this.usingBundle) { + return Promise.resolve(); + } + } + } else { + var mLineIndex = candidate.sdpMLineIndex; + if (candidate.sdpMid) { + for (var i = 0; i < this.transceivers.length; i++) { + if (this.transceivers[i].mid === candidate.sdpMid) { + mLineIndex = i; + break; + } + } + } + var transceiver = this.transceivers[mLineIndex]; + if (transceiver) { + var cand = Object.keys(candidate.candidate).length > 0 ? + SDPUtils.parseCandidate(candidate.candidate) : {}; + // Ignore Chrome's invalid candidates since Edge does not like them. + if (cand.protocol === 'tcp' && (cand.port === 0 || cand.port === 9)) { + return Promise.resolve(); + } + // Ignore RTCP candidates, we assume RTCP-MUX. + if (cand.component !== '1') { + return Promise.resolve(); + } + transceiver.iceTransport.addRemoteCandidate(cand); + + // update the remoteDescription. + var sections = SDPUtils.splitSections(this.remoteDescription.sdp); + sections[mLineIndex + 1] += (cand.type ? candidate.candidate.trim() + : 'a=end-of-candidates') + '\r\n'; + this.remoteDescription.sdp = sections.join(''); + } + } + if (arguments.length > 1 && typeof arguments[1] === 'function') { + window.setTimeout(arguments[1], 0); + } + return Promise.resolve(); + }; + + RTCPeerConnection.prototype.getStats = function() { + var promises = []; + this.transceivers.forEach(function(transceiver) { + ['rtpSender', 'rtpReceiver', 'iceGatherer', 'iceTransport', + 'dtlsTransport'].forEach(function(method) { + if (transceiver[method]) { + promises.push(transceiver[method].getStats()); + } + }); + }); + var cb = arguments.length > 1 && typeof arguments[1] === 'function' && + arguments[1]; + var fixStatsType = function(stat) { + return { + inboundrtp: 'inbound-rtp', + outboundrtp: 'outbound-rtp', + candidatepair: 'candidate-pair', + localcandidate: 'local-candidate', + remotecandidate: 'remote-candidate' + }[stat.type] || stat.type; + }; + return new Promise(function(resolve) { + // shim getStats with maplike support + var results = new Map(); + Promise.all(promises).then(function(res) { + res.forEach(function(result) { + Object.keys(result).forEach(function(id) { + result[id].type = fixStatsType(result[id]); + results.set(id, result[id]); + }); + }); + if (cb) { + window.setTimeout(cb, 0, results); + } + resolve(results); + }); + }); + }; + return RTCPeerConnection; +}; + +},{"sdp":17}],27:[function(require,module,exports){ /* * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. * @@ -7198,10 +6280,10 @@ module.exports = function(window) { /* eslint-env node */ 'use strict'; -var utils = require('../utils'); +var browserDetails = require('../utils').browserDetails; var firefoxShim = { - shimOnTrack: function(window) { + shimOnTrack: function() { if (typeof window === 'object' && window.RTCPeerConnection && !('ontrack' in window.RTCPeerConnection.prototype)) { Object.defineProperty(window.RTCPeerConnection.prototype, 'ontrack', { @@ -7219,7 +6301,6 @@ var firefoxShim = { var event = new Event('track'); event.track = track; event.receiver = {track: track}; - event.transceiver = {receiver: event.receiver}; event.streams = [e.stream]; this.dispatchEvent(event); }.bind(this)); @@ -7227,18 +6308,9 @@ var firefoxShim = { } }); } - if (typeof window === 'object' && window.RTCTrackEvent && - ('receiver' in window.RTCTrackEvent.prototype) && - !('transceiver' in window.RTCTrackEvent.prototype)) { - Object.defineProperty(window.RTCTrackEvent.prototype, 'transceiver', { - get: function() { - return {receiver: this.receiver}; - } - }); - } }, - shimSourceObject: function(window) { + shimSourceObject: function() { // Firefox has supported mozSrcObject since FF22, unprefixed in 42. if (typeof window === 'object') { if (window.HTMLMediaElement && @@ -7256,9 +6328,7 @@ var firefoxShim = { } }, - shimPeerConnection: function(window) { - var browserDetails = utils.detectBrowser(window); - + shimPeerConnection: function() { if (typeof window !== 'object' || !(window.RTCPeerConnection || window.mozRTCPeerConnection)) { return; // probably media.peerconnection.enabled=false in about:config @@ -7291,40 +6361,38 @@ var firefoxShim = { pcConfig.iceServers = newIceServers; } } - return new window.mozRTCPeerConnection(pcConfig, pcConstraints); + return new mozRTCPeerConnection(pcConfig, pcConstraints); }; - window.RTCPeerConnection.prototype = - window.mozRTCPeerConnection.prototype; + window.RTCPeerConnection.prototype = mozRTCPeerConnection.prototype; // wrap static methods. Currently just generateCertificate. - if (window.mozRTCPeerConnection.generateCertificate) { + if (mozRTCPeerConnection.generateCertificate) { Object.defineProperty(window.RTCPeerConnection, 'generateCertificate', { get: function() { - return window.mozRTCPeerConnection.generateCertificate; + return mozRTCPeerConnection.generateCertificate; } }); } - window.RTCSessionDescription = window.mozRTCSessionDescription; - window.RTCIceCandidate = window.mozRTCIceCandidate; + window.RTCSessionDescription = mozRTCSessionDescription; + window.RTCIceCandidate = mozRTCIceCandidate; } // shim away need for obsolete RTCIceCandidate/RTCSessionDescription. ['setLocalDescription', 'setRemoteDescription', 'addIceCandidate'] .forEach(function(method) { - var nativeMethod = window.RTCPeerConnection.prototype[method]; - window.RTCPeerConnection.prototype[method] = function() { + var nativeMethod = RTCPeerConnection.prototype[method]; + RTCPeerConnection.prototype[method] = function() { arguments[0] = new ((method === 'addIceCandidate') ? - window.RTCIceCandidate : - window.RTCSessionDescription)(arguments[0]); + RTCIceCandidate : RTCSessionDescription)(arguments[0]); return nativeMethod.apply(this, arguments); }; }); // support for addIceCandidate(null or undefined) var nativeAddIceCandidate = - window.RTCPeerConnection.prototype.addIceCandidate; - window.RTCPeerConnection.prototype.addIceCandidate = function() { + RTCPeerConnection.prototype.addIceCandidate; + RTCPeerConnection.prototype.addIceCandidate = function() { if (!arguments[0]) { if (arguments[1]) { arguments[1].apply(null); @@ -7352,12 +6420,8 @@ var firefoxShim = { remotecandidate: 'remote-candidate' }; - var nativeGetStats = window.RTCPeerConnection.prototype.getStats; - window.RTCPeerConnection.prototype.getStats = function( - selector, - onSucc, - onErr - ) { + var nativeGetStats = RTCPeerConnection.prototype.getStats; + RTCPeerConnection.prototype.getStats = function(selector, onSucc, onErr) { return nativeGetStats.apply(this, [selector || null]) .then(function(stats) { if (browserDetails.version < 48) { @@ -7397,7 +6461,7 @@ module.exports = { shimGetUserMedia: require('./getusermedia') }; -},{"../utils":32,"./getusermedia":30}],30:[function(require,module,exports){ +},{"../utils":30,"./getusermedia":28}],28:[function(require,module,exports){ /* * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. * @@ -7408,22 +6472,17 @@ module.exports = { /* eslint-env node */ 'use strict'; -var utils = require('../utils'); -var logging = utils.log; +var logging = require('../utils').log; +var browserDetails = require('../utils').browserDetails; // Expose public methods. -module.exports = function(window) { - var browserDetails = utils.detectBrowser(window); - var navigator = window && window.navigator; - var MediaStreamTrack = window && window.MediaStreamTrack; - +module.exports = function() { var shimError_ = function(e) { return { name: { - InternalError: 'NotReadableError', NotSupportedError: 'TypeError', - PermissionDeniedError: 'NotAllowedError', - SecurityError: 'NotAllowedError' + SecurityError: 'NotAllowedError', + PermissionDeniedError: 'NotAllowedError' }[e.name] || e.name, message: { 'The operation is insecure.': 'The request is not allowed by the ' + @@ -7555,60 +6614,18 @@ module.exports = function(window) { }); }; } - if (!(browserDetails.version > 55 && - 'autoGainControl' in navigator.mediaDevices.getSupportedConstraints())) { - var remap = function(obj, a, b) { - if (a in obj && !(b in obj)) { - obj[b] = obj[a]; - delete obj[a]; - } - }; - - var nativeGetUserMedia = navigator.mediaDevices.getUserMedia. - bind(navigator.mediaDevices); - navigator.mediaDevices.getUserMedia = function(c) { - if (typeof c === 'object' && typeof c.audio === 'object') { - c = JSON.parse(JSON.stringify(c)); - remap(c.audio, 'autoGainControl', 'mozAutoGainControl'); - remap(c.audio, 'noiseSuppression', 'mozNoiseSuppression'); - } - return nativeGetUserMedia(c); - }; - - if (MediaStreamTrack && MediaStreamTrack.prototype.getSettings) { - var nativeGetSettings = MediaStreamTrack.prototype.getSettings; - MediaStreamTrack.prototype.getSettings = function() { - var obj = nativeGetSettings.apply(this, arguments); - remap(obj, 'mozAutoGainControl', 'autoGainControl'); - remap(obj, 'mozNoiseSuppression', 'noiseSuppression'); - return obj; - }; - } - - if (MediaStreamTrack && MediaStreamTrack.prototype.applyConstraints) { - var nativeApplyConstraints = MediaStreamTrack.prototype.applyConstraints; - MediaStreamTrack.prototype.applyConstraints = function(c) { - if (this.kind === 'audio' && typeof c === 'object') { - c = JSON.parse(JSON.stringify(c)); - remap(c, 'autoGainControl', 'mozAutoGainControl'); - remap(c, 'noiseSuppression', 'mozNoiseSuppression'); - } - return nativeApplyConstraints.apply(this, [c]); - }; - } - } navigator.getUserMedia = function(constraints, onSuccess, onError) { if (browserDetails.version < 44) { return getUserMedia_(constraints, onSuccess, onError); } // Replace Firefox 44+'s deprecation warning with unprefixed version. - utils.deprecated('navigator.getUserMedia', - 'navigator.mediaDevices.getUserMedia'); + console.warn('navigator.getUserMedia has been replaced by ' + + 'navigator.mediaDevices.getUserMedia'); navigator.mediaDevices.getUserMedia(constraints).then(onSuccess, onError); }; }; -},{"../utils":32}],31:[function(require,module,exports){ +},{"../utils":30}],29:[function(require,module,exports){ /* * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. * @@ -7617,8 +6634,6 @@ module.exports = function(window) { * tree. */ 'use strict'; -var utils = require('../utils'); - var safariShim = { // TODO: DrAlex, should be here, double check against LayoutTests @@ -7626,94 +6641,9 @@ var safariShim = { // TODO: check for webkitGTK+ // shimPeerConnection: function() { }, - shimLocalStreamsAPI: function(window) { - if (typeof window !== 'object' || !window.RTCPeerConnection) { - return; - } - if (!('getLocalStreams' in window.RTCPeerConnection.prototype)) { - window.RTCPeerConnection.prototype.getLocalStreams = function() { - if (!this._localStreams) { - this._localStreams = []; - } - return this._localStreams; - }; - } - if (!('getStreamById' in window.RTCPeerConnection.prototype)) { - window.RTCPeerConnection.prototype.getStreamById = function(id) { - var result = null; - if (this._localStreams) { - this._localStreams.forEach(function(stream) { - if (stream.id === id) { - result = stream; - } - }); - } - if (this._remoteStreams) { - this._remoteStreams.forEach(function(stream) { - if (stream.id === id) { - result = stream; - } - }); - } - return result; - }; - } - if (!('addStream' in window.RTCPeerConnection.prototype)) { - var _addTrack = window.RTCPeerConnection.prototype.addTrack; - window.RTCPeerConnection.prototype.addStream = function(stream) { - if (!this._localStreams) { - this._localStreams = []; - } - if (this._localStreams.indexOf(stream) === -1) { - this._localStreams.push(stream); - } - var self = this; - stream.getTracks().forEach(function(track) { - _addTrack.call(self, track, stream); - }); - }; - - window.RTCPeerConnection.prototype.addTrack = function(track, stream) { - if (stream) { - if (!this._localStreams) { - this._localStreams = [stream]; - } else if (this._localStreams.indexOf(stream) === -1) { - this._localStreams.push(stream); - } - } - _addTrack.call(this, track, stream); - }; - } - if (!('removeStream' in window.RTCPeerConnection.prototype)) { - window.RTCPeerConnection.prototype.removeStream = function(stream) { - if (!this._localStreams) { - this._localStreams = []; - } - var index = this._localStreams.indexOf(stream); - if (index === -1) { - return; - } - this._localStreams.splice(index, 1); - var self = this; - var tracks = stream.getTracks(); - this.getSenders().forEach(function(sender) { - if (tracks.indexOf(sender.track) !== -1) { - self.removeTrack(sender); - } - }); - }; - } - }, - shimRemoteStreamsAPI: function(window) { - if (typeof window !== 'object' || !window.RTCPeerConnection) { - return; - } - if (!('getRemoteStreams' in window.RTCPeerConnection.prototype)) { - window.RTCPeerConnection.prototype.getRemoteStreams = function() { - return this._remoteStreams ? this._remoteStreams : []; - }; - } - if (!('onaddstream' in window.RTCPeerConnection.prototype)) { + shimOnAddStream: function() { + if (typeof window === 'object' && window.RTCPeerConnection && + !('onaddstream' in window.RTCPeerConnection.prototype)) { Object.defineProperty(window.RTCPeerConnection.prototype, 'onaddstream', { get: function() { return this._onaddstream; @@ -7726,13 +6656,13 @@ var safariShim = { this.addEventListener('addstream', this._onaddstream = f); this.addEventListener('track', this._onaddstreampoly = function(e) { var stream = e.streams[0]; - if (!this._remoteStreams) { - this._remoteStreams = []; + if (!this._streams) { + this._streams = []; } - if (this._remoteStreams.indexOf(stream) >= 0) { + if (this._streams.indexOf(stream) >= 0) { return; } - this._remoteStreams.push(stream); + this._streams.push(stream); var event = new Event('addstream'); event.stream = e.streams[0]; this.dispatchEvent(event); @@ -7741,70 +6671,8 @@ var safariShim = { }); } }, - shimCallbacksAPI: function(window) { - if (typeof window !== 'object' || !window.RTCPeerConnection) { - return; - } - var prototype = window.RTCPeerConnection.prototype; - var createOffer = prototype.createOffer; - var createAnswer = prototype.createAnswer; - var setLocalDescription = prototype.setLocalDescription; - var setRemoteDescription = prototype.setRemoteDescription; - var addIceCandidate = prototype.addIceCandidate; - - prototype.createOffer = function(successCallback, failureCallback) { - var options = (arguments.length >= 2) ? arguments[2] : arguments[0]; - var promise = createOffer.apply(this, [options]); - if (!failureCallback) { - return promise; - } - promise.then(successCallback, failureCallback); - return Promise.resolve(); - }; - - prototype.createAnswer = function(successCallback, failureCallback) { - var options = (arguments.length >= 2) ? arguments[2] : arguments[0]; - var promise = createAnswer.apply(this, [options]); - if (!failureCallback) { - return promise; - } - promise.then(successCallback, failureCallback); - return Promise.resolve(); - }; - - var withCallback = function(description, successCallback, failureCallback) { - var promise = setLocalDescription.apply(this, [description]); - if (!failureCallback) { - return promise; - } - promise.then(successCallback, failureCallback); - return Promise.resolve(); - }; - prototype.setLocalDescription = withCallback; - - withCallback = function(description, successCallback, failureCallback) { - var promise = setRemoteDescription.apply(this, [description]); - if (!failureCallback) { - return promise; - } - promise.then(successCallback, failureCallback); - return Promise.resolve(); - }; - prototype.setRemoteDescription = withCallback; - - withCallback = function(candidate, successCallback, failureCallback) { - var promise = addIceCandidate.apply(this, [candidate]); - if (!failureCallback) { - return promise; - } - promise.then(successCallback, failureCallback); - return Promise.resolve(); - }; - prototype.addIceCandidate = withCallback; - }, - shimGetUserMedia: function(window) { - var navigator = window && window.navigator; + shimGetUserMedia: function() { if (!navigator.getUserMedia) { if (navigator.webkitGetUserMedia) { navigator.getUserMedia = navigator.webkitGetUserMedia.bind(navigator); @@ -7816,69 +6684,18 @@ var safariShim = { }.bind(navigator); } } - }, - shimRTCIceServerUrls: function(window) { - // migrate from non-spec RTCIceServer.url to RTCIceServer.urls - var OrigPeerConnection = window.RTCPeerConnection; - window.RTCPeerConnection = function(pcConfig, pcConstraints) { - if (pcConfig && pcConfig.iceServers) { - var newIceServers = []; - for (var i = 0; i < pcConfig.iceServers.length; i++) { - var server = pcConfig.iceServers[i]; - if (!server.hasOwnProperty('urls') && - server.hasOwnProperty('url')) { - utils.deprecated('RTCIceServer.url', 'RTCIceServer.urls'); - server = JSON.parse(JSON.stringify(server)); - server.urls = server.url; - delete server.url; - newIceServers.push(server); - } else { - newIceServers.push(pcConfig.iceServers[i]); - } - } - pcConfig.iceServers = newIceServers; - } - return new OrigPeerConnection(pcConfig, pcConstraints); - }; - window.RTCPeerConnection.prototype = OrigPeerConnection.prototype; - // wrap static methods. Currently just generateCertificate. - if ('generateCertificate' in window.RTCPeerConnection) { - Object.defineProperty(window.RTCPeerConnection, 'generateCertificate', { - get: function() { - return OrigPeerConnection.generateCertificate; - } - }); - } - }, - shimTrackEventTransceiver: function(window) { - // Add event.transceiver member over deprecated event.receiver - if (typeof window === 'object' && window.RTCPeerConnection && - ('receiver' in window.RTCTrackEvent.prototype) && - // can't check 'transceiver' in window.RTCTrackEvent.prototype, as it is - // defined for some reason even when window.RTCTransceiver is not. - !window.RTCTransceiver) { - Object.defineProperty(window.RTCTrackEvent.prototype, 'transceiver', { - get: function() { - return {receiver: this.receiver}; - } - }); - } } }; // Expose public methods. module.exports = { - shimCallbacksAPI: safariShim.shimCallbacksAPI, - shimLocalStreamsAPI: safariShim.shimLocalStreamsAPI, - shimRemoteStreamsAPI: safariShim.shimRemoteStreamsAPI, - shimGetUserMedia: safariShim.shimGetUserMedia, - shimRTCIceServerUrls: safariShim.shimRTCIceServerUrls, - shimTrackEventTransceiver: safariShim.shimTrackEventTransceiver + shimOnAddStream: safariShim.shimOnAddStream, + shimGetUserMedia: safariShim.shimGetUserMedia // TODO // shimPeerConnection: safariShim.shimPeerConnection }; -},{"../utils":32}],32:[function(require,module,exports){ +},{}],30:[function(require,module,exports){ /* * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. * @@ -7890,7 +6707,6 @@ module.exports = { 'use strict'; var logDisabled_ = true; -var deprecationWarnings_ = true; // Utility methods. var utils = { @@ -7904,19 +6720,6 @@ var utils = { 'adapter.js logging enabled'; }, - /** - * Disable or enable deprecation warnings - * @param {!boolean} bool set to true to disable warnings. - */ - disableWarnings: function(bool) { - if (typeof bool !== 'boolean') { - return new Error('Argument type: ' + typeof bool + - '. Please use a boolean.'); - } - deprecationWarnings_ = !bool; - return 'adapter.js deprecation warnings ' + (bool ? 'disabled' : 'enabled'); - }, - log: function() { if (typeof window === 'object') { if (logDisabled_) { @@ -7928,17 +6731,6 @@ var utils = { } }, - /** - * Shows a deprecation warning suggesting the modern and spec-compatible API. - */ - deprecated: function(oldMethod, newMethod) { - if (!deprecationWarnings_) { - return; - } - console.warn(oldMethod + ' is deprecated, please use ' + newMethod + - ' instead.'); - }, - /** * Extract browser version out of the provided user agent string. * @@ -7958,9 +6750,7 @@ var utils = { * @return {object} result containing browser and version * properties. */ - detectBrowser: function(window) { - var navigator = window && window.navigator; - + detectBrowser: function() { // Returned result object. var result = {}; result.browser = null; @@ -8013,20 +6803,68 @@ var utils = { return result; }, + // shimCreateObjectURL must be called before shimSourceObject to avoid loop. + + shimCreateObjectURL: function() { + if (!(typeof window === 'object' && window.HTMLMediaElement && + 'srcObject' in window.HTMLMediaElement.prototype)) { + // Only shim CreateObjectURL using srcObject if srcObject exists. + return undefined; + } + + var nativeCreateObjectURL = URL.createObjectURL.bind(URL); + var nativeRevokeObjectURL = URL.revokeObjectURL.bind(URL); + var streams = new Map(), newId = 0; + + URL.createObjectURL = function(stream) { + if ('getTracks' in stream) { + var url = 'polyblob:' + (++newId); + streams.set(url, stream); + console.log('URL.createObjectURL(stream) is deprecated! ' + + 'Use elem.srcObject = stream instead!'); + return url; + } + return nativeCreateObjectURL(stream); + }; + URL.revokeObjectURL = function(url) { + nativeRevokeObjectURL(url); + streams.delete(url); + }; + + var dsc = Object.getOwnPropertyDescriptor(window.HTMLMediaElement.prototype, + 'src'); + Object.defineProperty(window.HTMLMediaElement.prototype, 'src', { + get: function() { + return dsc.get.apply(this); + }, + set: function(url) { + this.srcObject = streams.get(url) || null; + return dsc.set.apply(this, [url]); + } + }); + + var nativeSetAttribute = HTMLMediaElement.prototype.setAttribute; + HTMLMediaElement.prototype.setAttribute = function() { + if (arguments.length === 2 && + ('' + arguments[0]).toLowerCase() === 'src') { + this.srcObject = streams.get(arguments[1]) || null; + } + return nativeSetAttribute.apply(this, arguments); + }; + } }; // Export. module.exports = { log: utils.log, - deprecated: utils.deprecated, disableLog: utils.disableLog, - disableWarnings: utils.disableWarnings, + browserDetails: utils.detectBrowser(), extractVersion: utils.extractVersion, shimCreateObjectURL: utils.shimCreateObjectURL, detectBrowser: utils.detectBrowser.bind(utils) }; -},{}],33:[function(require,module,exports){ +},{}],31:[function(require,module,exports){ /* WildEmitter.js is a slim little event emitter by @henrikjoreteg largely based on @visionmedia's Emitter from UI Kit. @@ -8181,7 +7019,7 @@ WildEmitter.mixin = function (constructor) { WildEmitter.mixin(WildEmitter); -},{}],34:[function(require,module,exports){ +},{}],32:[function(require,module,exports){ /*! * EventEmitter v4.2.9 - git.io/ee * Oliver Caldwell @@ -8655,7 +7493,7 @@ WildEmitter.mixin(WildEmitter); } }.call(this)); -},{}],35:[function(require,module,exports){ +},{}],33:[function(require,module,exports){ function Mapper() { var sources = {}; this.forEach = function (callback) { @@ -8702,7 +7540,7 @@ Mapper.prototype.pop = function (id, source) { }; module.exports = Mapper; -},{}],36:[function(require,module,exports){ +},{}],34:[function(require,module,exports){ /* * (C) Copyright 2014 Kurento (http://kurento.org/) * @@ -8722,7 +7560,7 @@ module.exports = Mapper; var JsonRpcClient = require('./jsonrpcclient'); exports.JsonRpcClient = JsonRpcClient; -},{"./jsonrpcclient":37}],37:[function(require,module,exports){ +},{"./jsonrpcclient":35}],35:[function(require,module,exports){ /* * (C) Copyright 2014 Kurento (http://kurento.org/) * @@ -8958,7 +7796,7 @@ function JsonRpcClient(configuration) { } module.exports = JsonRpcClient; -},{"../":40,"./transports/webSocketWithReconnection":39}],38:[function(require,module,exports){ +},{"../":38,"./transports/webSocketWithReconnection":37}],36:[function(require,module,exports){ /* * (C) Copyright 2014 Kurento (http://kurento.org/) * @@ -8978,7 +7816,7 @@ module.exports = JsonRpcClient; var WebSocketWithReconnection = require('./webSocketWithReconnection'); exports.WebSocketWithReconnection = WebSocketWithReconnection; -},{"./webSocketWithReconnection":39}],39:[function(require,module,exports){ +},{"./webSocketWithReconnection":37}],37:[function(require,module,exports){ (function (global){ /* * (C) Copyright 2013-2015 Kurento (http://kurento.org/) @@ -9187,7 +8025,7 @@ module.exports = WebSocketWithReconnection; }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{}],40:[function(require,module,exports){ +},{}],38:[function(require,module,exports){ /* * (C) Copyright 2014 Kurento (http://kurento.org/) * @@ -9805,7 +8643,7 @@ RpcBuilder.clients = clients; RpcBuilder.clients.transports = transports; RpcBuilder.packers = packers; -},{"./Mapper":35,"./clients":36,"./clients/transports":38,"./packers":43,"events":1,"inherits":6}],41:[function(require,module,exports){ +},{"./Mapper":33,"./clients":34,"./clients/transports":36,"./packers":41,"events":1,"inherits":6}],39:[function(require,module,exports){ /** * JsonRPC 2.0 packer */ @@ -9885,7 +8723,7 @@ function unpack(message) { exports.pack = pack; exports.unpack = unpack; -},{}],42:[function(require,module,exports){ +},{}],40:[function(require,module,exports){ function pack(message) { throw new TypeError("Not yet implemented"); } @@ -9897,13 +8735,13 @@ function unpack(message) { exports.pack = pack; exports.unpack = unpack; -},{}],43:[function(require,module,exports){ +},{}],41:[function(require,module,exports){ var JsonRPC = require('./JsonRPC'); var XmlRPC = require('./XmlRPC'); exports.JsonRPC = JsonRPC; exports.XmlRPC = XmlRPC; -},{"./JsonRPC":41,"./XmlRPC":42}],44:[function(require,module,exports){ +},{"./JsonRPC":39,"./XmlRPC":40}],42:[function(require,module,exports){ /* * (C) Copyright 2014-2015 Kurento (http://kurento.org/) * @@ -10567,7 +9405,7 @@ exports.WebRtcPeerSendonly = WebRtcPeerSendonly; exports.WebRtcPeerSendrecv = WebRtcPeerSendrecv; exports.hark = harkUtils; -},{"events":1,"freeice":2,"hark":5,"inherits":6,"merge":7,"sdp-translator":15,"ua-parser-js":19,"uuid":21}],45:[function(require,module,exports){ +},{"events":1,"freeice":2,"hark":5,"inherits":6,"merge":7,"sdp-translator":14,"ua-parser-js":18,"uuid":20}],43:[function(require,module,exports){ /* * (C) Copyright 2014 Kurento (http://kurento.org/) * @@ -10596,7 +9434,7 @@ exports.hark = harkUtils; var WebRtcPeer = require('./WebRtcPeer'); exports.WebRtcPeer = WebRtcPeer; -},{"./WebRtcPeer":44}],46:[function(require,module,exports){ +},{"./WebRtcPeer":42}],44:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var OpenVidu_1 = require("./OpenVidu"); @@ -10609,7 +9447,7 @@ if (window) { //Command to generate bundle.js without namespace //watchify Main.ts -p [ tsify ] --exclude kurento-browser-extensions --debug -o ../static/js/OpenVidu.js -v -},{"./OpenVidu":47}],47:[function(require,module,exports){ +},{"./OpenVidu":45}],45:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); /* @@ -10720,7 +9558,7 @@ var OpenVidu = /** @class */ (function () { }()); exports.OpenVidu = OpenVidu; -},{"../OpenViduInternal/OpenViduInternal":52,"./Publisher":48,"./Session":49,"webrtc-adapter":22}],48:[function(require,module,exports){ +},{"../OpenViduInternal/OpenViduInternal":50,"./Publisher":46,"./Session":47,"webrtc-adapter":21}],46:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var EventEmitter = require("wolfy87-eventemitter"); @@ -10822,17 +9660,6 @@ var Publisher = /** @class */ (function () { }); } } - if (eventName == 'streamCreated') { - if (this.stream.isReady) { - this.ee.emitEvent('streamCreated', [{ stream: this.stream }]); - } - else { - this.stream.addEventListener('stream-created-by-publisher', function () { - console.warn('Publisher emitting streamCreated'); - _this.ee.emitEvent('streamCreated', [{ stream: _this.stream }]); - }); - } - } if (eventName == 'accessAllowed') { if (this.stream.accessIsAllowed) { this.ee.emitEvent('accessAllowed'); @@ -10858,7 +9685,7 @@ var Publisher = /** @class */ (function () { }()); exports.Publisher = Publisher; -},{"wolfy87-eventemitter":34}],49:[function(require,module,exports){ +},{"wolfy87-eventemitter":32}],47:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var Subscriber_1 = require("./Subscriber"); @@ -11008,7 +9835,7 @@ var Session = /** @class */ (function () { }()); exports.Session = Session; -},{"./Subscriber":50,"wolfy87-eventemitter":34}],50:[function(require,module,exports){ +},{"./Subscriber":48,"wolfy87-eventemitter":32}],48:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var EventEmitter = require("wolfy87-eventemitter"); @@ -11071,7 +9898,7 @@ var Subscriber = /** @class */ (function () { }()); exports.Subscriber = Subscriber; -},{"wolfy87-eventemitter":34}],51:[function(require,module,exports){ +},{"wolfy87-eventemitter":32}],49:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var Stream_1 = require("./Stream"); @@ -11143,7 +9970,7 @@ var Connection = /** @class */ (function () { }()); exports.Connection = Connection; -},{"./Stream":54}],52:[function(require,module,exports){ +},{"./Stream":52}],50:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); /* @@ -11477,7 +10304,7 @@ var OpenViduInternal = /** @class */ (function () { }()); exports.OpenViduInternal = OpenViduInternal; -},{"../KurentoUtils/kurento-jsonrpc":40,"./SessionInternal":53,"./Stream":54}],53:[function(require,module,exports){ +},{"../KurentoUtils/kurento-jsonrpc":38,"./SessionInternal":51,"./Stream":52}],51:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var Connection_1 = require("./Connection"); @@ -11599,7 +10426,6 @@ var SessionInternal = /** @class */ (function () { // Adding the remote stream to the OpenVidu object _this.openVidu.getRemoteStreams().push(stream); } - //} callback(undefined); } }); @@ -11669,12 +10495,12 @@ var SessionInternal = /** @class */ (function () { }); }; SessionInternal.prototype.onParticipantPublished = function (options) { - options.metadata = this.participants[options.id].data; // Get the existing Connection created on 'onParticipantJoined' for // existing participants or create a new one for new participants var connection = this.participants[options.id]; if (connection) { // Update existing Connection + options.metadata = connection.data; connection.options = options; connection.initStreams(options); } @@ -11689,16 +10515,16 @@ var SessionInternal = /** @class */ (function () { else { console.debug("Remote Connection found in connections list by its id [" + pid + "]"); } - connection.creationTime = this.participants[pid].creationTime; this.participants[pid] = connection; this.ee.emitEvent('participant-published', [{ connection: connection }]); var streams = connection.getStreams(); for (var key in streams) { + console.log(''); var stream = streams[key]; + this.ee.emitEvent('streamCreated', [{ stream: stream }]); if (this.subscribeToStreams) { stream.subscribe(); } - this.ee.emitEvent('streamCreated', [{ stream: stream }]); // Adding the remote stream to the OpenVidu object this.openVidu.getRemoteStreams().push(stream); } @@ -11950,7 +10776,7 @@ var SessionInternal = /** @class */ (function () { }()); exports.SessionInternal = SessionInternal; -},{"./Connection":51,"wolfy87-eventemitter":34}],54:[function(require,module,exports){ +},{"./Connection":49,"wolfy87-eventemitter":32}],52:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var EventEmitter = require("wolfy87-eventemitter"); @@ -12156,7 +10982,6 @@ var Stream = /** @class */ (function () { this.parentId = parentElement.id; this.video = parentElement.appendChild(this.video); } - this.ee.emitEvent('stream-created-by-publisher'); this.isReady = true; return this.video; }; @@ -12403,19 +11228,21 @@ var Stream = /** @class */ (function () { console.debug("Peer remote stream", _this.wrStream); if (_this.wrStream != undefined) { _this.emitSrcEvent(_this.wrStream); - _this.speechEvent = kurentoUtils.WebRtcPeer.hark(_this.wrStream, { threshold: _this.room.thresholdSpeaker }); - _this.speechEvent.on('speaking', function () { - _this.room.addParticipantSpeaking(participantId); - _this.room.emitEvent('stream-speaking', [{ - participantId: participantId - }]); - }); - _this.speechEvent.on('stopped_speaking', function () { - _this.room.removeParticipantSpeaking(participantId); - _this.room.emitEvent('stream-stopped-speaking', [{ - participantId: participantId - }]); - }); + if (_this.wrStream.getAudioTracks()[0] != null) { + _this.speechEvent = kurentoUtils.WebRtcPeer.hark(_this.wrStream, { threshold: _this.room.thresholdSpeaker }); + _this.speechEvent.on('speaking', function () { + _this.room.addParticipantSpeaking(participantId); + _this.room.emitEvent('stream-speaking', [{ + participantId: participantId + }]); + }); + _this.speechEvent.on('stopped_speaking', function () { + _this.room.removeParticipantSpeaking(participantId); + _this.room.emitEvent('stream-stopped-speaking', [{ + participantId: participantId + }]); + }); + } } for (var _i = 0, _a = _this.videoElements; _i < _a.length; _i++) { var videoElement = _a[_i]; @@ -12498,5 +11325,5 @@ var Stream = /** @class */ (function () { }()); exports.Stream = Stream; -},{"../KurentoUtils/kurento-utils-js":45,"webrtc-adapter":22,"wolfy87-eventemitter":34}]},{},[46]) -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL25vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvZXZlbnRzL2V2ZW50cy5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9mcmVlaWNlL2luZGV4LmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL2ZyZWVpY2Uvc3R1bi5qc29uIiwiLi4vLi4vbm9kZV9tb2R1bGVzL2ZyZWVpY2UvdHVybi5qc29uIiwiLi4vLi4vbm9kZV9tb2R1bGVzL2hhcmsvaGFyay5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9pbmhlcml0cy9pbmhlcml0c19icm93c2VyLmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL21lcmdlL21lcmdlLmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL25vcm1hbGljZS9pbmRleC5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9ydGNwZWVyY29ubmVjdGlvbi1zaGltL3J0Y3BlZXJjb25uZWN0aW9uLmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL3NkcC10cmFuc2Zvcm0vbGliL2dyYW1tYXIuanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvc2RwLXRyYW5zZm9ybS9saWIvaW5kZXguanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvc2RwLXRyYW5zZm9ybS9saWIvcGFyc2VyLmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL3NkcC10cmFuc2Zvcm0vbGliL3dyaXRlci5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9zZHAtdHJhbnNsYXRvci9saWIvYXJyYXktZXF1YWxzLmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL3NkcC10cmFuc2xhdG9yL2xpYi9pbmRleC5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9zZHAtdHJhbnNsYXRvci9saWIvaW50ZXJvcC5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9zZHAtdHJhbnNsYXRvci9saWIvdHJhbnNmb3JtLmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL3NkcC9zZHAuanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvdWEtcGFyc2VyLWpzL3NyYy91YS1wYXJzZXIuanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvdXVpZC9ybmctYnJvd3Nlci5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy91dWlkL3V1aWQuanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvd2VicnRjLWFkYXB0ZXIvc3JjL2pzL2FkYXB0ZXJfY29yZS5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy93ZWJydGMtYWRhcHRlci9zcmMvanMvYWRhcHRlcl9mYWN0b3J5LmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL3dlYnJ0Yy1hZGFwdGVyL3NyYy9qcy9jaHJvbWUvY2hyb21lX3NoaW0uanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvd2VicnRjLWFkYXB0ZXIvc3JjL2pzL2Nocm9tZS9nZXR1c2VybWVkaWEuanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvd2VicnRjLWFkYXB0ZXIvc3JjL2pzL2NvbW1vbl9zaGltLmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL3dlYnJ0Yy1hZGFwdGVyL3NyYy9qcy9lZGdlL2VkZ2Vfc2hpbS5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy93ZWJydGMtYWRhcHRlci9zcmMvanMvZWRnZS9nZXR1c2VybWVkaWEuanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvd2VicnRjLWFkYXB0ZXIvc3JjL2pzL2ZpcmVmb3gvZmlyZWZveF9zaGltLmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL3dlYnJ0Yy1hZGFwdGVyL3NyYy9qcy9maXJlZm94L2dldHVzZXJtZWRpYS5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy93ZWJydGMtYWRhcHRlci9zcmMvanMvc2FmYXJpL3NhZmFyaV9zaGltLmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL3dlYnJ0Yy1hZGFwdGVyL3NyYy9qcy91dGlscy5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy93aWxkZW1pdHRlci93aWxkZW1pdHRlci5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy93b2xmeTg3LWV2ZW50ZW1pdHRlci9FdmVudEVtaXR0ZXIuanMiLCIuLi9LdXJlbnRvVXRpbHMva3VyZW50by1qc29ucnBjL01hcHBlci5qcyIsIi4uL0t1cmVudG9VdGlscy9rdXJlbnRvLWpzb25ycGMvY2xpZW50cy9pbmRleC5qcyIsIi4uL0t1cmVudG9VdGlscy9rdXJlbnRvLWpzb25ycGMvY2xpZW50cy9qc29ucnBjY2xpZW50LmpzIiwiLi4vS3VyZW50b1V0aWxzL2t1cmVudG8tanNvbnJwYy9jbGllbnRzL3RyYW5zcG9ydHMvaW5kZXguanMiLCIuLi9LdXJlbnRvVXRpbHMva3VyZW50by1qc29ucnBjL2NsaWVudHMvdHJhbnNwb3J0cy93ZWJTb2NrZXRXaXRoUmVjb25uZWN0aW9uLmpzIiwiLi4vS3VyZW50b1V0aWxzL2t1cmVudG8tanNvbnJwYy9pbmRleC5qcyIsIi4uL0t1cmVudG9VdGlscy9rdXJlbnRvLWpzb25ycGMvcGFja2Vycy9Kc29uUlBDLmpzIiwiLi4vS3VyZW50b1V0aWxzL2t1cmVudG8tanNvbnJwYy9wYWNrZXJzL1htbFJQQy5qcyIsIi4uL0t1cmVudG9VdGlscy9rdXJlbnRvLWpzb25ycGMvcGFja2Vycy9pbmRleC5qcyIsIi4uL0t1cmVudG9VdGlscy9rdXJlbnRvLXV0aWxzLWpzL1dlYlJ0Y1BlZXIuanMiLCIuLi9LdXJlbnRvVXRpbHMva3VyZW50by11dGlscy1qcy9pbmRleC5qcyIsIk1haW4udHMiLCJPcGVuVmlkdS50cyIsIlB1Ymxpc2hlci50cyIsIlNlc3Npb24udHMiLCJTdWJzY3JpYmVyLnRzIiwiLi4vT3BlblZpZHVJbnRlcm5hbC9Db25uZWN0aW9uLnRzIiwiLi4vT3BlblZpZHVJbnRlcm5hbC9PcGVuVmlkdUludGVybmFsLnRzIiwiLi4vT3BlblZpZHVJbnRlcm5hbC9TZXNzaW9uSW50ZXJuYWwudHMiLCIuLi9PcGVuVmlkdUludGVybmFsL1N0cmVhbS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtBQ0FBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5U0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaEJBO0FBQ0E7O0FDREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzlLQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0aERBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqUUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzdGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsSEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbjNCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMW9CQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUN6Z0NBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQ2hDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDdkxBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUNiQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeklBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDanFCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3T0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0S0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hOQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDak5BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNVFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsSkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekpBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeGRBO0lBRUUsSUFBSSxPQUFPLEdBQUcsRUFBRSxDQUFDO0lBR2pCLElBQUksQ0FBQyxPQUFPLEdBQUcsVUFBUyxRQUFRO1FBRTlCLEdBQUcsQ0FBQSxDQUFDLElBQUks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Q0FBQyxLQUFLLEVBQUUsR0FBRyxrQ0FBa0MsQ0FBQyxDQUFDO0lBQ2pJLENBQUM7SUFDTCxhQUFDO0FBQUQsQ0FwbkJBLEFBb25CQyxJQUFBO0FBcG5CWSx3QkFBTSIsImZpbGUiOiJnZW5lcmF0ZWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlc0NvbnRlbnQiOlsiKGZ1bmN0aW9uIGUodCxuLHIpe2Z1bmN0aW9uIHMobyx1KXtpZighbltvXSl7aWYoIXRbb10pe3ZhciBhPXR5cGVvZiByZXF1aXJlPT1cImZ1bmN0aW9uXCImJnJlcXVpcmU7aWYoIXUmJmEpcmV0dXJuIGEobywhMCk7aWYoaSlyZXR1cm4gaShvLCEwKTt2YXIgZj1uZXcgRXJyb3IoXCJDYW5ub3QgZmluZCBtb2R1bGUgJ1wiK28rXCInXCIpO3Rocm93IGYuY29kZT1cIk1PRFVMRV9OT1RfRk9VTkRcIixmfXZhciBsPW5bb109e2V4cG9ydHM6e319O3Rbb11bMF0uY2FsbChsLmV4cG9ydHMsZnVuY3Rpb24oZSl7dmFyIG49dFtvXVsxXVtlXTtyZXR1cm4gcyhuP246ZSl9LGwsbC5leHBvcnRzLGUsdCxuLHIpfXJldHVybiBuW29dLmV4cG9ydHN9dmFyIGk9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtmb3IodmFyIG89MDtvPHIubGVuZ3RoO28rKylzKHJbb10pO3JldHVybiBzfSkiLCIvLyBDb3B5cmlnaHQgSm95ZW50LCBJbmMuIGFuZCBvdGhlciBOb2RlIGNvbnRyaWJ1dG9ycy5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYVxuLy8gY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZVxuLy8gXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nXG4vLyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsXG4vLyBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0XG4vLyBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGVcbi8vIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkXG4vLyBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTXG4vLyBPUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GXG4vLyBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOXG4vLyBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSxcbi8vIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUlxuLy8gT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRVxuLy8gVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS5cblxuZnVuY3Rpb24gRXZlbnRFbWl0dGVyKCkge1xuICB0aGlzLl9ldmVudHMgPSB0aGlzLl9ldmVudHMgfHwge307XG4gIHRoaXMuX21heExpc3RlbmVycyA9IHRoaXMuX21heExpc3RlbmVycyB8fCB1bmRlZmluZWQ7XG59XG5tb2R1bGUuZXhwb3J0cyA9IEV2ZW50RW1pdHRlcjtcblxuLy8gQmFja3dhcmRzLWNvbXBhdCB3aXRoIG5vZGUgMC4xMC54XG5FdmVudEVtaXR0ZXIuRXZlbnRFbWl0dGVyID0gRXZlbnRFbWl0dGVyO1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLl9ldmVudHMgPSB1bmRlZmluZWQ7XG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLl9tYXhMaXN0ZW5lcnMgPSB1bmRlZmluZWQ7XG5cbi8vIEJ5IGRlZmF1bHQgRXZlbnRFbWl0dGVycyB3aWxsIHByaW50IGEgd2FybmluZyBpZiBtb3JlIHRoYW4gMTAgbGlzdGVuZXJzIGFyZVxuLy8gYWRkZWQgdG8gaXQuIFRoaXMgaXMgYSB1c2VmdWwgZGVmYXVsdCB3aGljaCBoZWxwcyBmaW5kaW5nIG1lbW9yeSBsZWFrcy5cbkV2ZW50RW1pdHRlci5kZWZhdWx0TWF4TGlzdGVuZXJzID0gMTA7XG5cbi8vIE9idmlvdXNseSBub3QgYWxsIEVtaXR0ZXJzIHNob3VsZCBiZSBsaW1pdGVkIHRvIDEwLiBUaGlzIGZ1bmN0aW9uIGFsbG93c1xuLy8gdGhhdCB0byBiZSBpbmNyZWFzZWQuIFNldCB0byB6ZXJvIGZvciB1bmxpbWl0ZWQuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLnNldE1heExpc3RlbmVycyA9IGZ1bmN0aW9uKG4pIHtcbiAgaWYgKCFpc051bWJlcihuKSB8fCBuIDwgMCB8fCBpc05hTihuKSlcbiAgICB0aHJvdyBUeXBlRXJyb3IoJ24gbXVzdCBiZSBhIHBvc2l0aXZlIG51bWJlcicpO1xuICB0aGlzLl9tYXhMaXN0ZW5lcnMgPSBuO1xuICByZXR1cm4gdGhpcztcbn07XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuZW1pdCA9IGZ1bmN0aW9uKHR5cGUpIHtcbiAgdmFyIGVyLCBoYW5kbGVyLCBsZW4sIGFyZ3MsIGksIGxpc3RlbmVycztcblxuICBpZiAoIXRoaXMuX2V2ZW50cylcbiAgICB0aGlzLl9ldmVudHMgPSB7fTtcblxuICAvLyBJZiB0aGVyZSBpcyBubyAnZXJyb3InIGV2ZW50IGxpc3RlbmVyIHRoZW4gdGhyb3cuXG4gIGlmICh0eXBlID09PSAnZXJyb3InKSB7XG4gICAgaWYgKCF0aGlzLl9ldmVudHMuZXJyb3IgfHxcbiAgICAgICAgKGlzT2JqZWN0KHRoaXMuX2V2ZW50cy5lcnJvcikgJiYgIXRoaXMuX2V2ZW50cy5lcnJvci5sZW5ndGgpKSB7XG4gICAgICBlciA9IGFyZ3VtZW50c1sxXTtcbiAgICAgIGlmIChlciBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICAgIHRocm93IGVyOyAvLyBVbmhhbmRsZWQgJ2Vycm9yJyBldmVudFxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gQXQgbGVhc3QgZ2l2ZSBzb21lIGtpbmQgb2YgY29udGV4dCB0byB0aGUgdXNlclxuICAgICAgICB2YXIgZXJyID0gbmV3IEVycm9yKCdVbmNhdWdodCwgdW5zcGVjaWZpZWQgXCJlcnJvclwiIGV2ZW50LiAoJyArIGVyICsgJyknKTtcbiAgICAgICAgZXJyLmNvbnRleHQgPSBlcjtcbiAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGhhbmRsZXIgPSB0aGlzLl9ldmVudHNbdHlwZV07XG5cbiAgaWYgKGlzVW5kZWZpbmVkKGhhbmRsZXIpKVxuICAgIHJldHVybiBmYWxzZTtcblxuICBpZiAoaXNGdW5jdGlvbihoYW5kbGVyKSkge1xuICAgIHN3aXRjaCAoYXJndW1lbnRzLmxlbmd0aCkge1xuICAgICAgLy8gZmFzdCBjYXNlc1xuICAgICAgY2FzZSAxOlxuICAgICAgICBoYW5kbGVyLmNhbGwodGhpcyk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAyOlxuICAgICAgICBoYW5kbGVyLmNhbGwodGhpcywgYXJndW1lbnRzWzFdKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDM6XG4gICAgICAgIGhhbmRsZXIuY2FsbCh0aGlzLCBhcmd1bWVudHNbMV0sIGFyZ3VtZW50c1syXSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgLy8gc2xvd2VyXG4gICAgICBkZWZhdWx0OlxuICAgICAgICBhcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKTtcbiAgICAgICAgaGFuZGxlci5hcHBseSh0aGlzLCBhcmdzKTtcbiAgICB9XG4gIH0gZWxzZSBpZiAoaXNPYmplY3QoaGFuZGxlcikpIHtcbiAgICBhcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKTtcbiAgICBsaXN0ZW5lcnMgPSBoYW5kbGVyLnNsaWNlKCk7XG4gICAgbGVuID0gbGlzdGVuZXJzLmxlbmd0aDtcbiAgICBmb3IgKGkgPSAwOyBpIDwgbGVuOyBpKyspXG4gICAgICBsaXN0ZW5lcnNbaV0uYXBwbHkodGhpcywgYXJncyk7XG4gIH1cblxuICByZXR1cm4gdHJ1ZTtcbn07XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuYWRkTGlzdGVuZXIgPSBmdW5jdGlvbih0eXBlLCBsaXN0ZW5lcikge1xuICB2YXIgbTtcblxuICBpZiAoIWlzRnVuY3Rpb24obGlzdGVuZXIpKVxuICAgIHRocm93IFR5cGVFcnJvcignbGlzdGVuZXIgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG5cbiAgaWYgKCF0aGlzLl9ldmVudHMpXG4gICAgdGhpcy5fZXZlbnRzID0ge307XG5cbiAgLy8gVG8gYXZvaWQgcmVjdXJzaW9uIGluIHRoZSBjYXNlIHRoYXQgdHlwZSA9PT0gXCJuZXdMaXN0ZW5lclwiISBCZWZvcmVcbiAgLy8gYWRkaW5nIGl0IHRvIHRoZSBsaXN0ZW5lcnMsIGZpcnN0IGVtaXQgXCJuZXdMaXN0ZW5lclwiLlxuICBpZiAodGhpcy5fZXZlbnRzLm5ld0xpc3RlbmVyKVxuICAgIHRoaXMuZW1pdCgnbmV3TGlzdGVuZXInLCB0eXBlLFxuICAgICAgICAgICAgICBpc0Z1bmN0aW9uKGxpc3RlbmVyLmxpc3RlbmVyKSA/XG4gICAgICAgICAgICAgIGxpc3RlbmVyLmxpc3RlbmVyIDogbGlzdGVuZXIpO1xuXG4gIGlmICghdGhpcy5fZXZlbnRzW3R5cGVdKVxuICAgIC8vIE9wdGltaXplIHRoZSBjYXNlIG9mIG9uZSBsaXN0ZW5lci4gRG9uJ3QgbmVlZCB0aGUgZXh0cmEgYXJyYXkgb2JqZWN0LlxuICAgIHRoaXMuX2V2ZW50c1t0eXBlXSA9IGxpc3RlbmVyO1xuICBlbHNlIGlmIChpc09iamVjdCh0aGlzLl9ldmVudHNbdHlwZV0pKVxuICAgIC8vIElmIHdlJ3ZlIGFscmVhZHkgZ290IGFuIGFycmF5LCBqdXN0IGFwcGVuZC5cbiAgICB0aGlzLl9ldmVudHNbdHlwZV0ucHVzaChsaXN0ZW5lcik7XG4gIGVsc2VcbiAgICAvLyBBZGRpbmcgdGhlIHNlY29uZCBlbGVtZW50LCBuZWVkIHRvIGNoYW5nZSB0byBhcnJheS5cbiAgICB0aGlzLl9ldmVudHNbdHlwZV0gPSBbdGhpcy5fZXZlbnRzW3R5cGVdLCBsaXN0ZW5lcl07XG5cbiAgLy8gQ2hlY2sgZm9yIGxpc3RlbmVyIGxlYWtcbiAgaWYgKGlzT2JqZWN0KHRoaXMuX2V2ZW50c1t0eXBlXSkgJiYgIXRoaXMuX2V2ZW50c1t0eXBlXS53YXJuZWQpIHtcbiAgICBpZiAoIWlzVW5kZWZpbmVkKHRoaXMuX21heExpc3RlbmVycykpIHtcbiAgICAgIG0gPSB0aGlzLl9tYXhMaXN0ZW5lcnM7XG4gICAgfSBlbHNlIHtcbiAgICAgIG0gPSBFdmVudEVtaXR0ZXIuZGVmYXVsdE1heExpc3RlbmVycztcbiAgICB9XG5cbiAgICBpZiAobSAmJiBtID4gMCAmJiB0aGlzLl9ldmVudHNbdHlwZV0ubGVuZ3RoID4gbSkge1xuICAgICAgdGhpcy5fZXZlbnRzW3R5cGVdLndhcm5lZCA9IHRydWU7XG4gICAgICBjb25zb2xlLmVycm9yKCcobm9kZSkgd2FybmluZzogcG9zc2libGUgRXZlbnRFbWl0dGVyIG1lbW9yeSAnICtcbiAgICAgICAgICAgICAgICAgICAgJ2xlYWsgZGV0ZWN0ZWQuICVkIGxpc3RlbmVycyBhZGRlZC4gJyArXG4gICAgICAgICAgICAgICAgICAgICdVc2UgZW1pdHRlci5zZXRNYXhMaXN0ZW5lcnMoKSB0byBpbmNyZWFzZSBsaW1pdC4nLFxuICAgICAgICAgICAgICAgICAgICB0aGlzLl9ldmVudHNbdHlwZV0ubGVuZ3RoKTtcbiAgICAgIGlmICh0eXBlb2YgY29uc29sZS50cmFjZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAvLyBub3Qgc3VwcG9ydGVkIGluIElFIDEwXG4gICAgICAgIGNvbnNvbGUudHJhY2UoKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gdGhpcztcbn07XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUub24gPSBFdmVudEVtaXR0ZXIucHJvdG90eXBlLmFkZExpc3RlbmVyO1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLm9uY2UgPSBmdW5jdGlvbih0eXBlLCBsaXN0ZW5lcikge1xuICBpZiAoIWlzRnVuY3Rpb24obGlzdGVuZXIpKVxuICAgIHRocm93IFR5cGVFcnJvcignbGlzdGVuZXIgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG5cbiAgdmFyIGZpcmVkID0gZmFsc2U7XG5cbiAgZnVuY3Rpb24gZygpIHtcbiAgICB0aGlzLnJlbW92ZUxpc3RlbmVyKHR5cGUsIGcpO1xuXG4gICAgaWYgKCFmaXJlZCkge1xuICAgICAgZmlyZWQgPSB0cnVlO1xuICAgICAgbGlzdGVuZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICB9XG4gIH1cblxuICBnLmxpc3RlbmVyID0gbGlzdGVuZXI7XG4gIHRoaXMub24odHlwZSwgZyk7XG5cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vLyBlbWl0cyBhICdyZW1vdmVMaXN0ZW5lcicgZXZlbnQgaWZmIHRoZSBsaXN0ZW5lciB3YXMgcmVtb3ZlZFxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5yZW1vdmVMaXN0ZW5lciA9IGZ1bmN0aW9uKHR5cGUsIGxpc3RlbmVyKSB7XG4gIHZhciBsaXN0LCBwb3NpdGlvbiwgbGVuZ3RoLCBpO1xuXG4gIGlmICghaXNGdW5jdGlvbihsaXN0ZW5lcikpXG4gICAgdGhyb3cgVHlwZUVycm9yKCdsaXN0ZW5lciBtdXN0IGJlIGEgZnVuY3Rpb24nKTtcblxuICBpZiAoIXRoaXMuX2V2ZW50cyB8fCAhdGhpcy5fZXZlbnRzW3R5cGVdKVxuICAgIHJldHVybiB0aGlzO1xuXG4gIGxpc3QgPSB0aGlzLl9ldmVudHNbdHlwZV07XG4gIGxlbmd0aCA9IGxpc3QubGVuZ3RoO1xuICBwb3NpdGlvbiA9IC0xO1xuXG4gIGlmIChsaXN0ID09PSBsaXN0ZW5lciB8fFxuICAgICAgKGlzRnVuY3Rpb24obGlzdC5saXN0ZW5lcikgJiYgbGlzdC5saXN0ZW5lciA9PT0gbGlzdGVuZXIpKSB7XG4gICAgZGVsZXRlIHRoaXMuX2V2ZW50c1t0eXBlXTtcbiAgICBpZiAodGhpcy5fZXZlbnRzLnJlbW92ZUxpc3RlbmVyKVxuICAgICAgdGhpcy5lbWl0KCdyZW1vdmVMaXN0ZW5lcicsIHR5cGUsIGxpc3RlbmVyKTtcblxuICB9IGVsc2UgaWYgKGlzT2JqZWN0KGxpc3QpKSB7XG4gICAgZm9yIChpID0gbGVuZ3RoOyBpLS0gPiAwOykge1xuICAgICAgaWYgKGxpc3RbaV0gPT09IGxpc3RlbmVyIHx8XG4gICAgICAgICAgKGxpc3RbaV0ubGlzdGVuZXIgJiYgbGlzdFtpXS5saXN0ZW5lciA9PT0gbGlzdGVuZXIpKSB7XG4gICAgICAgIHBvc2l0aW9uID0gaTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHBvc2l0aW9uIDwgMClcbiAgICAgIHJldHVybiB0aGlzO1xuXG4gICAgaWYgKGxpc3QubGVuZ3RoID09PSAxKSB7XG4gICAgICBsaXN0Lmxlbmd0aCA9IDA7XG4gICAgICBkZWxldGUgdGhpcy5fZXZlbnRzW3R5cGVdO1xuICAgIH0gZWxzZSB7XG4gICAgICBsaXN0LnNwbGljZShwb3NpdGlvbiwgMSk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuX2V2ZW50cy5yZW1vdmVMaXN0ZW5lcilcbiAgICAgIHRoaXMuZW1pdCgncmVtb3ZlTGlzdGVuZXInLCB0eXBlLCBsaXN0ZW5lcik7XG4gIH1cblxuICByZXR1cm4gdGhpcztcbn07XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUucmVtb3ZlQWxsTGlzdGVuZXJzID0gZnVuY3Rpb24odHlwZSkge1xuICB2YXIga2V5LCBsaXN0ZW5lcnM7XG5cbiAgaWYgKCF0aGlzLl9ldmVudHMpXG4gICAgcmV0dXJuIHRoaXM7XG5cbiAgLy8gbm90IGxpc3RlbmluZyBmb3IgcmVtb3ZlTGlzdGVuZXIsIG5vIG5lZWQgdG8gZW1pdFxuICBpZiAoIXRoaXMuX2V2ZW50cy5yZW1vdmVMaXN0ZW5lcikge1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAwKVxuICAgICAgdGhpcy5fZXZlbnRzID0ge307XG4gICAgZWxzZSBpZiAodGhpcy5fZXZlbnRzW3R5cGVdKVxuICAgICAgZGVsZXRlIHRoaXMuX2V2ZW50c1t0eXBlXTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8vIGVtaXQgcmVtb3ZlTGlzdGVuZXIgZm9yIGFsbCBsaXN0ZW5lcnMgb24gYWxsIGV2ZW50c1xuICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMCkge1xuICAgIGZvciAoa2V5IGluIHRoaXMuX2V2ZW50cykge1xuICAgICAgaWYgKGtleSA9PT0gJ3JlbW92ZUxpc3RlbmVyJykgY29udGludWU7XG4gICAgICB0aGlzLnJlbW92ZUFsbExpc3RlbmVycyhrZXkpO1xuICAgIH1cbiAgICB0aGlzLnJlbW92ZUFsbExpc3RlbmVycygncmVtb3ZlTGlzdGVuZXInKTtcbiAgICB0aGlzLl9ldmVudHMgPSB7fTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIGxpc3RlbmVycyA9IHRoaXMuX2V2ZW50c1t0eXBlXTtcblxuICBpZiAoaXNGdW5jdGlvbihsaXN0ZW5lcnMpKSB7XG4gICAgdGhpcy5yZW1vdmVMaXN0ZW5lcih0eXBlLCBsaXN0ZW5lcnMpO1xuICB9IGVsc2UgaWYgKGxpc3RlbmVycykge1xuICAgIC8vIExJRk8gb3JkZXJcbiAgICB3aGlsZSAobGlzdGVuZXJzLmxlbmd0aClcbiAgICAgIHRoaXMucmVtb3ZlTGlzdGVuZXIodHlwZSwgbGlzdGVuZXJzW2xpc3RlbmVycy5sZW5ndGggLSAxXSk7XG4gIH1cbiAgZGVsZXRlIHRoaXMuX2V2ZW50c1t0eXBlXTtcblxuICByZXR1cm4gdGhpcztcbn07XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUubGlzdGVuZXJzID0gZnVuY3Rpb24odHlwZSkge1xuICB2YXIgcmV0O1xuICBpZiAoIXRoaXMuX2V2ZW50cyB8fCAhdGhpcy5fZXZlbnRzW3R5cGVdKVxuICAgIHJldCA9IFtdO1xuICBlbHNlIGlmIChpc0Z1bmN0aW9uKHRoaXMuX2V2ZW50c1t0eXBlXSkpXG4gICAgcmV0ID0gW3RoaXMuX2V2ZW50c1t0eXBlXV07XG4gIGVsc2VcbiAgICByZXQgPSB0aGlzLl9ldmVudHNbdHlwZV0uc2xpY2UoKTtcbiAgcmV0dXJuIHJldDtcbn07XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUubGlzdGVuZXJDb3VudCA9IGZ1bmN0aW9uKHR5cGUpIHtcbiAgaWYgKHRoaXMuX2V2ZW50cykge1xuICAgIHZhciBldmxpc3RlbmVyID0gdGhpcy5fZXZlbnRzW3R5cGVdO1xuXG4gICAgaWYgKGlzRnVuY3Rpb24oZXZsaXN0ZW5lcikpXG4gICAgICByZXR1cm4gMTtcbiAgICBlbHNlIGlmIChldmxpc3RlbmVyKVxuICAgICAgcmV0dXJuIGV2bGlzdGVuZXIubGVuZ3RoO1xuICB9XG4gIHJldHVybiAwO1xufTtcblxuRXZlbnRFbWl0dGVyLmxpc3RlbmVyQ291bnQgPSBmdW5jdGlvbihlbWl0dGVyLCB0eXBlKSB7XG4gIHJldHVybiBlbWl0dGVyLmxpc3RlbmVyQ291bnQodHlwZSk7XG59O1xuXG5mdW5jdGlvbiBpc0Z1bmN0aW9uKGFyZykge1xuICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gJ2Z1bmN0aW9uJztcbn1cblxuZnVuY3Rpb24gaXNOdW1iZXIoYXJnKSB7XG4gIHJldHVybiB0eXBlb2YgYXJnID09PSAnbnVtYmVyJztcbn1cblxuZnVuY3Rpb24gaXNPYmplY3QoYXJnKSB7XG4gIHJldHVybiB0eXBlb2YgYXJnID09PSAnb2JqZWN0JyAmJiBhcmcgIT09IG51bGw7XG59XG5cbmZ1bmN0aW9uIGlzVW5kZWZpbmVkKGFyZykge1xuICByZXR1cm4gYXJnID09PSB2b2lkIDA7XG59XG4iLCIvKiBqc2hpbnQgbm9kZTogdHJ1ZSAqL1xuJ3VzZSBzdHJpY3QnO1xuXG52YXIgbm9ybWFsaWNlID0gcmVxdWlyZSgnbm9ybWFsaWNlJyk7XG5cbi8qKlxuICAjIGZyZWVpY2VcblxuICBUaGUgYGZyZWVpY2VgIG1vZHVsZSBpcyBhIHNpbXBsZSB3YXkgb2YgZ2V0dGluZyByYW5kb20gU1RVTiBvciBUVVJOIHNlcnZlclxuICBmb3IgeW91ciBXZWJSVEMgYXBwbGljYXRpb24uICBUaGUgbGlzdCBvZiBzZXJ2ZXJzIChqdXN0IFNUVU4gYXQgdGhpcyBzdGFnZSlcbiAgd2VyZSBzb3VyY2VkIGZyb20gdGhpcyBbZ2lzdF0oaHR0cHM6Ly9naXN0LmdpdGh1Yi5jb20venppdW5pLzM3NDE5MzMpLlxuXG4gICMjIEV4YW1wbGUgVXNlXG5cbiAgVGhlIGZvbGxvd2luZyBkZW1vbnN0cmF0ZXMgaG93IHlvdSBjYW4gdXNlIGBmcmVlaWNlYCB3aXRoXG4gIFtydGMtcXVpY2tjb25uZWN0XShodHRwczovL2dpdGh1Yi5jb20vcnRjLWlvL3J0Yy1xdWlja2Nvbm5lY3QpOlxuXG4gIDw8PCBleGFtcGxlcy9xdWlja2Nvbm5lY3QuanNcblxuICBBcyB0aGUgYGZyZWVpY2VgIG1vZHVsZSBnZW5lcmF0ZXMgaWNlIHNlcnZlcnMgaW4gYSBsaXN0IGNvbXBsaWFudCB3aXRoIHRoZVxuICBXZWJSVEMgc3BlYyB5b3Ugd2lsbCBiZSBhYmxlIHRvIHVzZSBpdCB3aXRoIHJhdyBgUlRDUGVlckNvbm5lY3Rpb25gXG4gIGNvbnN0cnVjdG9ycyBhbmQgb3RoZXIgV2ViUlRDIGxpYnJhcmllcy5cblxuICAjIyBIZXksIGRvbid0IHVzZSBteSBTVFVOL1RVUk4gc2VydmVyIVxuXG4gIElmIGZvciBzb21lIHJlYXNvbiB5b3VyIGZyZWUgU1RVTiBvciBUVVJOIHNlcnZlciBlbmRzIHVwIGluIHRoZVxuICBsaXN0IG9mIHNlcnZlcnMgKFtzdHVuXShodHRwczovL2dpdGh1Yi5jb20vRGFtb25PZWhsbWFuL2ZyZWVpY2UvYmxvYi9tYXN0ZXIvc3R1bi5qc29uKSBvclxuICBbdHVybl0oaHR0cHM6Ly9naXRodWIuY29tL0RhbW9uT2VobG1hbi9mcmVlaWNlL2Jsb2IvbWFzdGVyL3R1cm4uanNvbikpXG4gIHRoYXQgaXMgdXNlZCBpbiB0aGlzIG1vZHVsZSwgeW91IGNhbiBmZWVsXG4gIGZyZWUgdG8gb3BlbiBhbiBpc3N1ZSBvbiB0aGlzIHJlcG9zaXRvcnkgYW5kIHRob3NlIHNlcnZlcnMgd2lsbCBiZSByZW1vdmVkXG4gIHdpdGhpbiAyNCBob3VycyAob3Igc29vbmVyKS4gIFRoaXMgaXMgdGhlIHF1aWNrZXN0IGFuZCBwcm9iYWJseSB0aGUgbW9zdFxuICBwb2xpdGUgd2F5IHRvIGhhdmUgc29tZXRoaW5nIHJlbW92ZWQgKGFuZCBwcm92aWRlcyB1cyBzb21lIHZpc2liaWxpdHlcbiAgaWYgc29tZW9uZSBvcGVucyBhIHB1bGwgcmVxdWVzdCByZXF1ZXN0aW5nIHRoYXQgYSBzZXJ2ZXIgaXMgYWRkZWQpLlxuXG4gICMjIFBsZWFzZSBhZGQgbXkgc2VydmVyIVxuXG4gIElmIHlvdSBoYXZlIGEgc2VydmVyIHRoYXQgeW91IHdpc2ggdG8gYWRkIHRvIHRoZSBsaXN0LCB0aGF0J3MgYXdlc29tZSEgSSdtXG4gIHN1cmUgSSBzcGVhayBvbiBiZWhhbGYgb2YgYSB3aG9sZSBwaWxlIG9mIFdlYlJUQyBkZXZlbG9wZXJzIHdobyBzYXkgdGhhbmtzLlxuICBUbyBnZXQgaXQgaW50byB0aGUgbGlzdCwgZmVlbCBmcmVlIHRvIGVpdGhlciBvcGVuIGEgcHVsbCByZXF1ZXN0IG9yIGlmIHlvdVxuICBmaW5kIHRoYXQgcHJvY2VzcyBhIGJpdCBkYXVudGluZyB0aGVuIGp1c3QgY3JlYXRlIGFuIGlzc3VlIHJlcXVlc3RpbmdcbiAgdGhlIGFkZGl0aW9uIG9mIHRoZSBzZXJ2ZXIgKG1ha2Ugc3VyZSB5b3UgcHJvdmlkZSBhbGwgdGhlIGRldGFpbHMsIGFuZCBpZlxuICB5b3UgaGF2ZSBhIFRlcm1zIG9mIFNlcnZpY2UgdGhlbiBpbmNsdWRpbmcgdGhhdCBpbiB0aGUgUFIvaXNzdWUgd291bGQgYmVcbiAgYXdlc29tZSkuXG5cbiAgIyMgSSBrbm93IG9mIGEgZnJlZSBzZXJ2ZXIsIGNhbiBJIGFkZCBpdD9cblxuICBTdXJlLCBpZiB5b3UgZG8geW91ciBob21ld29yayBhbmQgbWFrZSBzdXJlIGl0IGlzIG9rIHRvIHVzZSAoSSdtIGN1cnJlbnRseVxuICBpbiB0aGUgcHJvY2VzcyBvZiByZXZpZXdpbmcgdGhlIHRlcm1zIG9mIHRob3NlIFNUVU4gc2VydmVycyBpbmNsdWRlZCBmcm9tXG4gIHRoZSBvcmlnaW5hbCBsaXN0KS4gIElmIGl0J3Mgb2sgdG8gZ28sIHRoZW4gcGxlYXNlIHNlZSB0aGUgcHJldmlvdXMgZW50cnlcbiAgZm9yIGhvdyB0byBhZGQgaXQuXG5cbiAgIyMgQ3VycmVudCBMaXN0IG9mIFNlcnZlcnNcblxuICAqIGN1cnJlbnQgYXMgYXQgdGhlIHRpbWUgb2YgbGFzdCBgUkVBRE1FLm1kYCBmaWxlIGdlbmVyYXRpb25cblxuICAjIyMgU1RVTlxuXG4gIDw8PCBzdHVuLmpzb25cblxuICAjIyMgVFVSTlxuXG4gIDw8PCB0dXJuLmpzb25cblxuKiovXG5cbnZhciBmcmVlaWNlID0gbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihvcHRzKSB7XG4gIC8vIGlmIGEgbGlzdCBvZiBzZXJ2ZXJzIGhhcyBiZWVuIHByb3ZpZGVkLCB0aGVuIHVzZSBpdCBpbnN0ZWFkIG9mIGRlZmF1bHRzXG4gIHZhciBzZXJ2ZXJzID0ge1xuICAgIHN0dW46IChvcHRzIHx8IHt9KS5zdHVuIHx8IHJlcXVpcmUoJy4vc3R1bi5qc29uJyksXG4gICAgdHVybjogKG9wdHMgfHwge30pLnR1cm4gfHwgcmVxdWlyZSgnLi90dXJuLmpzb24nKVxuICB9O1xuXG4gIHZhciBzdHVuQ291bnQgPSAob3B0cyB8fCB7fSkuc3R1bkNvdW50IHx8IDI7XG4gIHZhciB0dXJuQ291bnQgPSAob3B0cyB8fCB7fSkudHVybkNvdW50IHx8IDA7XG4gIHZhciBzZWxlY3RlZDtcblxuICBmdW5jdGlvbiBnZXRTZXJ2ZXJzKHR5cGUsIGNvdW50KSB7XG4gICAgdmFyIG91dCA9IFtdO1xuICAgIHZhciBpbnB1dCA9IFtdLmNvbmNhdChzZXJ2ZXJzW3R5cGVdKTtcbiAgICB2YXIgaWR4O1xuXG4gICAgd2hpbGUgKGlucHV0Lmxlbmd0aCAmJiBvdXQubGVuZ3RoIDwgY291bnQpIHtcbiAgICAgIGlkeCA9IChNYXRoLnJhbmRvbSgpICogaW5wdXQubGVuZ3RoKSB8IDA7XG4gICAgICBvdXQgPSBvdXQuY29uY2F0KGlucHV0LnNwbGljZShpZHgsIDEpKTtcbiAgICB9XG5cbiAgICByZXR1cm4gb3V0Lm1hcChmdW5jdGlvbih1cmwpIHtcbiAgICAgICAgLy9JZiBpdCdzIGEgbm90IGEgc3RyaW5nLCBkb24ndCB0cnkgdG8gXCJub3JtYWxpY2VcIiBpdCBvdGhlcndpc2UgdXNpbmcgdHlwZTp1cmwgd2lsbCBzY3JldyBpdCB1cFxuICAgICAgICBpZiAoKHR5cGVvZiB1cmwgIT09ICdzdHJpbmcnKSAmJiAoISAodXJsIGluc3RhbmNlb2YgU3RyaW5nKSkpIHtcbiAgICAgICAgICAgIHJldHVybiB1cmw7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gbm9ybWFsaWNlKHR5cGUgKyAnOicgKyB1cmwpO1xuICAgICAgICB9XG4gICAgfSk7XG4gIH1cblxuICAvLyBhZGQgc3R1biBzZXJ2ZXJzXG4gIHNlbGVjdGVkID0gW10uY29uY2F0KGdldFNlcnZlcnMoJ3N0dW4nLCBzdHVuQ291bnQpKTtcblxuICBpZiAodHVybkNvdW50KSB7XG4gICAgc2VsZWN0ZWQgPSBzZWxlY3RlZC5jb25jYXQoZ2V0U2VydmVycygndHVybicsIHR1cm5Db3VudCkpO1xuICB9XG5cbiAgcmV0dXJuIHNlbGVjdGVkO1xufTtcbiIsIm1vZHVsZS5leHBvcnRzPVtcbiAgXCJzdHVuLmwuZ29vZ2xlLmNvbToxOTMwMlwiLFxuICBcInN0dW4xLmwuZ29vZ2xlLmNvbToxOTMwMlwiLFxuICBcInN0dW4yLmwuZ29vZ2xlLmNvbToxOTMwMlwiLFxuICBcInN0dW4zLmwuZ29vZ2xlLmNvbToxOTMwMlwiLFxuICBcInN0dW40LmwuZ29vZ2xlLmNvbToxOTMwMlwiLFxuICBcInN0dW4uZWtpZ2EubmV0XCIsXG4gIFwic3R1bi5pZGVhc2lwLmNvbVwiLFxuICBcInN0dW4uc2NobHVuZC5kZVwiLFxuICBcInN0dW4uc3R1bnByb3RvY29sLm9yZzozNDc4XCIsXG4gIFwic3R1bi52b2lwYXJvdW5kLmNvbVwiLFxuICBcInN0dW4udm9pcGJ1c3Rlci5jb21cIixcbiAgXCJzdHVuLnZvaXBzdHVudC5jb21cIixcbiAgXCJzdHVuLnZveGdyYXRpYS5vcmdcIixcbiAgXCJzdHVuLnNlcnZpY2VzLm1vemlsbGEuY29tXCJcbl1cbiIsIm1vZHVsZS5leHBvcnRzPVtdXG4iLCJ2YXIgV2lsZEVtaXR0ZXIgPSByZXF1aXJlKCd3aWxkZW1pdHRlcicpO1xuXG5mdW5jdGlvbiBnZXRNYXhWb2x1bWUgKGFuYWx5c2VyLCBmZnRCaW5zKSB7XG4gIHZhciBtYXhWb2x1bWUgPSAtSW5maW5pdHk7XG4gIGFuYWx5c2VyLmdldEZsb2F0RnJlcXVlbmN5RGF0YShmZnRCaW5zKTtcblxuICBmb3IodmFyIGk9NCwgaWk9ZmZ0Qmlucy5sZW5ndGg7IGkgPCBpaTsgaSsrKSB7XG4gICAgaWYgKGZmdEJpbnNbaV0gPiBtYXhWb2x1bWUgJiYgZmZ0Qmluc1tpXSA8IDApIHtcbiAgICAgIG1heFZvbHVtZSA9IGZmdEJpbnNbaV07XG4gICAgfVxuICB9O1xuXG4gIHJldHVybiBtYXhWb2x1bWU7XG59XG5cblxudmFyIGF1ZGlvQ29udGV4dFR5cGUgPSB3aW5kb3cuQXVkaW9Db250ZXh0IHx8IHdpbmRvdy53ZWJraXRBdWRpb0NvbnRleHQ7XG4vLyB1c2UgYSBzaW5nbGUgYXVkaW8gY29udGV4dCBkdWUgdG8gaGFyZHdhcmUgbGltaXRzXG52YXIgYXVkaW9Db250ZXh0ID0gbnVsbDtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oc3RyZWFtLCBvcHRpb25zKSB7XG4gIHZhciBoYXJrZXIgPSBuZXcgV2lsZEVtaXR0ZXIoKTtcblxuXG4gIC8vIG1ha2UgaXQgbm90IGJyZWFrIGluIG5vbi1zdXBwb3J0ZWQgYnJvd3NlcnNcbiAgaWYgKCFhdWRpb0NvbnRleHRUeXBlKSByZXR1cm4gaGFya2VyO1xuXG4gIC8vQ29uZmlnXG4gIHZhciBvcHRpb25zID0gb3B0aW9ucyB8fCB7fSxcbiAgICAgIHNtb290aGluZyA9IChvcHRpb25zLnNtb290aGluZyB8fCAwLjEpLFxuICAgICAgaW50ZXJ2YWwgPSAob3B0aW9ucy5pbnRlcnZhbCB8fCA1MCksXG4gICAgICB0aHJlc2hvbGQgPSBvcHRpb25zLnRocmVzaG9sZCxcbiAgICAgIHBsYXkgPSBvcHRpb25zLnBsYXksXG4gICAgICBoaXN0b3J5ID0gb3B0aW9ucy5oaXN0b3J5IHx8IDEwLFxuICAgICAgcnVubmluZyA9IHRydWU7XG5cbiAgLy9TZXR1cCBBdWRpbyBDb250ZXh0XG4gIGlmICghYXVkaW9Db250ZXh0KSB7XG4gICAgYXVkaW9Db250ZXh0ID0gbmV3IGF1ZGlvQ29udGV4dFR5cGUoKTtcbiAgfVxuICB2YXIgc291cmNlTm9kZSwgZmZ0QmlucywgYW5hbHlzZXI7XG5cbiAgYW5hbHlzZXIgPSBhdWRpb0NvbnRleHQuY3JlYXRlQW5hbHlzZXIoKTtcbiAgYW5hbHlzZXIuZmZ0U2l6ZSA9IDUxMjtcbiAgYW5hbHlzZXIuc21vb3RoaW5nVGltZUNvbnN0YW50ID0gc21vb3RoaW5nO1xuICBmZnRCaW5zID0gbmV3IEZsb2F0MzJBcnJheShhbmFseXNlci5mZnRTaXplKTtcblxuICBpZiAoc3RyZWFtLmpxdWVyeSkgc3RyZWFtID0gc3RyZWFtWzBdO1xuICBpZiAoc3RyZWFtIGluc3RhbmNlb2YgSFRNTEF1ZGlvRWxlbWVudCB8fCBzdHJlYW0gaW5zdGFuY2VvZiBIVE1MVmlkZW9FbGVtZW50KSB7XG4gICAgLy9BdWRpbyBUYWdcbiAgICBzb3VyY2VOb2RlID0gYXVkaW9Db250ZXh0LmNyZWF0ZU1lZGlhRWxlbWVudFNvdXJjZShzdHJlYW0pO1xuICAgIGlmICh0eXBlb2YgcGxheSA9PT0gJ3VuZGVmaW5lZCcpIHBsYXkgPSB0cnVlO1xuICAgIHRocmVzaG9sZCA9IHRocmVzaG9sZCB8fCAtNTA7XG4gIH0gZWxzZSB7XG4gICAgLy9XZWJSVEMgU3RyZWFtXG4gICAgc291cmNlTm9kZSA9IGF1ZGlvQ29udGV4dC5jcmVhdGVNZWRpYVN0cmVhbVNvdXJjZShzdHJlYW0pO1xuICAgIHRocmVzaG9sZCA9IHRocmVzaG9sZCB8fCAtNTA7XG4gIH1cblxuICBzb3VyY2VOb2RlLmNvbm5lY3QoYW5hbHlzZXIpO1xuICBpZiAocGxheSkgYW5hbHlzZXIuY29ubmVjdChhdWRpb0NvbnRleHQuZGVzdGluYXRpb24pO1xuXG4gIGhhcmtlci5zcGVha2luZyA9IGZhbHNlO1xuXG4gIGhhcmtlci5zZXRUaHJlc2hvbGQgPSBmdW5jdGlvbih0KSB7XG4gICAgdGhyZXNob2xkID0gdDtcbiAgfTtcblxuICBoYXJrZXIuc2V0SW50ZXJ2YWwgPSBmdW5jdGlvbihpKSB7XG4gICAgaW50ZXJ2YWwgPSBpO1xuICB9O1xuICBcbiAgaGFya2VyLnN0b3AgPSBmdW5jdGlvbigpIHtcbiAgICBydW5uaW5nID0gZmFsc2U7XG4gICAgaGFya2VyLmVtaXQoJ3ZvbHVtZV9jaGFuZ2UnLCAtMTAwLCB0aHJlc2hvbGQpO1xuICAgIGlmIChoYXJrZXIuc3BlYWtpbmcpIHtcbiAgICAgIGhhcmtlci5zcGVha2luZyA9IGZhbHNlO1xuICAgICAgaGFya2VyLmVtaXQoJ3N0b3BwZWRfc3BlYWtpbmcnKTtcbiAgICB9XG4gIH07XG4gIGhhcmtlci5zcGVha2luZ0hpc3RvcnkgPSBbXTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBoaXN0b3J5OyBpKyspIHtcbiAgICAgIGhhcmtlci5zcGVha2luZ0hpc3RvcnkucHVzaCgwKTtcbiAgfVxuXG4gIC8vIFBvbGwgdGhlIGFuYWx5c2VyIG5vZGUgdG8gZGV0ZXJtaW5lIGlmIHNwZWFraW5nXG4gIC8vIGFuZCBlbWl0IGV2ZW50cyBpZiBjaGFuZ2VkXG4gIHZhciBsb29wZXIgPSBmdW5jdGlvbigpIHtcbiAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkge1xuICAgIFxuICAgICAgLy9jaGVjayBpZiBzdG9wIGhhcyBiZWVuIGNhbGxlZFxuICAgICAgaWYoIXJ1bm5pbmcpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgXG4gICAgICB2YXIgY3VycmVudFZvbHVtZSA9IGdldE1heFZvbHVtZShhbmFseXNlciwgZmZ0Qmlucyk7XG5cbiAgICAgIGhhcmtlci5lbWl0KCd2b2x1bWVfY2hhbmdlJywgY3VycmVudFZvbHVtZSwgdGhyZXNob2xkKTtcblxuICAgICAgdmFyIGhpc3RvcnkgPSAwO1xuICAgICAgaWYgKGN1cnJlbnRWb2x1bWUgPiB0aHJlc2hvbGQgJiYgIWhhcmtlci5zcGVha2luZykge1xuICAgICAgICAvLyB0cmlnZ2VyIHF1aWNrbHksIHNob3J0IGhpc3RvcnlcbiAgICAgICAgZm9yICh2YXIgaSA9IGhhcmtlci5zcGVha2luZ0hpc3RvcnkubGVuZ3RoIC0gMzsgaSA8IGhhcmtlci5zcGVha2luZ0hpc3RvcnkubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICBoaXN0b3J5ICs9IGhhcmtlci5zcGVha2luZ0hpc3RvcnlbaV07XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGhpc3RvcnkgPj0gMikge1xuICAgICAgICAgIGhhcmtlci5zcGVha2luZyA9IHRydWU7XG4gICAgICAgICAgaGFya2VyLmVtaXQoJ3NwZWFraW5nJyk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAoY3VycmVudFZvbHVtZSA8IHRocmVzaG9sZCAmJiBoYXJrZXIuc3BlYWtpbmcpIHtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBoYXJrZXIuc3BlYWtpbmdIaXN0b3J5Lmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgaGlzdG9yeSArPSBoYXJrZXIuc3BlYWtpbmdIaXN0b3J5W2ldO1xuICAgICAgICB9XG4gICAgICAgIGlmIChoaXN0b3J5ID09IDApIHtcbiAgICAgICAgICBoYXJrZXIuc3BlYWtpbmcgPSBmYWxzZTtcbiAgICAgICAgICBoYXJrZXIuZW1pdCgnc3RvcHBlZF9zcGVha2luZycpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBoYXJrZXIuc3BlYWtpbmdIaXN0b3J5LnNoaWZ0KCk7XG4gICAgICBoYXJrZXIuc3BlYWtpbmdIaXN0b3J5LnB1c2goMCArIChjdXJyZW50Vm9sdW1lID4gdGhyZXNob2xkKSk7XG5cbiAgICAgIGxvb3BlcigpO1xuICAgIH0sIGludGVydmFsKTtcbiAgfTtcbiAgbG9vcGVyKCk7XG5cblxuICByZXR1cm4gaGFya2VyO1xufVxuIiwiaWYgKHR5cGVvZiBPYmplY3QuY3JlYXRlID09PSAnZnVuY3Rpb24nKSB7XG4gIC8vIGltcGxlbWVudGF0aW9uIGZyb20gc3RhbmRhcmQgbm9kZS5qcyAndXRpbCcgbW9kdWxlXG4gIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaW5oZXJpdHMoY3Rvciwgc3VwZXJDdG9yKSB7XG4gICAgY3Rvci5zdXBlcl8gPSBzdXBlckN0b3JcbiAgICBjdG9yLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoc3VwZXJDdG9yLnByb3RvdHlwZSwge1xuICAgICAgY29uc3RydWN0b3I6IHtcbiAgICAgICAgdmFsdWU6IGN0b3IsXG4gICAgICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgICAgICB3cml0YWJsZTogdHJ1ZSxcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlXG4gICAgICB9XG4gICAgfSk7XG4gIH07XG59IGVsc2Uge1xuICAvLyBvbGQgc2Nob29sIHNoaW0gZm9yIG9sZCBicm93c2Vyc1xuICBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGluaGVyaXRzKGN0b3IsIHN1cGVyQ3Rvcikge1xuICAgIGN0b3Iuc3VwZXJfID0gc3VwZXJDdG9yXG4gICAgdmFyIFRlbXBDdG9yID0gZnVuY3Rpb24gKCkge31cbiAgICBUZW1wQ3Rvci5wcm90b3R5cGUgPSBzdXBlckN0b3IucHJvdG90eXBlXG4gICAgY3Rvci5wcm90b3R5cGUgPSBuZXcgVGVtcEN0b3IoKVxuICAgIGN0b3IucHJvdG90eXBlLmNvbnN0cnVjdG9yID0gY3RvclxuICB9XG59XG4iLCIvKiFcclxuICogQG5hbWUgSmF2YVNjcmlwdC9Ob2RlSlMgTWVyZ2UgdjEuMi4wXHJcbiAqIEBhdXRob3IgeWVpa29zXHJcbiAqIEByZXBvc2l0b3J5IGh0dHBzOi8vZ2l0aHViLmNvbS95ZWlrb3MvanMubWVyZ2VcclxuXHJcbiAqIENvcHlyaWdodCAyMDE0IHllaWtvcyAtIE1JVCBsaWNlbnNlXHJcbiAqIGh0dHBzOi8vcmF3LmdpdGh1Yi5jb20veWVpa29zL2pzLm1lcmdlL21hc3Rlci9MSUNFTlNFXHJcbiAqL1xyXG5cclxuOyhmdW5jdGlvbihpc05vZGUpIHtcclxuXHJcblx0LyoqXHJcblx0ICogTWVyZ2Ugb25lIG9yIG1vcmUgb2JqZWN0cyBcclxuXHQgKiBAcGFyYW0gYm9vbD8gY2xvbmVcclxuXHQgKiBAcGFyYW0gbWl4ZWQsLi4uIGFyZ3VtZW50c1xyXG5cdCAqIEByZXR1cm4gb2JqZWN0XHJcblx0ICovXHJcblxyXG5cdHZhciBQdWJsaWMgPSBmdW5jdGlvbihjbG9uZSkge1xyXG5cclxuXHRcdHJldHVybiBtZXJnZShjbG9uZSA9PT0gdHJ1ZSwgZmFsc2UsIGFyZ3VtZW50cyk7XHJcblxyXG5cdH0sIHB1YmxpY05hbWUgPSAnbWVyZ2UnO1xyXG5cclxuXHQvKipcclxuXHQgKiBNZXJnZSB0d28gb3IgbW9yZSBvYmplY3RzIHJlY3Vyc2l2ZWx5IFxyXG5cdCAqIEBwYXJhbSBib29sPyBjbG9uZVxyXG5cdCAqIEBwYXJhbSBtaXhlZCwuLi4gYXJndW1lbnRzXHJcblx0ICogQHJldHVybiBvYmplY3RcclxuXHQgKi9cclxuXHJcblx0UHVibGljLnJlY3Vyc2l2ZSA9IGZ1bmN0aW9uKGNsb25lKSB7XHJcblxyXG5cdFx0cmV0dXJuIG1lcmdlKGNsb25lID09PSB0cnVlLCB0cnVlLCBhcmd1bWVudHMpO1xyXG5cclxuXHR9O1xyXG5cclxuXHQvKipcclxuXHQgKiBDbG9uZSB0aGUgaW5wdXQgcmVtb3ZpbmcgYW55IHJlZmVyZW5jZVxyXG5cdCAqIEBwYXJhbSBtaXhlZCBpbnB1dFxyXG5cdCAqIEByZXR1cm4gbWl4ZWRcclxuXHQgKi9cclxuXHJcblx0UHVibGljLmNsb25lID0gZnVuY3Rpb24oaW5wdXQpIHtcclxuXHJcblx0XHR2YXIgb3V0cHV0ID0gaW5wdXQsXHJcblx0XHRcdHR5cGUgPSB0eXBlT2YoaW5wdXQpLFxyXG5cdFx0XHRpbmRleCwgc2l6ZTtcclxuXHJcblx0XHRpZiAodHlwZSA9PT0gJ2FycmF5Jykge1xyXG5cclxuXHRcdFx0b3V0cHV0ID0gW107XHJcblx0XHRcdHNpemUgPSBpbnB1dC5sZW5ndGg7XHJcblxyXG5cdFx0XHRmb3IgKGluZGV4PTA7aW5kZXg8c2l6ZTsrK2luZGV4KVxyXG5cclxuXHRcdFx0XHRvdXRwdXRbaW5kZXhdID0gUHVibGljLmNsb25lKGlucHV0W2luZGV4XSk7XHJcblxyXG5cdFx0fSBlbHNlIGlmICh0eXBlID09PSAnb2JqZWN0Jykge1xyXG5cclxuXHRcdFx0b3V0cHV0ID0ge307XHJcblxyXG5cdFx0XHRmb3IgKGluZGV4IGluIGlucHV0KVxyXG5cclxuXHRcdFx0XHRvdXRwdXRbaW5kZXhdID0gUHVibGljLmNsb25lKGlucHV0W2luZGV4XSk7XHJcblxyXG5cdFx0fVxyXG5cclxuXHRcdHJldHVybiBvdXRwdXQ7XHJcblxyXG5cdH07XHJcblxyXG5cdC8qKlxyXG5cdCAqIE1lcmdlIHR3byBvYmplY3RzIHJlY3Vyc2l2ZWx5XHJcblx0ICogQHBhcmFtIG1peGVkIGlucHV0XHJcblx0ICogQHBhcmFtIG1peGVkIGV4dGVuZFxyXG5cdCAqIEByZXR1cm4gbWl4ZWRcclxuXHQgKi9cclxuXHJcblx0ZnVuY3Rpb24gbWVyZ2VfcmVjdXJzaXZlKGJhc2UsIGV4dGVuZCkge1xyXG5cclxuXHRcdGlmICh0eXBlT2YoYmFzZSkgIT09ICdvYmplY3QnKVxyXG5cclxuXHRcdFx0cmV0dXJuIGV4dGVuZDtcclxuXHJcblx0XHRmb3IgKHZhciBrZXkgaW4gZXh0ZW5kKSB7XHJcblxyXG5cdFx0XHRpZiAodHlwZU9mKGJhc2Vba2V5XSkgPT09ICdvYmplY3QnICYmIHR5cGVPZihleHRlbmRba2V5XSkgPT09ICdvYmplY3QnKSB7XHJcblxyXG5cdFx0XHRcdGJhc2Vba2V5XSA9IG1lcmdlX3JlY3Vyc2l2ZShiYXNlW2tleV0sIGV4dGVuZFtrZXldKTtcclxuXHJcblx0XHRcdH0gZWxzZSB7XHJcblxyXG5cdFx0XHRcdGJhc2Vba2V5XSA9IGV4dGVuZFtrZXldO1xyXG5cclxuXHRcdFx0fVxyXG5cclxuXHRcdH1cclxuXHJcblx0XHRyZXR1cm4gYmFzZTtcclxuXHJcblx0fVxyXG5cclxuXHQvKipcclxuXHQgKiBNZXJnZSB0d28gb3IgbW9yZSBvYmplY3RzXHJcblx0ICogQHBhcmFtIGJvb2wgY2xvbmVcclxuXHQgKiBAcGFyYW0gYm9vbCByZWN1cnNpdmVcclxuXHQgKiBAcGFyYW0gYXJyYXkgYXJndlxyXG5cdCAqIEByZXR1cm4gb2JqZWN0XHJcblx0ICovXHJcblxyXG5cdGZ1bmN0aW9uIG1lcmdlKGNsb25lLCByZWN1cnNpdmUsIGFyZ3YpIHtcclxuXHJcblx0XHR2YXIgcmVzdWx0ID0gYXJndlswXSxcclxuXHRcdFx0c2l6ZSA9IGFyZ3YubGVuZ3RoO1xyXG5cclxuXHRcdGlmIChjbG9uZSB8fCB0eXBlT2YocmVzdWx0KSAhPT0gJ29iamVjdCcpXHJcblxyXG5cdFx0XHRyZXN1bHQgPSB7fTtcclxuXHJcblx0XHRmb3IgKHZhciBpbmRleD0wO2luZGV4PHNpemU7KytpbmRleCkge1xyXG5cclxuXHRcdFx0dmFyIGl0ZW0gPSBhcmd2W2luZGV4XSxcclxuXHJcblx0XHRcdFx0dHlwZSA9IHR5cGVPZihpdGVtKTtcclxuXHJcblx0XHRcdGlmICh0eXBlICE9PSAnb2JqZWN0JykgY29udGludWU7XHJcblxyXG5cdFx0XHRmb3IgKHZhciBrZXkgaW4gaXRlbSkge1xyXG5cclxuXHRcdFx0XHR2YXIgc2l0ZW0gPSBjbG9uZSA/IFB1YmxpYy5jbG9uZShpdGVtW2tleV0pIDogaXRlbVtrZXldO1xyXG5cclxuXHRcdFx0XHRpZiAocmVjdXJzaXZlKSB7XHJcblxyXG5cdFx0XHRcdFx0cmVzdWx0W2tleV0gPSBtZXJnZV9yZWN1cnNpdmUocmVzdWx0W2tleV0sIHNpdGVtKTtcclxuXHJcblx0XHRcdFx0fSBlbHNlIHtcclxuXHJcblx0XHRcdFx0XHRyZXN1bHRba2V5XSA9IHNpdGVtO1xyXG5cclxuXHRcdFx0XHR9XHJcblxyXG5cdFx0XHR9XHJcblxyXG5cdFx0fVxyXG5cclxuXHRcdHJldHVybiByZXN1bHQ7XHJcblxyXG5cdH1cclxuXHJcblx0LyoqXHJcblx0ICogR2V0IHR5cGUgb2YgdmFyaWFibGVcclxuXHQgKiBAcGFyYW0gbWl4ZWQgaW5wdXRcclxuXHQgKiBAcmV0dXJuIHN0cmluZ1xyXG5cdCAqXHJcblx0ICogQHNlZSBodHRwOi8vanNwZXJmLmNvbS90eXBlb2Z2YXJcclxuXHQgKi9cclxuXHJcblx0ZnVuY3Rpb24gdHlwZU9mKGlucHV0KSB7XHJcblxyXG5cdFx0cmV0dXJuICh7fSkudG9TdHJpbmcuY2FsbChpbnB1dCkuc2xpY2UoOCwgLTEpLnRvTG93ZXJDYXNlKCk7XHJcblxyXG5cdH1cclxuXHJcblx0aWYgKGlzTm9kZSkge1xyXG5cclxuXHRcdG1vZHVsZS5leHBvcnRzID0gUHVibGljO1xyXG5cclxuXHR9IGVsc2Uge1xyXG5cclxuXHRcdHdpbmRvd1twdWJsaWNOYW1lXSA9IFB1YmxpYztcclxuXHJcblx0fVxyXG5cclxufSkodHlwZW9mIG1vZHVsZSA9PT0gJ29iamVjdCcgJiYgbW9kdWxlICYmIHR5cGVvZiBtb2R1bGUuZXhwb3J0cyA9PT0gJ29iamVjdCcgJiYgbW9kdWxlLmV4cG9ydHMpOyIsIi8qKlxuICAjIG5vcm1hbGljZVxuXG4gIE5vcm1hbGl6ZSBhbiBpY2Ugc2VydmVyIGNvbmZpZ3VyYXRpb24gb2JqZWN0IChvciBwbGFpbiBvbGQgc3RyaW5nKSBpbnRvIGEgZm9ybWF0XG4gIHRoYXQgaXMgdXNhYmxlIGluIGFsbCBicm93c2VycyBzdXBwb3J0aW5nIFdlYlJUQy4gIFByaW1hcmlseSB0aGlzIG1vZHVsZSBpcyBkZXNpZ25lZFxuICB0byBoZWxwIHdpdGggdGhlIHRyYW5zaXRpb24gb2YgdGhlIGB1cmxgIGF0dHJpYnV0ZSBvZiB0aGUgY29uZmlndXJhdGlvbiBvYmplY3QgdG9cbiAgdGhlIGB1cmxzYCBhdHRyaWJ1dGUuXG5cbiAgIyMgRXhhbXBsZSBVc2FnZVxuXG4gIDw8PCBleGFtcGxlcy9zaW1wbGUuanNcblxuKiovXG5cbnZhciBwcm90b2NvbHMgPSBbXG4gICdzdHVuOicsXG4gICd0dXJuOidcbl07XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oaW5wdXQpIHtcbiAgdmFyIHVybCA9IChpbnB1dCB8fCB7fSkudXJsIHx8IGlucHV0O1xuICB2YXIgcHJvdG9jb2w7XG4gIHZhciBwYXJ0cztcbiAgdmFyIG91dHB1dCA9IHt9O1xuXG4gIC8vIGlmIHdlIGRvbid0IGhhdmUgYSBzdHJpbmcgdXJsLCB0aGVuIGFsbG93IHRoZSBpbnB1dCB0byBwYXNzdGhyb3VnaFxuICBpZiAodHlwZW9mIHVybCAhPSAnc3RyaW5nJyAmJiAoISAodXJsIGluc3RhbmNlb2YgU3RyaW5nKSkpIHtcbiAgICByZXR1cm4gaW5wdXQ7XG4gIH1cblxuICAvLyB0cmltIHRoZSB1cmwgc3RyaW5nLCBhbmQgY29udmVydCB0byBhbiBhcnJheVxuICB1cmwgPSB1cmwudHJpbSgpO1xuXG4gIC8vIGlmIHRoZSBwcm90b2NvbCBpcyBub3Qga25vd24sIHRoZW4gcGFzc3Rocm91Z2hcbiAgcHJvdG9jb2wgPSBwcm90b2NvbHNbcHJvdG9jb2xzLmluZGV4T2YodXJsLnNsaWNlKDAsIDUpKV07XG4gIGlmICghIHByb3RvY29sKSB7XG4gICAgcmV0dXJuIGlucHV0O1xuICB9XG5cbiAgLy8gbm93IGxldCdzIGF0dGFjayB0aGUgcmVtYWluaW5nIHVybCBwYXJ0c1xuICB1cmwgPSB1cmwuc2xpY2UoNSk7XG4gIHBhcnRzID0gdXJsLnNwbGl0KCdAJyk7XG5cbiAgb3V0cHV0LnVzZXJuYW1lID0gaW5wdXQudXNlcm5hbWU7XG4gIG91dHB1dC5jcmVkZW50aWFsID0gaW5wdXQuY3JlZGVudGlhbDtcbiAgLy8gaWYgd2UgaGF2ZSBhbiBhdXRoZW50aWNhdGlvbiBwYXJ0LCB0aGVuIHNldCB0aGUgY3JlZGVudGlhbHNcbiAgaWYgKHBhcnRzLmxlbmd0aCA+IDEpIHtcbiAgICB1cmwgPSBwYXJ0c1sxXTtcbiAgICBwYXJ0cyA9IHBhcnRzWzBdLnNwbGl0KCc6Jyk7XG5cbiAgICAvLyBhZGQgdGhlIG91dHB1dCBjcmVkZW50aWFsIGFuZCB1c2VybmFtZVxuICAgIG91dHB1dC51c2VybmFtZSA9IHBhcnRzWzBdO1xuICAgIG91dHB1dC5jcmVkZW50aWFsID0gKGlucHV0IHx8IHt9KS5jcmVkZW50aWFsIHx8IHBhcnRzWzFdIHx8ICcnO1xuICB9XG5cbiAgb3V0cHV0LnVybCA9IHByb3RvY29sICsgdXJsO1xuICBvdXRwdXQudXJscyA9IFsgb3V0cHV0LnVybCBdO1xuXG4gIHJldHVybiBvdXRwdXQ7XG59O1xuIiwiLypcbiAqICBDb3B5cmlnaHQgKGMpIDIwMTcgVGhlIFdlYlJUQyBwcm9qZWN0IGF1dGhvcnMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKlxuICogIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2VcbiAqICB0aGF0IGNhbiBiZSBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlIGluIHRoZSByb290IG9mIHRoZSBzb3VyY2VcbiAqICB0cmVlLlxuICovXG4gLyogZXNsaW50LWVudiBub2RlICovXG4ndXNlIHN0cmljdCc7XG5cbnZhciBTRFBVdGlscyA9IHJlcXVpcmUoJ3NkcCcpO1xuXG5mdW5jdGlvbiB3cml0ZU1lZGlhU2VjdGlvbih0cmFuc2NlaXZlciwgY2FwcywgdHlwZSwgc3RyZWFtLCBkdGxzUm9sZSkge1xuICB2YXIgc2RwID0gU0RQVXRpbHMud3JpdGVSdHBEZXNjcmlwdGlvbih0cmFuc2NlaXZlci5raW5kLCBjYXBzKTtcblxuICAvLyBNYXAgSUNFIHBhcmFtZXRlcnMgKHVmcmFnLCBwd2QpIHRvIFNEUC5cbiAgc2RwICs9IFNEUFV0aWxzLndyaXRlSWNlUGFyYW1ldGVycyhcbiAgICAgIHRyYW5zY2VpdmVyLmljZUdhdGhlcmVyLmdldExvY2FsUGFyYW1ldGVycygpKTtcblxuICAvLyBNYXAgRFRMUyBwYXJhbWV0ZXJzIHRvIFNEUC5cbiAgc2RwICs9IFNEUFV0aWxzLndyaXRlRHRsc1BhcmFtZXRlcnMoXG4gICAgICB0cmFuc2NlaXZlci5kdGxzVHJhbnNwb3J0LmdldExvY2FsUGFyYW1ldGVycygpLFxuICAgICAgdHlwZSA9PT0gJ29mZmVyJyA/ICdhY3RwYXNzJyA6IGR0bHNSb2xlIHx8ICdhY3RpdmUnKTtcblxuICBzZHAgKz0gJ2E9bWlkOicgKyB0cmFuc2NlaXZlci5taWQgKyAnXFxyXFxuJztcblxuICBpZiAodHJhbnNjZWl2ZXIuZGlyZWN0aW9uKSB7XG4gICAgc2RwICs9ICdhPScgKyB0cmFuc2NlaXZlci5kaXJlY3Rpb24gKyAnXFxyXFxuJztcbiAgfSBlbHNlIGlmICh0cmFuc2NlaXZlci5ydHBTZW5kZXIgJiYgdHJhbnNjZWl2ZXIucnRwUmVjZWl2ZXIpIHtcbiAgICBzZHAgKz0gJ2E9c2VuZHJlY3ZcXHJcXG4nO1xuICB9IGVsc2UgaWYgKHRyYW5zY2VpdmVyLnJ0cFNlbmRlcikge1xuICAgIHNkcCArPSAnYT1zZW5kb25seVxcclxcbic7XG4gIH0gZWxzZSBpZiAodHJhbnNjZWl2ZXIucnRwUmVjZWl2ZXIpIHtcbiAgICBzZHAgKz0gJ2E9cmVjdm9ubHlcXHJcXG4nO1xuICB9IGVsc2Uge1xuICAgIHNkcCArPSAnYT1pbmFjdGl2ZVxcclxcbic7XG4gIH1cblxuICBpZiAodHJhbnNjZWl2ZXIucnRwU2VuZGVyKSB7XG4gICAgLy8gc3BlYy5cbiAgICB2YXIgbXNpZCA9ICdtc2lkOicgKyBzdHJlYW0uaWQgKyAnICcgK1xuICAgICAgICB0cmFuc2NlaXZlci5ydHBTZW5kZXIudHJhY2suaWQgKyAnXFxyXFxuJztcbiAgICBzZHAgKz0gJ2E9JyArIG1zaWQ7XG5cbiAgICAvLyBmb3IgQ2hyb21lLlxuICAgIHNkcCArPSAnYT1zc3JjOicgKyB0cmFuc2NlaXZlci5zZW5kRW5jb2RpbmdQYXJhbWV0ZXJzWzBdLnNzcmMgK1xuICAgICAgICAnICcgKyBtc2lkO1xuICAgIGlmICh0cmFuc2NlaXZlci5zZW5kRW5jb2RpbmdQYXJhbWV0ZXJzWzBdLnJ0eCkge1xuICAgICAgc2RwICs9ICdhPXNzcmM6JyArIHRyYW5zY2VpdmVyLnNlbmRFbmNvZGluZ1BhcmFtZXRlcnNbMF0ucnR4LnNzcmMgK1xuICAgICAgICAgICcgJyArIG1zaWQ7XG4gICAgICBzZHAgKz0gJ2E9c3NyYy1ncm91cDpGSUQgJyArXG4gICAgICAgICAgdHJhbnNjZWl2ZXIuc2VuZEVuY29kaW5nUGFyYW1ldGVyc1swXS5zc3JjICsgJyAnICtcbiAgICAgICAgICB0cmFuc2NlaXZlci5zZW5kRW5jb2RpbmdQYXJhbWV0ZXJzWzBdLnJ0eC5zc3JjICtcbiAgICAgICAgICAnXFxyXFxuJztcbiAgICB9XG4gIH1cbiAgLy8gRklYTUU6IHRoaXMgc2hvdWxkIGJlIHdyaXR0ZW4gYnkgd3JpdGVSdHBEZXNjcmlwdGlvbi5cbiAgc2RwICs9ICdhPXNzcmM6JyArIHRyYW5zY2VpdmVyLnNlbmRFbmNvZGluZ1BhcmFtZXRlcnNbMF0uc3NyYyArXG4gICAgICAnIGNuYW1lOicgKyBTRFBVdGlscy5sb2NhbENOYW1lICsgJ1xcclxcbic7XG4gIGlmICh0cmFuc2NlaXZlci5ydHBTZW5kZXIgJiYgdHJhbnNjZWl2ZXIuc2VuZEVuY29kaW5nUGFyYW1ldGVyc1swXS5ydHgpIHtcbiAgICBzZHAgKz0gJ2E9c3NyYzonICsgdHJhbnNjZWl2ZXIuc2VuZEVuY29kaW5nUGFyYW1ldGVyc1swXS5ydHguc3NyYyArXG4gICAgICAgICcgY25hbWU6JyArIFNEUFV0aWxzLmxvY2FsQ05hbWUgKyAnXFxyXFxuJztcbiAgfVxuICByZXR1cm4gc2RwO1xufVxuXG4vLyBFZGdlIGRvZXMgbm90IGxpa2Vcbi8vIDEpIHN0dW46IGZpbHRlcmVkIGFmdGVyIDE0MzkzIHVubGVzcyA/dHJhbnNwb3J0PXVkcCBpcyBwcmVzZW50XG4vLyAyKSB0dXJuOiB0aGF0IGRvZXMgbm90IGhhdmUgYWxsIG9mIHR1cm46aG9zdDpwb3J0P3RyYW5zcG9ydD11ZHBcbi8vIDMpIHR1cm46IHdpdGggaXB2NiBhZGRyZXNzZXNcbi8vIDQpIHR1cm46IG9jY3VycmluZyBtdWxpcGxlIHRpbWVzXG5mdW5jdGlvbiBmaWx0ZXJJY2VTZXJ2ZXJzKGljZVNlcnZlcnMsIGVkZ2VWZXJzaW9uKSB7XG4gIHZhciBoYXNUdXJuID0gZmFsc2U7XG4gIGljZVNlcnZlcnMgPSBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KGljZVNlcnZlcnMpKTtcbiAgcmV0dXJuIGljZVNlcnZlcnMuZmlsdGVyKGZ1bmN0aW9uKHNlcnZlcikge1xuICAgIGlmIChzZXJ2ZXIgJiYgKHNlcnZlci51cmxzIHx8IHNlcnZlci51cmwpKSB7XG4gICAgICB2YXIgdXJscyA9IHNlcnZlci51cmxzIHx8IHNlcnZlci51cmw7XG4gICAgICBpZiAoc2VydmVyLnVybCAmJiAhc2VydmVyLnVybHMpIHtcbiAgICAgICAgY29uc29sZS53YXJuKCdSVENJY2VTZXJ2ZXIudXJsIGlzIGRlcHJlY2F0ZWQhIFVzZSB1cmxzIGluc3RlYWQuJyk7XG4gICAgICB9XG4gICAgICB2YXIgaXNTdHJpbmcgPSB0eXBlb2YgdXJscyA9PT0gJ3N0cmluZyc7XG4gICAgICBpZiAoaXNTdHJpbmcpIHtcbiAgICAgICAgdXJscyA9IFt1cmxzXTtcbiAgICAgIH1cbiAgICAgIHVybHMgPSB1cmxzLmZpbHRlcihmdW5jdGlvbih1cmwpIHtcbiAgICAgICAgdmFyIHZhbGlkVHVybiA9IHVybC5pbmRleE9mKCd0dXJuOicpID09PSAwICYmXG4gICAgICAgICAgICB1cmwuaW5kZXhPZigndHJhbnNwb3J0PXVkcCcpICE9PSAtMSAmJlxuICAgICAgICAgICAgdXJsLmluZGV4T2YoJ3R1cm46WycpID09PSAtMSAmJlxuICAgICAgICAgICAgIWhhc1R1cm47XG5cbiAgICAgICAgaWYgKHZhbGlkVHVybikge1xuICAgICAgICAgIGhhc1R1cm4gPSB0cnVlO1xuICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB1cmwuaW5kZXhPZignc3R1bjonKSA9PT0gMCAmJiBlZGdlVmVyc2lvbiA+PSAxNDM5MyAmJlxuICAgICAgICAgICAgdXJsLmluZGV4T2YoJz90cmFuc3BvcnQ9dWRwJykgPT09IC0xO1xuICAgICAgfSk7XG5cbiAgICAgIGRlbGV0ZSBzZXJ2ZXIudXJsO1xuICAgICAgc2VydmVyLnVybHMgPSBpc1N0cmluZyA/IHVybHNbMF0gOiB1cmxzO1xuICAgICAgcmV0dXJuICEhdXJscy5sZW5ndGg7XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbiAgfSk7XG59XG5cbi8vIERldGVybWluZXMgdGhlIGludGVyc2VjdGlvbiBvZiBsb2NhbCBhbmQgcmVtb3RlIGNhcGFiaWxpdGllcy5cbmZ1bmN0aW9uIGdldENvbW1vbkNhcGFiaWxpdGllcyhsb2NhbENhcGFiaWxpdGllcywgcmVtb3RlQ2FwYWJpbGl0aWVzKSB7XG4gIHZhciBjb21tb25DYXBhYmlsaXRpZXMgPSB7XG4gICAgY29kZWNzOiBbXSxcbiAgICBoZWFkZXJFeHRlbnNpb25zOiBbXSxcbiAgICBmZWNNZWNoYW5pc21zOiBbXVxuICB9O1xuXG4gIHZhciBmaW5kQ29kZWNCeVBheWxvYWRUeXBlID0gZnVuY3Rpb24ocHQsIGNvZGVjcykge1xuICAgIHB0ID0gcGFyc2VJbnQocHQsIDEwKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGNvZGVjcy5sZW5ndGg7IGkrKykge1xuICAgICAgaWYgKGNvZGVjc1tpXS5wYXlsb2FkVHlwZSA9PT0gcHQgfHxcbiAgICAgICAgICBjb2RlY3NbaV0ucHJlZmVycmVkUGF5bG9hZFR5cGUgPT09IHB0KSB7XG4gICAgICAgIHJldHVybiBjb2RlY3NbaV07XG4gICAgICB9XG4gICAgfVxuICB9O1xuXG4gIHZhciBydHhDYXBhYmlsaXR5TWF0Y2hlcyA9IGZ1bmN0aW9uKGxSdHgsIHJSdHgsIGxDb2RlY3MsIHJDb2RlY3MpIHtcbiAgICB2YXIgbENvZGVjID0gZmluZENvZGVjQnlQYXlsb2FkVHlwZShsUnR4LnBhcmFtZXRlcnMuYXB0LCBsQ29kZWNzKTtcbiAgICB2YXIgckNvZGVjID0gZmluZENvZGVjQnlQYXlsb2FkVHlwZShyUnR4LnBhcmFtZXRlcnMuYXB0LCByQ29kZWNzKTtcbiAgICByZXR1cm4gbENvZGVjICYmIHJDb2RlYyAmJlxuICAgICAgICBsQ29kZWMubmFtZS50b0xvd2VyQ2FzZSgpID09PSByQ29kZWMubmFtZS50b0xvd2VyQ2FzZSgpO1xuICB9O1xuXG4gIGxvY2FsQ2FwYWJpbGl0aWVzLmNvZGVjcy5mb3JFYWNoKGZ1bmN0aW9uKGxDb2RlYykge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcmVtb3RlQ2FwYWJpbGl0aWVzLmNvZGVjcy5sZW5ndGg7IGkrKykge1xuICAgICAgdmFyIHJDb2RlYyA9IHJlbW90ZUNhcGFiaWxpdGllcy5jb2RlY3NbaV07XG4gICAgICBpZiAobENvZGVjLm5hbWUudG9Mb3dlckNhc2UoKSA9PT0gckNvZGVjLm5hbWUudG9Mb3dlckNhc2UoKSAmJlxuICAgICAgICAgIGxDb2RlYy5jbG9ja1JhdGUgPT09IHJDb2RlYy5jbG9ja1JhdGUpIHtcbiAgICAgICAgaWYgKGxDb2RlYy5uYW1lLnRvTG93ZXJDYXNlKCkgPT09ICdydHgnICYmXG4gICAgICAgICAgICBsQ29kZWMucGFyYW1ldGVycyAmJiByQ29kZWMucGFyYW1ldGVycy5hcHQpIHtcbiAgICAgICAgICAvLyBmb3IgUlRYIHdlIG5lZWQgdG8gZmluZCB0aGUgbG9jYWwgcnR4IHRoYXQgaGFzIGEgYXB0XG4gICAgICAgICAgLy8gd2hpY2ggcG9pbnRzIHRvIHRoZSBzYW1lIGxvY2FsIGNvZGVjIGFzIHRoZSByZW1vdGUgb25lLlxuICAgICAgICAgIGlmICghcnR4Q2FwYWJpbGl0eU1hdGNoZXMobENvZGVjLCByQ29kZWMsXG4gICAgICAgICAgICAgIGxvY2FsQ2FwYWJpbGl0aWVzLmNvZGVjcywgcmVtb3RlQ2FwYWJpbGl0aWVzLmNvZGVjcykpIHtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByQ29kZWMgPSBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KHJDb2RlYykpOyAvLyBkZWVwY29weVxuICAgICAgICAvLyBudW1iZXIgb2YgY2hhbm5lbHMgaXMgdGhlIGhpZ2hlc3QgY29tbW9uIG51bWJlciBvZiBjaGFubmVsc1xuICAgICAgICByQ29kZWMubnVtQ2hhbm5lbHMgPSBNYXRoLm1pbihsQ29kZWMubnVtQ2hhbm5lbHMsXG4gICAgICAgICAgICByQ29kZWMubnVtQ2hhbm5lbHMpO1xuICAgICAgICAvLyBwdXNoIHJDb2RlYyBzbyB3ZSByZXBseSB3aXRoIG9mZmVyZXIgcGF5bG9hZCB0eXBlXG4gICAgICAgIGNvbW1vbkNhcGFiaWxpdGllcy5jb2RlY3MucHVzaChyQ29kZWMpO1xuXG4gICAgICAgIC8vIGRldGVybWluZSBjb21tb24gZmVlZGJhY2sgbWVjaGFuaXNtc1xuICAgICAgICByQ29kZWMucnRjcEZlZWRiYWNrID0gckNvZGVjLnJ0Y3BGZWVkYmFjay5maWx0ZXIoZnVuY3Rpb24oZmIpIHtcbiAgICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IGxDb2RlYy5ydGNwRmVlZGJhY2subGVuZ3RoOyBqKyspIHtcbiAgICAgICAgICAgIGlmIChsQ29kZWMucnRjcEZlZWRiYWNrW2pdLnR5cGUgPT09IGZiLnR5cGUgJiZcbiAgICAgICAgICAgICAgICBsQ29kZWMucnRjcEZlZWRiYWNrW2pdLnBhcmFtZXRlciA9PT0gZmIucGFyYW1ldGVyKSB7XG4gICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH0pO1xuICAgICAgICAvLyBGSVhNRTogYWxzbyBuZWVkIHRvIGRldGVybWluZSAucGFyYW1ldGVyc1xuICAgICAgICAvLyAgc2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9vcGVucGVlci9vcnRjL2lzc3Vlcy81NjlcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuICB9KTtcblxuICBsb2NhbENhcGFiaWxpdGllcy5oZWFkZXJFeHRlbnNpb25zLmZvckVhY2goZnVuY3Rpb24obEhlYWRlckV4dGVuc2lvbikge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcmVtb3RlQ2FwYWJpbGl0aWVzLmhlYWRlckV4dGVuc2lvbnMubGVuZ3RoO1xuICAgICAgICAgaSsrKSB7XG4gICAgICB2YXIgckhlYWRlckV4dGVuc2lvbiA9IHJlbW90ZUNhcGFiaWxpdGllcy5oZWFkZXJFeHRlbnNpb25zW2ldO1xuICAgICAgaWYgKGxIZWFkZXJFeHRlbnNpb24udXJpID09PSBySGVhZGVyRXh0ZW5zaW9uLnVyaSkge1xuICAgICAgICBjb21tb25DYXBhYmlsaXRpZXMuaGVhZGVyRXh0ZW5zaW9ucy5wdXNoKHJIZWFkZXJFeHRlbnNpb24pO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG4gIH0pO1xuXG4gIC8vIEZJWE1FOiBmZWNNZWNoYW5pc21zXG4gIHJldHVybiBjb21tb25DYXBhYmlsaXRpZXM7XG59XG5cbi8vIGlzIGFjdGlvbj1zZXRMb2NhbERlc2NyaXB0aW9uIHdpdGggdHlwZSBhbGxvd2VkIGluIHNpZ25hbGluZ1N0YXRlXG5mdW5jdGlvbiBpc0FjdGlvbkFsbG93ZWRJblNpZ25hbGluZ1N0YXRlKGFjdGlvbiwgdHlwZSwgc2lnbmFsaW5nU3RhdGUpIHtcbiAgcmV0dXJuIHtcbiAgICBvZmZlcjoge1xuICAgICAgc2V0TG9jYWxEZXNjcmlwdGlvbjogWydzdGFibGUnLCAnaGF2ZS1sb2NhbC1vZmZlciddLFxuICAgICAgc2V0UmVtb3RlRGVzY3JpcHRpb246IFsnc3RhYmxlJywgJ2hhdmUtcmVtb3RlLW9mZmVyJ11cbiAgICB9LFxuICAgIGFuc3dlcjoge1xuICAgICAgc2V0TG9jYWxEZXNjcmlwdGlvbjogWydoYXZlLXJlbW90ZS1vZmZlcicsICdoYXZlLWxvY2FsLXByYW5zd2VyJ10sXG4gICAgICBzZXRSZW1vdGVEZXNjcmlwdGlvbjogWydoYXZlLWxvY2FsLW9mZmVyJywgJ2hhdmUtcmVtb3RlLXByYW5zd2VyJ11cbiAgICB9XG4gIH1bdHlwZV1bYWN0aW9uXS5pbmRleE9mKHNpZ25hbGluZ1N0YXRlKSAhPT0gLTE7XG59XG5cbmZ1bmN0aW9uIG1heWJlQWRkQ2FuZGlkYXRlKGljZVRyYW5zcG9ydCwgY2FuZGlkYXRlKSB7XG4gIC8vIEVkZ2UncyBpbnRlcm5hbCByZXByZXNlbnRhdGlvbiBhZGRzIHNvbWUgZmllbGRzIHRoZXJlZm9yZVxuICAvLyBub3QgYWxsIGZpZWxk0ZUgYXJlIHRha2VuIGludG8gYWNjb3VudC5cbiAgdmFyIGFscmVhZHlBZGRlZCA9IGljZVRyYW5zcG9ydC5nZXRSZW1vdGVDYW5kaWRhdGVzKClcbiAgICAgIC5maW5kKGZ1bmN0aW9uKHJlbW90ZUNhbmRpZGF0ZSkge1xuICAgICAgICByZXR1cm4gY2FuZGlkYXRlLmZvdW5kYXRpb24gPT09IHJlbW90ZUNhbmRpZGF0ZS5mb3VuZGF0aW9uICYmXG4gICAgICAgICAgICBjYW5kaWRhdGUuaXAgPT09IHJlbW90ZUNhbmRpZGF0ZS5pcCAmJlxuICAgICAgICAgICAgY2FuZGlkYXRlLnBvcnQgPT09IHJlbW90ZUNhbmRpZGF0ZS5wb3J0ICYmXG4gICAgICAgICAgICBjYW5kaWRhdGUucHJpb3JpdHkgPT09IHJlbW90ZUNhbmRpZGF0ZS5wcmlvcml0eSAmJlxuICAgICAgICAgICAgY2FuZGlkYXRlLnByb3RvY29sID09PSByZW1vdGVDYW5kaWRhdGUucHJvdG9jb2wgJiZcbiAgICAgICAgICAgIGNhbmRpZGF0ZS50eXBlID09PSByZW1vdGVDYW5kaWRhdGUudHlwZTtcbiAgICAgIH0pO1xuICBpZiAoIWFscmVhZHlBZGRlZCkge1xuICAgIGljZVRyYW5zcG9ydC5hZGRSZW1vdGVDYW5kaWRhdGUoY2FuZGlkYXRlKTtcbiAgfVxuICByZXR1cm4gIWFscmVhZHlBZGRlZDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbih3aW5kb3csIGVkZ2VWZXJzaW9uKSB7XG4gIHZhciBSVENQZWVyQ29ubmVjdGlvbiA9IGZ1bmN0aW9uKGNvbmZpZykge1xuICAgIHZhciBzZWxmID0gdGhpcztcblxuICAgIHZhciBfZXZlbnRUYXJnZXQgPSBkb2N1bWVudC5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCk7XG4gICAgWydhZGRFdmVudExpc3RlbmVyJywgJ3JlbW92ZUV2ZW50TGlzdGVuZXInLCAnZGlzcGF0Y2hFdmVudCddXG4gICAgICAgIC5mb3JFYWNoKGZ1bmN0aW9uKG1ldGhvZCkge1xuICAgICAgICAgIHNlbGZbbWV0aG9kXSA9IF9ldmVudFRhcmdldFttZXRob2RdLmJpbmQoX2V2ZW50VGFyZ2V0KTtcbiAgICAgICAgfSk7XG5cbiAgICB0aGlzLm9uaWNlY2FuZGlkYXRlID0gbnVsbDtcbiAgICB0aGlzLm9uYWRkc3RyZWFtID0gbnVsbDtcbiAgICB0aGlzLm9udHJhY2sgPSBudWxsO1xuICAgIHRoaXMub25yZW1vdmVzdHJlYW0gPSBudWxsO1xuICAgIHRoaXMub25zaWduYWxpbmdzdGF0ZWNoYW5nZSA9IG51bGw7XG4gICAgdGhpcy5vbmljZWNvbm5lY3Rpb25zdGF0ZWNoYW5nZSA9IG51bGw7XG4gICAgdGhpcy5vbmljZWdhdGhlcmluZ3N0YXRlY2hhbmdlID0gbnVsbDtcbiAgICB0aGlzLm9ubmVnb3RpYXRpb25uZWVkZWQgPSBudWxsO1xuICAgIHRoaXMub25kYXRhY2hhbm5lbCA9IG51bGw7XG4gICAgdGhpcy5jYW5Ucmlja2xlSWNlQ2FuZGlkYXRlcyA9IG51bGw7XG5cbiAgICB0aGlzLm5lZWROZWdvdGlhdGlvbiA9IGZhbHNlO1xuXG4gICAgdGhpcy5sb2NhbFN0cmVhbXMgPSBbXTtcbiAgICB0aGlzLnJlbW90ZVN0cmVhbXMgPSBbXTtcblxuICAgIHRoaXMubG9jYWxEZXNjcmlwdGlvbiA9IG51bGw7XG4gICAgdGhpcy5yZW1vdGVEZXNjcmlwdGlvbiA9IG51bGw7XG5cbiAgICB0aGlzLnNpZ25hbGluZ1N0YXRlID0gJ3N0YWJsZSc7XG4gICAgdGhpcy5pY2VDb25uZWN0aW9uU3RhdGUgPSAnbmV3JztcbiAgICB0aGlzLmljZUdhdGhlcmluZ1N0YXRlID0gJ25ldyc7XG5cbiAgICBjb25maWcgPSBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KGNvbmZpZyB8fCB7fSkpO1xuXG4gICAgdGhpcy51c2luZ0J1bmRsZSA9IGNvbmZpZy5idW5kbGVQb2xpY3kgPT09ICdtYXgtYnVuZGxlJztcbiAgICBpZiAoY29uZmlnLnJ0Y3BNdXhQb2xpY3kgPT09ICduZWdvdGlhdGUnKSB7XG4gICAgICB2YXIgZSA9IG5ldyBFcnJvcigncnRjcE11eFBvbGljeSBcXCduZWdvdGlhdGVcXCcgaXMgbm90IHN1cHBvcnRlZCcpO1xuICAgICAgZS5uYW1lID0gJ05vdFN1cHBvcnRlZEVycm9yJztcbiAgICAgIHRocm93KGUpO1xuICAgIH0gZWxzZSBpZiAoIWNvbmZpZy5ydGNwTXV4UG9saWN5KSB7XG4gICAgICBjb25maWcucnRjcE11eFBvbGljeSA9ICdyZXF1aXJlJztcbiAgICB9XG5cbiAgICBzd2l0Y2ggKGNvbmZpZy5pY2VUcmFuc3BvcnRQb2xpY3kpIHtcbiAgICAgIGNhc2UgJ2FsbCc6XG4gICAgICBjYXNlICdyZWxheSc6XG4gICAgICAgIGJyZWFrO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgY29uZmlnLmljZVRyYW5zcG9ydFBvbGljeSA9ICdhbGwnO1xuICAgICAgICBicmVhaztcbiAgICB9XG5cbiAgICBzd2l0Y2ggKGNvbmZpZy5idW5kbGVQb2xpY3kpIHtcbiAgICAgIGNhc2UgJ2JhbGFuY2VkJzpcbiAgICAgIGNhc2UgJ21heC1jb21wYXQnOlxuICAgICAgY2FzZSAnbWF4LWJ1bmRsZSc6XG4gICAgICAgIGJyZWFrO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgY29uZmlnLmJ1bmRsZVBvbGljeSA9ICdiYWxhbmNlZCc7XG4gICAgICAgIGJyZWFrO1xuICAgIH1cblxuICAgIGNvbmZpZy5pY2VTZXJ2ZXJzID0gZmlsdGVySWNlU2VydmVycyhjb25maWcuaWNlU2VydmVycyB8fCBbXSwgZWRnZVZlcnNpb24pO1xuXG4gICAgdGhpcy5faWNlR2F0aGVyZXJzID0gW107XG4gICAgaWYgKGNvbmZpZy5pY2VDYW5kaWRhdGVQb29sU2l6ZSkge1xuICAgICAgZm9yICh2YXIgaSA9IGNvbmZpZy5pY2VDYW5kaWRhdGVQb29sU2l6ZTsgaSA+IDA7IGktLSkge1xuICAgICAgICB0aGlzLl9pY2VHYXRoZXJlcnMgPSBuZXcgd2luZG93LlJUQ0ljZUdhdGhlcmVyKHtcbiAgICAgICAgICBpY2VTZXJ2ZXJzOiBjb25maWcuaWNlU2VydmVycyxcbiAgICAgICAgICBnYXRoZXJQb2xpY3k6IGNvbmZpZy5pY2VUcmFuc3BvcnRQb2xpY3lcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbmZpZy5pY2VDYW5kaWRhdGVQb29sU2l6ZSA9IDA7XG4gICAgfVxuXG4gICAgdGhpcy5fY29uZmlnID0gY29uZmlnO1xuXG4gICAgLy8gcGVyLXRyYWNrIGljZUdhdGhlcnMsIGljZVRyYW5zcG9ydHMsIGR0bHNUcmFuc3BvcnRzLCBydHBTZW5kZXJzLCAuLi5cbiAgICAvLyBldmVyeXRoaW5nIHRoYXQgaXMgbmVlZGVkIHRvIGRlc2NyaWJlIGEgU0RQIG0tbGluZS5cbiAgICB0aGlzLnRyYW5zY2VpdmVycyA9IFtdO1xuXG4gICAgdGhpcy5fc2RwU2Vzc2lvbklkID0gU0RQVXRpbHMuZ2VuZXJhdGVTZXNzaW9uSWQoKTtcbiAgICB0aGlzLl9zZHBTZXNzaW9uVmVyc2lvbiA9IDA7XG5cbiAgICB0aGlzLl9kdGxzUm9sZSA9IHVuZGVmaW5lZDsgLy8gcm9sZSBmb3IgYT1zZXR1cCB0byB1c2UgaW4gYW5zd2Vycy5cbiAgfTtcblxuICBSVENQZWVyQ29ubmVjdGlvbi5wcm90b3R5cGUuX2VtaXRHYXRoZXJpbmdTdGF0ZUNoYW5nZSA9IGZ1bmN0aW9uKCkge1xuICAgIHZhciBldmVudCA9IG5ldyBFdmVudCgnaWNlZ2F0aGVyaW5nc3RhdGVjaGFuZ2UnKTtcbiAgICB0aGlzLmRpc3BhdGNoRXZlbnQoZXZlbnQpO1xuICAgIGlmICh0eXBlb2YgdGhpcy5vbmljZWdhdGhlcmluZ3N0YXRlY2hhbmdlID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICB0aGlzLm9uaWNlZ2F0aGVyaW5nc3RhdGVjaGFuZ2UoZXZlbnQpO1xuICAgIH1cbiAgfTtcblxuICBSVENQZWVyQ29ubmVjdGlvbi5wcm90b3R5cGUuZ2V0Q29uZmlndXJhdGlvbiA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLl9jb25maWc7XG4gIH07XG5cbiAgUlRDUGVlckNvbm5lY3Rpb24ucHJvdG90eXBlLmdldExvY2FsU3RyZWFtcyA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLmxvY2FsU3RyZWFtcztcbiAgfTtcblxuICBSVENQZWVyQ29ubmVjdGlvbi5wcm90b3R5cGUuZ2V0UmVtb3RlU3RyZWFtcyA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLnJlbW90ZVN0cmVhbXM7XG4gIH07XG5cbiAgLy8gaW50ZXJuYWwgaGVscGVyIHRvIGNyZWF0ZSBhIHRyYW5zY2VpdmVyIG9iamVjdC5cbiAgLy8gKHdoaWggaXMgbm90IHlldCB0aGUgc2FtZSBhcyB0aGUgV2ViUlRDIDEuMCB0cmFuc2NlaXZlcilcbiAgUlRDUGVlckNvbm5lY3Rpb24ucHJvdG90eXBlLl9jcmVhdGVUcmFuc2NlaXZlciA9IGZ1bmN0aW9uKGtpbmQpIHtcbiAgICB2YXIgaGFzQnVuZGxlVHJhbnNwb3J0ID0gdGhpcy50cmFuc2NlaXZlcnMubGVuZ3RoID4gMDtcbiAgICB2YXIgdHJhbnNjZWl2ZXIgPSB7XG4gICAgICB0cmFjazogbnVsbCxcbiAgICAgIGljZUdhdGhlcmVyOiBudWxsLFxuICAgICAgaWNlVHJhbnNwb3J0OiBudWxsLFxuICAgICAgZHRsc1RyYW5zcG9ydDogbnVsbCxcbiAgICAgIGxvY2FsQ2FwYWJpbGl0aWVzOiBudWxsLFxuICAgICAgcmVtb3RlQ2FwYWJpbGl0aWVzOiBudWxsLFxuICAgICAgcnRwU2VuZGVyOiBudWxsLFxuICAgICAgcnRwUmVjZWl2ZXI6IG51bGwsXG4gICAgICBraW5kOiBraW5kLFxuICAgICAgbWlkOiBudWxsLFxuICAgICAgc2VuZEVuY29kaW5nUGFyYW1ldGVyczogbnVsbCxcbiAgICAgIHJlY3ZFbmNvZGluZ1BhcmFtZXRlcnM6IG51bGwsXG4gICAgICBzdHJlYW06IG51bGwsXG4gICAgICB3YW50UmVjZWl2ZTogdHJ1ZVxuICAgIH07XG4gICAgaWYgKHRoaXMudXNpbmdCdW5kbGUgJiYgaGFzQnVuZGxlVHJhbnNwb3J0KSB7XG4gICAgICB0cmFuc2NlaXZlci5pY2VUcmFuc3BvcnQgPSB0aGlzLnRyYW5zY2VpdmVyc1swXS5pY2VUcmFuc3BvcnQ7XG4gICAgICB0cmFuc2NlaXZlci5kdGxzVHJhbnNwb3J0ID0gdGhpcy50cmFuc2NlaXZlcnNbMF0uZHRsc1RyYW5zcG9ydDtcbiAgICB9IGVsc2Uge1xuICAgICAgdmFyIHRyYW5zcG9ydHMgPSB0aGlzLl9jcmVhdGVJY2VBbmREdGxzVHJhbnNwb3J0cygpO1xuICAgICAgdHJhbnNjZWl2ZXIuaWNlVHJhbnNwb3J0ID0gdHJhbnNwb3J0cy5pY2VUcmFuc3BvcnQ7XG4gICAgICB0cmFuc2NlaXZlci5kdGxzVHJhbnNwb3J0ID0gdHJhbnNwb3J0cy5kdGxzVHJhbnNwb3J0O1xuICAgIH1cbiAgICB0aGlzLnRyYW5zY2VpdmVycy5wdXNoKHRyYW5zY2VpdmVyKTtcbiAgICByZXR1cm4gdHJhbnNjZWl2ZXI7XG4gIH07XG5cbiAgUlRDUGVlckNvbm5lY3Rpb24ucHJvdG90eXBlLmFkZFRyYWNrID0gZnVuY3Rpb24odHJhY2ssIHN0cmVhbSkge1xuICAgIHZhciB0cmFuc2NlaXZlcjtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMudHJhbnNjZWl2ZXJzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBpZiAoIXRoaXMudHJhbnNjZWl2ZXJzW2ldLnRyYWNrICYmXG4gICAgICAgICAgdGhpcy50cmFuc2NlaXZlcnNbaV0ua2luZCA9PT0gdHJhY2sua2luZCkge1xuICAgICAgICB0cmFuc2NlaXZlciA9IHRoaXMudHJhbnNjZWl2ZXJzW2ldO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAoIXRyYW5zY2VpdmVyKSB7XG4gICAgICB0cmFuc2NlaXZlciA9IHRoaXMuX2NyZWF0ZVRyYW5zY2VpdmVyKHRyYWNrLmtpbmQpO1xuICAgIH1cblxuICAgIHRoaXMuX21heWJlRmlyZU5lZ290aWF0aW9uTmVlZGVkKCk7XG5cbiAgICBpZiAodGhpcy5sb2NhbFN0cmVhbXMuaW5kZXhPZihzdHJlYW0pID09PSAtMSkge1xuICAgICAgdGhpcy5sb2NhbFN0cmVhbXMucHVzaChzdHJlYW0pO1xuICAgIH1cblxuICAgIHRyYW5zY2VpdmVyLnRyYWNrID0gdHJhY2s7XG4gICAgdHJhbnNjZWl2ZXIuc3RyZWFtID0gc3RyZWFtO1xuICAgIHRyYW5zY2VpdmVyLnJ0cFNlbmRlciA9IG5ldyB3aW5kb3cuUlRDUnRwU2VuZGVyKHRyYWNrLFxuICAgICAgICB0cmFuc2NlaXZlci5kdGxzVHJhbnNwb3J0KTtcbiAgICByZXR1cm4gdHJhbnNjZWl2ZXIucnRwU2VuZGVyO1xuICB9O1xuXG4gIFJUQ1BlZXJDb25uZWN0aW9uLnByb3RvdHlwZS5hZGRTdHJlYW0gPSBmdW5jdGlvbihzdHJlYW0pIHtcbiAgICB2YXIgc2VsZiA9IHRoaXM7XG4gICAgaWYgKGVkZ2VWZXJzaW9uID49IDE1MDI1KSB7XG4gICAgICBzdHJlYW0uZ2V0VHJhY2tzKCkuZm9yRWFjaChmdW5jdGlvbih0cmFjaykge1xuICAgICAgICBzZWxmLmFkZFRyYWNrKHRyYWNrLCBzdHJlYW0pO1xuICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIENsb25lIGlzIG5lY2Vzc2FyeSBmb3IgbG9jYWwgZGVtb3MgbW9zdGx5LCBhdHRhY2hpbmcgZGlyZWN0bHlcbiAgICAgIC8vIHRvIHR3byBkaWZmZXJlbnQgc2VuZGVycyBkb2VzIG5vdCB3b3JrIChidWlsZCAxMDU0NykuXG4gICAgICAvLyBGaXhlZCBpbiAxNTAyNSAob3IgZWFybGllcilcbiAgICAgIHZhciBjbG9uZWRTdHJlYW0gPSBzdHJlYW0uY2xvbmUoKTtcbiAgICAgIHN0cmVhbS5nZXRUcmFja3MoKS5mb3JFYWNoKGZ1bmN0aW9uKHRyYWNrLCBpZHgpIHtcbiAgICAgICAgdmFyIGNsb25lZFRyYWNrID0gY2xvbmVkU3RyZWFtLmdldFRyYWNrcygpW2lkeF07XG4gICAgICAgIHRyYWNrLmFkZEV2ZW50TGlzdGVuZXIoJ2VuYWJsZWQnLCBmdW5jdGlvbihldmVudCkge1xuICAgICAgICAgIGNsb25lZFRyYWNrLmVuYWJsZWQgPSBldmVudC5lbmFibGVkO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgICAgY2xvbmVkU3RyZWFtLmdldFRyYWNrcygpLmZvckVhY2goZnVuY3Rpb24odHJhY2spIHtcbiAgICAgICAgc2VsZi5hZGRUcmFjayh0cmFjaywgY2xvbmVkU3RyZWFtKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfTtcblxuICBSVENQZWVyQ29ubmVjdGlvbi5wcm90b3R5cGUucmVtb3ZlU3RyZWFtID0gZnVuY3Rpb24oc3RyZWFtKSB7XG4gICAgdmFyIGlkeCA9IHRoaXMubG9jYWxTdHJlYW1zLmluZGV4T2Yoc3RyZWFtKTtcbiAgICBpZiAoaWR4ID4gLTEpIHtcbiAgICAgIHRoaXMubG9jYWxTdHJlYW1zLnNwbGljZShpZHgsIDEpO1xuICAgICAgdGhpcy5fbWF5YmVGaXJlTmVnb3RpYXRpb25OZWVkZWQoKTtcbiAgICB9XG4gIH07XG5cbiAgUlRDUGVlckNvbm5lY3Rpb24ucHJvdG90eXBlLmdldFNlbmRlcnMgPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gdGhpcy50cmFuc2NlaXZlcnMuZmlsdGVyKGZ1bmN0aW9uKHRyYW5zY2VpdmVyKSB7XG4gICAgICByZXR1cm4gISF0cmFuc2NlaXZlci5ydHBTZW5kZXI7XG4gICAgfSlcbiAgICAubWFwKGZ1bmN0aW9uKHRyYW5zY2VpdmVyKSB7XG4gICAgICByZXR1cm4gdHJhbnNjZWl2ZXIucnRwU2VuZGVyO1xuICAgIH0pO1xuICB9O1xuXG4gIFJUQ1BlZXJDb25uZWN0aW9uLnByb3RvdHlwZS5nZXRSZWNlaXZlcnMgPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gdGhpcy50cmFuc2NlaXZlcnMuZmlsdGVyKGZ1bmN0aW9uKHRyYW5zY2VpdmVyKSB7XG4gICAgICByZXR1cm4gISF0cmFuc2NlaXZlci5ydHBSZWNlaXZlcjtcbiAgICB9KVxuICAgIC5tYXAoZnVuY3Rpb24odHJhbnNjZWl2ZXIpIHtcbiAgICAgIHJldHVybiB0cmFuc2NlaXZlci5ydHBSZWNlaXZlcjtcbiAgICB9KTtcbiAgfTtcblxuXG4gIFJUQ1BlZXJDb25uZWN0aW9uLnByb3RvdHlwZS5fY3JlYXRlSWNlR2F0aGVyZXIgPSBmdW5jdGlvbihzZHBNTGluZUluZGV4LFxuICAgICAgdXNpbmdCdW5kbGUpIHtcbiAgICB2YXIgc2VsZiA9IHRoaXM7XG4gICAgaWYgKHVzaW5nQnVuZGxlICYmIHNkcE1MaW5lSW5kZXggPiAwKSB7XG4gICAgICByZXR1cm4gdGhpcy50cmFuc2NlaXZlcnNbMF0uaWNlR2F0aGVyZXI7XG4gICAgfSBlbHNlIGlmICh0aGlzLl9pY2VHYXRoZXJlcnMubGVuZ3RoKSB7XG4gICAgICByZXR1cm4gdGhpcy5faWNlR2F0aGVyZXJzLnNoaWZ0KCk7XG4gICAgfVxuICAgIHZhciBpY2VHYXRoZXJlciA9IG5ldyB3aW5kb3cuUlRDSWNlR2F0aGVyZXIoe1xuICAgICAgaWNlU2VydmVyczogdGhpcy5fY29uZmlnLmljZVNlcnZlcnMsXG4gICAgICBnYXRoZXJQb2xpY3k6IHRoaXMuX2NvbmZpZy5pY2VUcmFuc3BvcnRQb2xpY3lcbiAgICB9KTtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoaWNlR2F0aGVyZXIsICdzdGF0ZScsXG4gICAgICAgIHt2YWx1ZTogJ25ldycsIHdyaXRhYmxlOiB0cnVlfVxuICAgICk7XG5cbiAgICB0aGlzLnRyYW5zY2VpdmVyc1tzZHBNTGluZUluZGV4XS5jYW5kaWRhdGVzID0gW107XG4gICAgdGhpcy50cmFuc2NlaXZlcnNbc2RwTUxpbmVJbmRleF0uYnVmZmVyQ2FuZGlkYXRlcyA9IGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgICB2YXIgZW5kID0gIWV2ZW50LmNhbmRpZGF0ZSB8fCBPYmplY3Qua2V5cyhldmVudC5jYW5kaWRhdGUpLmxlbmd0aCA9PT0gMDtcbiAgICAgIC8vIHBvbHlmaWxsIHNpbmNlIFJUQ0ljZUdhdGhlcmVyLnN0YXRlIGlzIG5vdCBpbXBsZW1lbnRlZCBpblxuICAgICAgLy8gRWRnZSAxMDU0NyB5ZXQuXG4gICAgICBpY2VHYXRoZXJlci5zdGF0ZSA9IGVuZCA/ICdjb21wbGV0ZWQnIDogJ2dhdGhlcmluZyc7XG4gICAgICBpZiAoc2VsZi50cmFuc2NlaXZlcnNbc2RwTUxpbmVJbmRleF0uY2FuZGlkYXRlcyAhPT0gbnVsbCkge1xuICAgICAgICBzZWxmLnRyYW5zY2VpdmVyc1tzZHBNTGluZUluZGV4XS5jYW5kaWRhdGVzLnB1c2goZXZlbnQuY2FuZGlkYXRlKTtcbiAgICAgIH1cbiAgICB9O1xuICAgIGljZUdhdGhlcmVyLmFkZEV2ZW50TGlzdGVuZXIoJ2xvY2FsY2FuZGlkYXRlJyxcbiAgICAgIHRoaXMudHJhbnNjZWl2ZXJzW3NkcE1MaW5lSW5kZXhdLmJ1ZmZlckNhbmRpZGF0ZXMpO1xuICAgIHJldHVybiBpY2VHYXRoZXJlcjtcbiAgfTtcblxuICAvLyBzdGFydCBnYXRoZXJpbmcgZnJvbSBhbiBSVENJY2VHYXRoZXJlci5cbiAgUlRDUGVlckNvbm5lY3Rpb24ucHJvdG90eXBlLl9nYXRoZXIgPSBmdW5jdGlvbihtaWQsIHNkcE1MaW5lSW5kZXgpIHtcbiAgICB2YXIgc2VsZiA9IHRoaXM7XG4gICAgdmFyIGljZUdhdGhlcmVyID0gdGhpcy50cmFuc2NlaXZlcnNbc2RwTUxpbmVJbmRleF0uaWNlR2F0aGVyZXI7XG4gICAgaWYgKGljZUdhdGhlcmVyLm9ubG9jYWxjYW5kaWRhdGUpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdmFyIGNhbmRpZGF0ZXMgPSB0aGlzLnRyYW5zY2VpdmVyc1tzZHBNTGluZUluZGV4XS5jYW5kaWRhdGVzO1xuICAgIHRoaXMudHJhbnNjZWl2ZXJzW3NkcE1MaW5lSW5kZXhdLmNhbmRpZGF0ZXMgPSBudWxsO1xuICAgIGljZUdhdGhlcmVyLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2xvY2FsY2FuZGlkYXRlJyxcbiAgICAgIHRoaXMudHJhbnNjZWl2ZXJzW3NkcE1MaW5lSW5kZXhdLmJ1ZmZlckNhbmRpZGF0ZXMpO1xuICAgIGljZUdhdGhlcmVyLm9ubG9jYWxjYW5kaWRhdGUgPSBmdW5jdGlvbihldnQpIHtcbiAgICAgIGlmIChzZWxmLnVzaW5nQnVuZGxlICYmIHNkcE1MaW5lSW5kZXggPiAwKSB7XG4gICAgICAgIC8vIGlmIHdlIGtub3cgdGhhdCB3ZSB1c2UgYnVuZGxlIHdlIGNhbiBkcm9wIGNhbmRpZGF0ZXMgd2l0aFxuICAgICAgICAvLyDRlWRwTUxpbmVJbmRleCA+IDAuIElmIHdlIGRvbid0IGRvIHRoaXMgdGhlbiBvdXIgc3RhdGUgZ2V0c1xuICAgICAgICAvLyBjb25mdXNlZCBzaW5jZSB3ZSBkaXNwb3NlIHRoZSBleHRyYSBpY2UgZ2F0aGVyZXIuXG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHZhciBldmVudCA9IG5ldyBFdmVudCgnaWNlY2FuZGlkYXRlJyk7XG4gICAgICBldmVudC5jYW5kaWRhdGUgPSB7c2RwTWlkOiBtaWQsIHNkcE1MaW5lSW5kZXg6IHNkcE1MaW5lSW5kZXh9O1xuXG4gICAgICB2YXIgY2FuZCA9IGV2dC5jYW5kaWRhdGU7XG4gICAgICAvLyBFZGdlIGVtaXRzIGFuIGVtcHR5IG9iamVjdCBmb3IgUlRDSWNlQ2FuZGlkYXRlQ29tcGxldGXigKVcbiAgICAgIHZhciBlbmQgPSAhY2FuZCB8fCBPYmplY3Qua2V5cyhjYW5kKS5sZW5ndGggPT09IDA7XG4gICAgICBpZiAoZW5kKSB7XG4gICAgICAgIC8vIHBvbHlmaWxsIHNpbmNlIFJUQ0ljZUdhdGhlcmVyLnN0YXRlIGlzIG5vdCBpbXBsZW1lbnRlZCBpblxuICAgICAgICAvLyBFZGdlIDEwNTQ3IHlldC5cbiAgICAgICAgaWYgKGljZUdhdGhlcmVyLnN0YXRlID09PSAnbmV3JyB8fCBpY2VHYXRoZXJlci5zdGF0ZSA9PT0gJ2dhdGhlcmluZycpIHtcbiAgICAgICAgICBpY2VHYXRoZXJlci5zdGF0ZSA9ICdjb21wbGV0ZWQnO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZiAoaWNlR2F0aGVyZXIuc3RhdGUgPT09ICduZXcnKSB7XG4gICAgICAgICAgaWNlR2F0aGVyZXIuc3RhdGUgPSAnZ2F0aGVyaW5nJztcbiAgICAgICAgfVxuICAgICAgICAvLyBSVENJY2VDYW5kaWRhdGUgZG9lc24ndCBoYXZlIGEgY29tcG9uZW50LCBuZWVkcyB0byBiZSBhZGRlZFxuICAgICAgICBjYW5kLmNvbXBvbmVudCA9IDE7XG4gICAgICAgIGV2ZW50LmNhbmRpZGF0ZS5jYW5kaWRhdGUgPSBTRFBVdGlscy53cml0ZUNhbmRpZGF0ZShjYW5kKTtcbiAgICAgIH1cblxuICAgICAgLy8gdXBkYXRlIGxvY2FsIGRlc2NyaXB0aW9uLlxuICAgICAgdmFyIHNlY3Rpb25zID0gU0RQVXRpbHMuc3BsaXRTZWN0aW9ucyhzZWxmLmxvY2FsRGVzY3JpcHRpb24uc2RwKTtcbiAgICAgIGlmICghZW5kKSB7XG4gICAgICAgIHNlY3Rpb25zW2V2ZW50LmNhbmRpZGF0ZS5zZHBNTGluZUluZGV4ICsgMV0gKz1cbiAgICAgICAgICAgICdhPScgKyBldmVudC5jYW5kaWRhdGUuY2FuZGlkYXRlICsgJ1xcclxcbic7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzZWN0aW9uc1tldmVudC5jYW5kaWRhdGUuc2RwTUxpbmVJbmRleCArIDFdICs9XG4gICAgICAgICAgICAnYT1lbmQtb2YtY2FuZGlkYXRlc1xcclxcbic7XG4gICAgICB9XG4gICAgICBzZWxmLmxvY2FsRGVzY3JpcHRpb24uc2RwID0gc2VjdGlvbnMuam9pbignJyk7XG4gICAgICB2YXIgY29tcGxldGUgPSBzZWxmLnRyYW5zY2VpdmVycy5ldmVyeShmdW5jdGlvbih0cmFuc2NlaXZlcikge1xuICAgICAgICByZXR1cm4gdHJhbnNjZWl2ZXIuaWNlR2F0aGVyZXIgJiZcbiAgICAgICAgICAgIHRyYW5zY2VpdmVyLmljZUdhdGhlcmVyLnN0YXRlID09PSAnY29tcGxldGVkJztcbiAgICAgIH0pO1xuXG4gICAgICBpZiAoc2VsZi5pY2VHYXRoZXJpbmdTdGF0ZSAhPT0gJ2dhdGhlcmluZycpIHtcbiAgICAgICAgc2VsZi5pY2VHYXRoZXJpbmdTdGF0ZSA9ICdnYXRoZXJpbmcnO1xuICAgICAgICBzZWxmLl9lbWl0R2F0aGVyaW5nU3RhdGVDaGFuZ2UoKTtcbiAgICAgIH1cblxuICAgICAgLy8gRW1pdCBjYW5kaWRhdGUuIEFsc28gZW1pdCBudWxsIGNhbmRpZGF0ZSB3aGVuIGFsbCBnYXRoZXJlcnMgYXJlXG4gICAgICAvLyBjb21wbGV0ZS5cbiAgICAgIGlmICghZW5kKSB7XG4gICAgICAgIHNlbGYuZGlzcGF0Y2hFdmVudChldmVudCk7XG4gICAgICAgIGlmICh0eXBlb2Ygc2VsZi5vbmljZWNhbmRpZGF0ZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgIHNlbGYub25pY2VjYW5kaWRhdGUoZXZlbnQpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAoY29tcGxldGUpIHtcbiAgICAgICAgc2VsZi5kaXNwYXRjaEV2ZW50KG5ldyBFdmVudCgnaWNlY2FuZGlkYXRlJykpO1xuICAgICAgICBpZiAodHlwZW9mIHNlbGYub25pY2VjYW5kaWRhdGUgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICBzZWxmLm9uaWNlY2FuZGlkYXRlKG5ldyBFdmVudCgnaWNlY2FuZGlkYXRlJykpO1xuICAgICAgICB9XG4gICAgICAgIHNlbGYuaWNlR2F0aGVyaW5nU3RhdGUgPSAnY29tcGxldGUnO1xuICAgICAgICBzZWxmLl9lbWl0R2F0aGVyaW5nU3RhdGVDaGFuZ2UoKTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgLy8gZW1pdCBhbHJlYWR5IGdhdGhlcmVkIGNhbmRpZGF0ZXMuXG4gICAgd2luZG93LnNldFRpbWVvdXQoZnVuY3Rpb24oKSB7XG4gICAgICBjYW5kaWRhdGVzLmZvckVhY2goZnVuY3Rpb24oY2FuZGlkYXRlKSB7XG4gICAgICAgIHZhciBlID0gbmV3IEV2ZW50KCdSVENJY2VHYXRoZXJFdmVudCcpO1xuICAgICAgICBlLmNhbmRpZGF0ZSA9IGNhbmRpZGF0ZTtcbiAgICAgICAgaWNlR2F0aGVyZXIub25sb2NhbGNhbmRpZGF0ZShlKTtcbiAgICAgIH0pO1xuICAgIH0sIDApO1xuICB9O1xuXG4gIC8vIENyZWF0ZSBJQ0UgdHJhbnNwb3J0IGFuZCBEVExTIHRyYW5zcG9ydC5cbiAgUlRDUGVlckNvbm5lY3Rpb24ucHJvdG90eXBlLl9jcmVhdGVJY2VBbmREdGxzVHJhbnNwb3J0cyA9IGZ1bmN0aW9uKCkge1xuICAgIHZhciBzZWxmID0gdGhpcztcbiAgICB2YXIgaWNlVHJhbnNwb3J0ID0gbmV3IHdpbmRvdy5SVENJY2VUcmFuc3BvcnQobnVsbCk7XG4gICAgaWNlVHJhbnNwb3J0Lm9uaWNlc3RhdGVjaGFuZ2UgPSBmdW5jdGlvbigpIHtcbiAgICAgIHNlbGYuX3VwZGF0ZUNvbm5lY3Rpb25TdGF0ZSgpO1xuICAgIH07XG5cbiAgICB2YXIgZHRsc1RyYW5zcG9ydCA9IG5ldyB3aW5kb3cuUlRDRHRsc1RyYW5zcG9ydChpY2VUcmFuc3BvcnQpO1xuICAgIGR0bHNUcmFuc3BvcnQub25kdGxzc3RhdGVjaGFuZ2UgPSBmdW5jdGlvbigpIHtcbiAgICAgIHNlbGYuX3VwZGF0ZUNvbm5lY3Rpb25TdGF0ZSgpO1xuICAgIH07XG4gICAgZHRsc1RyYW5zcG9ydC5vbmVycm9yID0gZnVuY3Rpb24oKSB7XG4gICAgICAvLyBvbmVycm9yIGRvZXMgbm90IHNldCBzdGF0ZSB0byBmYWlsZWQgYnkgaXRzZWxmLlxuICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGR0bHNUcmFuc3BvcnQsICdzdGF0ZScsXG4gICAgICAgICAge3ZhbHVlOiAnZmFpbGVkJywgd3JpdGFibGU6IHRydWV9KTtcbiAgICAgIHNlbGYuX3VwZGF0ZUNvbm5lY3Rpb25TdGF0ZSgpO1xuICAgIH07XG5cbiAgICByZXR1cm4ge1xuICAgICAgaWNlVHJhbnNwb3J0OiBpY2VUcmFuc3BvcnQsXG4gICAgICBkdGxzVHJhbnNwb3J0OiBkdGxzVHJhbnNwb3J0XG4gICAgfTtcbiAgfTtcblxuICAvLyBEZXN0cm95IElDRSBnYXRoZXJlciwgSUNFIHRyYW5zcG9ydCBhbmQgRFRMUyB0cmFuc3BvcnQuXG4gIC8vIFdpdGhvdXQgdHJpZ2dlcmluZyB0aGUgY2FsbGJhY2tzLlxuICBSVENQZWVyQ29ubmVjdGlvbi5wcm90b3R5cGUuX2Rpc3Bvc2VJY2VBbmREdGxzVHJhbnNwb3J0cyA9IGZ1bmN0aW9uKFxuICAgICAgc2RwTUxpbmVJbmRleCkge1xuICAgIHZhciBpY2VHYXRoZXJlciA9IHRoaXMudHJhbnNjZWl2ZXJzW3NkcE1MaW5lSW5kZXhdLmljZUdhdGhlcmVyO1xuICAgIGlmIChpY2VHYXRoZXJlcikge1xuICAgICAgZGVsZXRlIGljZUdhdGhlcmVyLm9ubG9jYWxjYW5kaWRhdGU7XG4gICAgICBkZWxldGUgdGhpcy50cmFuc2NlaXZlcnNbc2RwTUxpbmVJbmRleF0uaWNlR2F0aGVyZXI7XG4gICAgfVxuICAgIHZhciBpY2VUcmFuc3BvcnQgPSB0aGlzLnRyYW5zY2VpdmVyc1tzZHBNTGluZUluZGV4XS5pY2VUcmFuc3BvcnQ7XG4gICAgaWYgKGljZVRyYW5zcG9ydCkge1xuICAgICAgZGVsZXRlIGljZVRyYW5zcG9ydC5vbmljZXN0YXRlY2hhbmdlO1xuICAgICAgZGVsZXRlIHRoaXMudHJhbnNjZWl2ZXJzW3NkcE1MaW5lSW5kZXhdLmljZVRyYW5zcG9ydDtcbiAgICB9XG4gICAgdmFyIGR0bHNUcmFuc3BvcnQgPSB0aGlzLnRyYW5zY2VpdmVyc1tzZHBNTGluZUluZGV4XS5kdGxzVHJhbnNwb3J0O1xuICAgIGlmIChkdGxzVHJhbnNwb3J0KSB7XG4gICAgICBkZWxldGUgZHRsc1RyYW5zcG9ydC5vbmR0bHNzdGF0ZWNoYW5nZTtcbiAgICAgIGRlbGV0ZSBkdGxzVHJhbnNwb3J0Lm9uZXJyb3I7XG4gICAgICBkZWxldGUgdGhpcy50cmFuc2NlaXZlcnNbc2RwTUxpbmVJbmRleF0uZHRsc1RyYW5zcG9ydDtcbiAgICB9XG4gIH07XG5cbiAgLy8gU3RhcnQgdGhlIFJUUCBTZW5kZXIgYW5kIFJlY2VpdmVyIGZvciBhIHRyYW5zY2VpdmVyLlxuICBSVENQZWVyQ29ubmVjdGlvbi5wcm90b3R5cGUuX3RyYW5zY2VpdmUgPSBmdW5jdGlvbih0cmFuc2NlaXZlcixcbiAgICAgIHNlbmQsIHJlY3YpIHtcbiAgICB2YXIgcGFyYW1zID0gZ2V0Q29tbW9uQ2FwYWJpbGl0aWVzKHRyYW5zY2VpdmVyLmxvY2FsQ2FwYWJpbGl0aWVzLFxuICAgICAgICB0cmFuc2NlaXZlci5yZW1vdGVDYXBhYmlsaXRpZXMpO1xuICAgIGlmIChzZW5kICYmIHRyYW5zY2VpdmVyLnJ0cFNlbmRlcikge1xuICAgICAgcGFyYW1zLmVuY29kaW5ncyA9IHRyYW5zY2VpdmVyLnNlbmRFbmNvZGluZ1BhcmFtZXRlcnM7XG4gICAgICBwYXJhbXMucnRjcCA9IHtcbiAgICAgICAgY25hbWU6IFNEUFV0aWxzLmxvY2FsQ05hbWUsXG4gICAgICAgIGNvbXBvdW5kOiB0cmFuc2NlaXZlci5ydGNwUGFyYW1ldGVycy5jb21wb3VuZFxuICAgICAgfTtcbiAgICAgIGlmICh0cmFuc2NlaXZlci5yZWN2RW5jb2RpbmdQYXJhbWV0ZXJzLmxlbmd0aCkge1xuICAgICAgICBwYXJhbXMucnRjcC5zc3JjID0gdHJhbnNjZWl2ZXIucmVjdkVuY29kaW5nUGFyYW1ldGVyc1swXS5zc3JjO1xuICAgICAgfVxuICAgICAgdHJhbnNjZWl2ZXIucnRwU2VuZGVyLnNlbmQocGFyYW1zKTtcbiAgICB9XG4gICAgaWYgKHJlY3YgJiYgdHJhbnNjZWl2ZXIucnRwUmVjZWl2ZXIgJiYgcGFyYW1zLmNvZGVjcy5sZW5ndGggPiAwKSB7XG4gICAgICAvLyByZW1vdmUgUlRYIGZpZWxkIGluIEVkZ2UgMTQ5NDJcbiAgICAgIGlmICh0cmFuc2NlaXZlci5raW5kID09PSAndmlkZW8nXG4gICAgICAgICAgJiYgdHJhbnNjZWl2ZXIucmVjdkVuY29kaW5nUGFyYW1ldGVyc1xuICAgICAgICAgICYmIGVkZ2VWZXJzaW9uIDwgMTUwMTkpIHtcbiAgICAgICAgdHJhbnNjZWl2ZXIucmVjdkVuY29kaW5nUGFyYW1ldGVycy5mb3JFYWNoKGZ1bmN0aW9uKHApIHtcbiAgICAgICAgICBkZWxldGUgcC5ydHg7XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgcGFyYW1zLmVuY29kaW5ncyA9IHRyYW5zY2VpdmVyLnJlY3ZFbmNvZGluZ1BhcmFtZXRlcnM7XG4gICAgICBwYXJhbXMucnRjcCA9IHtcbiAgICAgICAgY25hbWU6IHRyYW5zY2VpdmVyLnJ0Y3BQYXJhbWV0ZXJzLmNuYW1lLFxuICAgICAgICBjb21wb3VuZDogdHJhbnNjZWl2ZXIucnRjcFBhcmFtZXRlcnMuY29tcG91bmRcbiAgICAgIH07XG4gICAgICBpZiAodHJhbnNjZWl2ZXIuc2VuZEVuY29kaW5nUGFyYW1ldGVycy5sZW5ndGgpIHtcbiAgICAgICAgcGFyYW1zLnJ0Y3Auc3NyYyA9IHRyYW5zY2VpdmVyLnNlbmRFbmNvZGluZ1BhcmFtZXRlcnNbMF0uc3NyYztcbiAgICAgIH1cbiAgICAgIHRyYW5zY2VpdmVyLnJ0cFJlY2VpdmVyLnJlY2VpdmUocGFyYW1zKTtcbiAgICB9XG4gIH07XG5cbiAgUlRDUGVlckNvbm5lY3Rpb24ucHJvdG90eXBlLnNldExvY2FsRGVzY3JpcHRpb24gPSBmdW5jdGlvbihkZXNjcmlwdGlvbikge1xuICAgIHZhciBzZWxmID0gdGhpcztcbiAgICB2YXIgYXJncyA9IGFyZ3VtZW50cztcblxuICAgIGlmICghaXNBY3Rpb25BbGxvd2VkSW5TaWduYWxpbmdTdGF0ZSgnc2V0TG9jYWxEZXNjcmlwdGlvbicsXG4gICAgICAgIGRlc2NyaXB0aW9uLnR5cGUsIHRoaXMuc2lnbmFsaW5nU3RhdGUpKSB7XG4gICAgICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24ocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgICAgIHZhciBlID0gbmV3IEVycm9yKCdDYW4gbm90IHNldCBsb2NhbCAnICsgZGVzY3JpcHRpb24udHlwZSArXG4gICAgICAgICAgICAnIGluIHN0YXRlICcgKyBzZWxmLnNpZ25hbGluZ1N0YXRlKTtcbiAgICAgICAgZS5uYW1lID0gJ0ludmFsaWRTdGF0ZUVycm9yJztcbiAgICAgICAgaWYgKGFyZ3MubGVuZ3RoID4gMiAmJiB0eXBlb2YgYXJnc1syXSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgIGFyZ3NbMl0uYXBwbHkobnVsbCwgW2VdKTtcbiAgICAgICAgfVxuICAgICAgICByZWplY3QoZSk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICB2YXIgc2VjdGlvbnM7XG4gICAgdmFyIHNlc3Npb25wYXJ0O1xuICAgIGlmIChkZXNjcmlwdGlvbi50eXBlID09PSAnb2ZmZXInKSB7XG4gICAgICAvLyBWRVJZIGxpbWl0ZWQgc3VwcG9ydCBmb3IgU0RQIG11bmdpbmcuIExpbWl0ZWQgdG86XG4gICAgICAvLyAqIGNoYW5naW5nIHRoZSBvcmRlciBvZiBjb2RlY3NcbiAgICAgIHNlY3Rpb25zID0gU0RQVXRpbHMuc3BsaXRTZWN0aW9ucyhkZXNjcmlwdGlvbi5zZHApO1xuICAgICAgc2Vzc2lvbnBhcnQgPSBzZWN0aW9ucy5zaGlmdCgpO1xuICAgICAgc2VjdGlvbnMuZm9yRWFjaChmdW5jdGlvbihtZWRpYVNlY3Rpb24sIHNkcE1MaW5lSW5kZXgpIHtcbiAgICAgICAgdmFyIGNhcHMgPSBTRFBVdGlscy5wYXJzZVJ0cFBhcmFtZXRlcnMobWVkaWFTZWN0aW9uKTtcbiAgICAgICAgc2VsZi50cmFuc2NlaXZlcnNbc2RwTUxpbmVJbmRleF0ubG9jYWxDYXBhYmlsaXRpZXMgPSBjYXBzO1xuICAgICAgfSk7XG5cbiAgICAgIHRoaXMudHJhbnNjZWl2ZXJzLmZvckVhY2goZnVuY3Rpb24odHJhbnNjZWl2ZXIsIHNkcE1MaW5lSW5kZXgpIHtcbiAgICAgICAgc2VsZi5fZ2F0aGVyKHRyYW5zY2VpdmVyLm1pZCwgc2RwTUxpbmVJbmRleCk7XG4gICAgICB9KTtcbiAgICB9IGVsc2UgaWYgKGRlc2NyaXB0aW9uLnR5cGUgPT09ICdhbnN3ZXInKSB7XG4gICAgICBzZWN0aW9ucyA9IFNEUFV0aWxzLnNwbGl0U2VjdGlvbnMoc2VsZi5yZW1vdGVEZXNjcmlwdGlvbi5zZHApO1xuICAgICAgc2Vzc2lvbnBhcnQgPSBzZWN0aW9ucy5zaGlmdCgpO1xuICAgICAgdmFyIGlzSWNlTGl0ZSA9IFNEUFV0aWxzLm1hdGNoUHJlZml4KHNlc3Npb25wYXJ0LFxuICAgICAgICAgICdhPWljZS1saXRlJykubGVuZ3RoID4gMDtcbiAgICAgIHNlY3Rpb25zLmZvckVhY2goZnVuY3Rpb24obWVkaWFTZWN0aW9uLCBzZHBNTGluZUluZGV4KSB7XG4gICAgICAgIHZhciB0cmFuc2NlaXZlciA9IHNlbGYudHJhbnNjZWl2ZXJzW3NkcE1MaW5lSW5kZXhdO1xuICAgICAgICB2YXIgaWNlR2F0aGVyZXIgPSB0cmFuc2NlaXZlci5pY2VHYXRoZXJlcjtcbiAgICAgICAgdmFyIGljZVRyYW5zcG9ydCA9IHRyYW5zY2VpdmVyLmljZVRyYW5zcG9ydDtcbiAgICAgICAgdmFyIGR0bHNUcmFuc3BvcnQgPSB0cmFuc2NlaXZlci5kdGxzVHJhbnNwb3J0O1xuICAgICAgICB2YXIgbG9jYWxDYXBhYmlsaXRpZXMgPSB0cmFuc2NlaXZlci5sb2NhbENhcGFiaWxpdGllcztcbiAgICAgICAgdmFyIHJlbW90ZUNhcGFiaWxpdGllcyA9IHRyYW5zY2VpdmVyLnJlbW90ZUNhcGFiaWxpdGllcztcblxuICAgICAgICAvLyB0cmVhdCBidW5kbGUtb25seSBhcyBub3QtcmVqZWN0ZWQuXG4gICAgICAgIHZhciByZWplY3RlZCA9IFNEUFV0aWxzLmlzUmVqZWN0ZWQobWVkaWFTZWN0aW9uKSAmJlxuICAgICAgICAgICAgIVNEUFV0aWxzLm1hdGNoUHJlZml4KG1lZGlhU2VjdGlvbiwgJ2E9YnVuZGxlLW9ubHknKS5sZW5ndGggPT09IDE7XG5cbiAgICAgICAgaWYgKCFyZWplY3RlZCAmJiAhdHJhbnNjZWl2ZXIuaXNEYXRhY2hhbm5lbCkge1xuICAgICAgICAgIHZhciByZW1vdGVJY2VQYXJhbWV0ZXJzID0gU0RQVXRpbHMuZ2V0SWNlUGFyYW1ldGVycyhcbiAgICAgICAgICAgICAgbWVkaWFTZWN0aW9uLCBzZXNzaW9ucGFydCk7XG4gICAgICAgICAgdmFyIHJlbW90ZUR0bHNQYXJhbWV0ZXJzID0gU0RQVXRpbHMuZ2V0RHRsc1BhcmFtZXRlcnMoXG4gICAgICAgICAgICAgIG1lZGlhU2VjdGlvbiwgc2Vzc2lvbnBhcnQpO1xuICAgICAgICAgIGlmIChpc0ljZUxpdGUpIHtcbiAgICAgICAgICAgIHJlbW90ZUR0bHNQYXJhbWV0ZXJzLnJvbGUgPSAnc2VydmVyJztcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAoIXNlbGYudXNpbmdCdW5kbGUgfHwgc2RwTUxpbmVJbmRleCA9PT0gMCkge1xuICAgICAgICAgICAgc2VsZi5fZ2F0aGVyKHRyYW5zY2VpdmVyLm1pZCwgc2RwTUxpbmVJbmRleCk7XG4gICAgICAgICAgICBpZiAoaWNlVHJhbnNwb3J0LnN0YXRlID09PSAnbmV3Jykge1xuICAgICAgICAgICAgICBpY2VUcmFuc3BvcnQuc3RhcnQoaWNlR2F0aGVyZXIsIHJlbW90ZUljZVBhcmFtZXRlcnMsXG4gICAgICAgICAgICAgICAgICBpc0ljZUxpdGUgPyAnY29udHJvbGxpbmcnIDogJ2NvbnRyb2xsZWQnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChkdGxzVHJhbnNwb3J0LnN0YXRlID09PSAnbmV3Jykge1xuICAgICAgICAgICAgICBkdGxzVHJhbnNwb3J0LnN0YXJ0KHJlbW90ZUR0bHNQYXJhbWV0ZXJzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICAvLyBDYWxjdWxhdGUgaW50ZXJzZWN0aW9uIG9mIGNhcGFiaWxpdGllcy5cbiAgICAgICAgICB2YXIgcGFyYW1zID0gZ2V0Q29tbW9uQ2FwYWJpbGl0aWVzKGxvY2FsQ2FwYWJpbGl0aWVzLFxuICAgICAgICAgICAgICByZW1vdGVDYXBhYmlsaXRpZXMpO1xuXG4gICAgICAgICAgLy8gU3RhcnQgdGhlIFJUQ1J0cFNlbmRlci4gVGhlIFJUQ1J0cFJlY2VpdmVyIGZvciB0aGlzXG4gICAgICAgICAgLy8gdHJhbnNjZWl2ZXIgaGFzIGFscmVhZHkgYmVlbiBzdGFydGVkIGluIHNldFJlbW90ZURlc2NyaXB0aW9uLlxuICAgICAgICAgIHNlbGYuX3RyYW5zY2VpdmUodHJhbnNjZWl2ZXIsXG4gICAgICAgICAgICAgIHBhcmFtcy5jb2RlY3MubGVuZ3RoID4gMCxcbiAgICAgICAgICAgICAgZmFsc2UpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICB0aGlzLmxvY2FsRGVzY3JpcHRpb24gPSB7XG4gICAgICB0eXBlOiBkZXNjcmlwdGlvbi50eXBlLFxuICAgICAgc2RwOiBkZXNjcmlwdGlvbi5zZHBcbiAgICB9O1xuICAgIHN3aXRjaCAoZGVzY3JpcHRpb24udHlwZSkge1xuICAgICAgY2FzZSAnb2ZmZXInOlxuICAgICAgICB0aGlzLl91cGRhdGVTaWduYWxpbmdTdGF0ZSgnaGF2ZS1sb2NhbC1vZmZlcicpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ2Fuc3dlcic6XG4gICAgICAgIHRoaXMuX3VwZGF0ZVNpZ25hbGluZ1N0YXRlKCdzdGFibGUnKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCd1bnN1cHBvcnRlZCB0eXBlIFwiJyArIGRlc2NyaXB0aW9uLnR5cGUgK1xuICAgICAgICAgICAgJ1wiJyk7XG4gICAgfVxuXG4gICAgLy8gSWYgYSBzdWNjZXNzIGNhbGxiYWNrIHdhcyBwcm92aWRlZCwgZW1pdCBJQ0UgY2FuZGlkYXRlcyBhZnRlciBpdFxuICAgIC8vIGhhcyBiZWVuIGV4ZWN1dGVkLiBPdGhlcndpc2UsIGVtaXQgY2FsbGJhY2sgYWZ0ZXIgdGhlIFByb21pc2UgaXNcbiAgICAvLyByZXNvbHZlZC5cbiAgICB2YXIgY2IgPSBhcmd1bWVudHMubGVuZ3RoID4gMSAmJiB0eXBlb2YgYXJndW1lbnRzWzFdID09PSAnZnVuY3Rpb24nICYmXG4gICAgICAgIGFyZ3VtZW50c1sxXTtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24ocmVzb2x2ZSkge1xuICAgICAgaWYgKGNiKSB7XG4gICAgICAgIGNiLmFwcGx5KG51bGwpO1xuICAgICAgfVxuICAgICAgcmVzb2x2ZSgpO1xuICAgIH0pO1xuICB9O1xuXG4gIFJUQ1BlZXJDb25uZWN0aW9uLnByb3RvdHlwZS5zZXRSZW1vdGVEZXNjcmlwdGlvbiA9IGZ1bmN0aW9uKGRlc2NyaXB0aW9uKSB7XG4gICAgdmFyIHNlbGYgPSB0aGlzO1xuICAgIHZhciBhcmdzID0gYXJndW1lbnRzO1xuXG4gICAgaWYgKCFpc0FjdGlvbkFsbG93ZWRJblNpZ25hbGluZ1N0YXRlKCdzZXRSZW1vdGVEZXNjcmlwdGlvbicsXG4gICAgICAgIGRlc2NyaXB0aW9uLnR5cGUsIHRoaXMuc2lnbmFsaW5nU3RhdGUpKSB7XG4gICAgICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24ocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgICAgIHZhciBlID0gbmV3IEVycm9yKCdDYW4gbm90IHNldCByZW1vdGUgJyArIGRlc2NyaXB0aW9uLnR5cGUgK1xuICAgICAgICAgICAgJyBpbiBzdGF0ZSAnICsgc2VsZi5zaWduYWxpbmdTdGF0ZSk7XG4gICAgICAgIGUubmFtZSA9ICdJbnZhbGlkU3RhdGVFcnJvcic7XG4gICAgICAgIGlmIChhcmdzLmxlbmd0aCA+IDIgJiYgdHlwZW9mIGFyZ3NbMl0gPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICBhcmdzWzJdLmFwcGx5KG51bGwsIFtlXSk7XG4gICAgICAgIH1cbiAgICAgICAgcmVqZWN0KGUpO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgdmFyIHN0cmVhbXMgPSB7fTtcbiAgICB0aGlzLnJlbW90ZVN0cmVhbXMuZm9yRWFjaChmdW5jdGlvbihzdHJlYW0pIHtcbiAgICAgIHN0cmVhbXNbc3RyZWFtLmlkXSA9IHN0cmVhbTtcbiAgICB9KTtcbiAgICB2YXIgcmVjZWl2ZXJMaXN0ID0gW107XG4gICAgdmFyIHNlY3Rpb25zID0gU0RQVXRpbHMuc3BsaXRTZWN0aW9ucyhkZXNjcmlwdGlvbi5zZHApO1xuICAgIHZhciBzZXNzaW9ucGFydCA9IHNlY3Rpb25zLnNoaWZ0KCk7XG4gICAgdmFyIGlzSWNlTGl0ZSA9IFNEUFV0aWxzLm1hdGNoUHJlZml4KHNlc3Npb25wYXJ0LFxuICAgICAgICAnYT1pY2UtbGl0ZScpLmxlbmd0aCA+IDA7XG4gICAgdmFyIHVzaW5nQnVuZGxlID0gU0RQVXRpbHMubWF0Y2hQcmVmaXgoc2Vzc2lvbnBhcnQsXG4gICAgICAgICdhPWdyb3VwOkJVTkRMRSAnKS5sZW5ndGggPiAwO1xuICAgIHRoaXMudXNpbmdCdW5kbGUgPSB1c2luZ0J1bmRsZTtcbiAgICB2YXIgaWNlT3B0aW9ucyA9IFNEUFV0aWxzLm1hdGNoUHJlZml4KHNlc3Npb25wYXJ0LFxuICAgICAgICAnYT1pY2Utb3B0aW9uczonKVswXTtcbiAgICBpZiAoaWNlT3B0aW9ucykge1xuICAgICAgdGhpcy5jYW5Ucmlja2xlSWNlQ2FuZGlkYXRlcyA9IGljZU9wdGlvbnMuc3Vic3RyKDE0KS5zcGxpdCgnICcpXG4gICAgICAgICAgLmluZGV4T2YoJ3RyaWNrbGUnKSA+PSAwO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmNhblRyaWNrbGVJY2VDYW5kaWRhdGVzID0gZmFsc2U7XG4gICAgfVxuXG4gICAgc2VjdGlvbnMuZm9yRWFjaChmdW5jdGlvbihtZWRpYVNlY3Rpb24sIHNkcE1MaW5lSW5kZXgpIHtcbiAgICAgIHZhciBsaW5lcyA9IFNEUFV0aWxzLnNwbGl0TGluZXMobWVkaWFTZWN0aW9uKTtcbiAgICAgIHZhciBraW5kID0gU0RQVXRpbHMuZ2V0S2luZChtZWRpYVNlY3Rpb24pO1xuICAgICAgLy8gdHJlYXQgYnVuZGxlLW9ubHkgYXMgbm90LXJlamVjdGVkLlxuICAgICAgdmFyIHJlamVjdGVkID0gU0RQVXRpbHMuaXNSZWplY3RlZChtZWRpYVNlY3Rpb24pICYmXG4gICAgICAgICAgIVNEUFV0aWxzLm1hdGNoUHJlZml4KG1lZGlhU2VjdGlvbiwgJ2E9YnVuZGxlLW9ubHknKS5sZW5ndGggPT09IDE7XG4gICAgICB2YXIgcHJvdG9jb2wgPSBsaW5lc1swXS5zdWJzdHIoMikuc3BsaXQoJyAnKVsyXTtcblxuICAgICAgdmFyIGRpcmVjdGlvbiA9IFNEUFV0aWxzLmdldERpcmVjdGlvbihtZWRpYVNlY3Rpb24sIHNlc3Npb25wYXJ0KTtcbiAgICAgIHZhciByZW1vdGVNc2lkID0gU0RQVXRpbHMucGFyc2VNc2lkKG1lZGlhU2VjdGlvbik7XG5cbiAgICAgIHZhciBtaWQgPSBTRFBVdGlscy5nZXRNaWQobWVkaWFTZWN0aW9uKSB8fCBTRFBVdGlscy5nZW5lcmF0ZUlkZW50aWZpZXIoKTtcblxuICAgICAgLy8gUmVqZWN0IGRhdGFjaGFubmVscyB3aGljaCBhcmUgbm90IGltcGxlbWVudGVkIHlldC5cbiAgICAgIGlmIChraW5kID09PSAnYXBwbGljYXRpb24nICYmIHByb3RvY29sID09PSAnRFRMUy9TQ1RQJykge1xuICAgICAgICBzZWxmLnRyYW5zY2VpdmVyc1tzZHBNTGluZUluZGV4XSA9IHtcbiAgICAgICAgICBtaWQ6IG1pZCxcbiAgICAgICAgICBpc0RhdGFjaGFubmVsOiB0cnVlXG4gICAgICAgIH07XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgdmFyIHRyYW5zY2VpdmVyO1xuICAgICAgdmFyIGljZUdhdGhlcmVyO1xuICAgICAgdmFyIGljZVRyYW5zcG9ydDtcbiAgICAgIHZhciBkdGxzVHJhbnNwb3J0O1xuICAgICAgdmFyIHJ0cFJlY2VpdmVyO1xuICAgICAgdmFyIHNlbmRFbmNvZGluZ1BhcmFtZXRlcnM7XG4gICAgICB2YXIgcmVjdkVuY29kaW5nUGFyYW1ldGVycztcbiAgICAgIHZhciBsb2NhbENhcGFiaWxpdGllcztcblxuICAgICAgdmFyIHRyYWNrO1xuICAgICAgLy8gRklYTUU6IGVuc3VyZSB0aGUgbWVkaWFTZWN0aW9uIGhhcyBydGNwLW11eCBzZXQuXG4gICAgICB2YXIgcmVtb3RlQ2FwYWJpbGl0aWVzID0gU0RQVXRpbHMucGFyc2VSdHBQYXJhbWV0ZXJzKG1lZGlhU2VjdGlvbik7XG4gICAgICB2YXIgcmVtb3RlSWNlUGFyYW1ldGVycztcbiAgICAgIHZhciByZW1vdGVEdGxzUGFyYW1ldGVycztcbiAgICAgIGlmICghcmVqZWN0ZWQpIHtcbiAgICAgICAgcmVtb3RlSWNlUGFyYW1ldGVycyA9IFNEUFV0aWxzLmdldEljZVBhcmFtZXRlcnMobWVkaWFTZWN0aW9uLFxuICAgICAgICAgICAgc2Vzc2lvbnBhcnQpO1xuICAgICAgICByZW1vdGVEdGxzUGFyYW1ldGVycyA9IFNEUFV0aWxzLmdldER0bHNQYXJhbWV0ZXJzKG1lZGlhU2VjdGlvbixcbiAgICAgICAgICAgIHNlc3Npb25wYXJ0KTtcbiAgICAgICAgcmVtb3RlRHRsc1BhcmFtZXRlcnMucm9sZSA9ICdjbGllbnQnO1xuICAgICAgfVxuICAgICAgcmVjdkVuY29kaW5nUGFyYW1ldGVycyA9XG4gICAgICAgICAgU0RQVXRpbHMucGFyc2VSdHBFbmNvZGluZ1BhcmFtZXRlcnMobWVkaWFTZWN0aW9uKTtcblxuICAgICAgdmFyIHJ0Y3BQYXJhbWV0ZXJzID0gU0RQVXRpbHMucGFyc2VSdGNwUGFyYW1ldGVycyhtZWRpYVNlY3Rpb24pO1xuXG4gICAgICB2YXIgaXNDb21wbGV0ZSA9IFNEUFV0aWxzLm1hdGNoUHJlZml4KG1lZGlhU2VjdGlvbixcbiAgICAgICAgICAnYT1lbmQtb2YtY2FuZGlkYXRlcycsIHNlc3Npb25wYXJ0KS5sZW5ndGggPiAwO1xuICAgICAgdmFyIGNhbmRzID0gU0RQVXRpbHMubWF0Y2hQcmVmaXgobWVkaWFTZWN0aW9uLCAnYT1jYW5kaWRhdGU6JylcbiAgICAgICAgICAubWFwKGZ1bmN0aW9uKGNhbmQpIHtcbiAgICAgICAgICAgIHJldHVybiBTRFBVdGlscy5wYXJzZUNhbmRpZGF0ZShjYW5kKTtcbiAgICAgICAgICB9KVxuICAgICAgICAgIC5maWx0ZXIoZnVuY3Rpb24oY2FuZCkge1xuICAgICAgICAgICAgcmV0dXJuIGNhbmQuY29tcG9uZW50ID09PSAxO1xuICAgICAgICAgIH0pO1xuXG4gICAgICAvLyBDaGVjayBpZiB3ZSBjYW4gdXNlIEJVTkRMRSBhbmQgZGlzcG9zZSB0cmFuc3BvcnRzLlxuICAgICAgaWYgKChkZXNjcmlwdGlvbi50eXBlID09PSAnb2ZmZXInIHx8IGRlc2NyaXB0aW9uLnR5cGUgPT09ICdhbnN3ZXInKSAmJlxuICAgICAgICAgICFyZWplY3RlZCAmJiB1c2luZ0J1bmRsZSAmJiBzZHBNTGluZUluZGV4ID4gMCAmJlxuICAgICAgICAgIHNlbGYudHJhbnNjZWl2ZXJzW3NkcE1MaW5lSW5kZXhdKSB7XG4gICAgICAgIHNlbGYuX2Rpc3Bvc2VJY2VBbmREdGxzVHJhbnNwb3J0cyhzZHBNTGluZUluZGV4KTtcbiAgICAgICAgc2VsZi50cmFuc2NlaXZlcnNbc2RwTUxpbmVJbmRleF0uaWNlR2F0aGVyZXIgPVxuICAgICAgICAgICAgc2VsZi50cmFuc2NlaXZlcnNbMF0uaWNlR2F0aGVyZXI7XG4gICAgICAgIHNlbGYudHJhbnNjZWl2ZXJzW3NkcE1MaW5lSW5kZXhdLmljZVRyYW5zcG9ydCA9XG4gICAgICAgICAgICBzZWxmLnRyYW5zY2VpdmVyc1swXS5pY2VUcmFuc3BvcnQ7XG4gICAgICAgIHNlbGYudHJhbnNjZWl2ZXJzW3NkcE1MaW5lSW5kZXhdLmR0bHNUcmFuc3BvcnQgPVxuICAgICAgICAgICAgc2VsZi50cmFuc2NlaXZlcnNbMF0uZHRsc1RyYW5zcG9ydDtcbiAgICAgICAgaWYgKHNlbGYudHJhbnNjZWl2ZXJzW3NkcE1MaW5lSW5kZXhdLnJ0cFNlbmRlcikge1xuICAgICAgICAgIHNlbGYudHJhbnNjZWl2ZXJzW3NkcE1MaW5lSW5kZXhdLnJ0cFNlbmRlci5zZXRUcmFuc3BvcnQoXG4gICAgICAgICAgICAgIHNlbGYudHJhbnNjZWl2ZXJzWzBdLmR0bHNUcmFuc3BvcnQpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChzZWxmLnRyYW5zY2VpdmVyc1tzZHBNTGluZUluZGV4XS5ydHBSZWNlaXZlcikge1xuICAgICAgICAgIHNlbGYudHJhbnNjZWl2ZXJzW3NkcE1MaW5lSW5kZXhdLnJ0cFJlY2VpdmVyLnNldFRyYW5zcG9ydChcbiAgICAgICAgICAgICAgc2VsZi50cmFuc2NlaXZlcnNbMF0uZHRsc1RyYW5zcG9ydCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChkZXNjcmlwdGlvbi50eXBlID09PSAnb2ZmZXInICYmICFyZWplY3RlZCkge1xuICAgICAgICB0cmFuc2NlaXZlciA9IHNlbGYudHJhbnNjZWl2ZXJzW3NkcE1MaW5lSW5kZXhdIHx8XG4gICAgICAgICAgICBzZWxmLl9jcmVhdGVUcmFuc2NlaXZlcihraW5kKTtcbiAgICAgICAgdHJhbnNjZWl2ZXIubWlkID0gbWlkO1xuXG4gICAgICAgIGlmICghdHJhbnNjZWl2ZXIuaWNlR2F0aGVyZXIpIHtcbiAgICAgICAgICB0cmFuc2NlaXZlci5pY2VHYXRoZXJlciA9IHNlbGYuX2NyZWF0ZUljZUdhdGhlcmVyKHNkcE1MaW5lSW5kZXgsXG4gICAgICAgICAgICAgIHVzaW5nQnVuZGxlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChjYW5kcy5sZW5ndGggJiYgdHJhbnNjZWl2ZXIuaWNlVHJhbnNwb3J0LnN0YXRlID09PSAnbmV3Jykge1xuICAgICAgICAgIGlmIChpc0NvbXBsZXRlICYmICghdXNpbmdCdW5kbGUgfHwgc2RwTUxpbmVJbmRleCA9PT0gMCkpIHtcbiAgICAgICAgICAgIHRyYW5zY2VpdmVyLmljZVRyYW5zcG9ydC5zZXRSZW1vdGVDYW5kaWRhdGVzKGNhbmRzKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY2FuZHMuZm9yRWFjaChmdW5jdGlvbihjYW5kaWRhdGUpIHtcbiAgICAgICAgICAgICAgbWF5YmVBZGRDYW5kaWRhdGUodHJhbnNjZWl2ZXIuaWNlVHJhbnNwb3J0LCBjYW5kaWRhdGUpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgbG9jYWxDYXBhYmlsaXRpZXMgPSB3aW5kb3cuUlRDUnRwUmVjZWl2ZXIuZ2V0Q2FwYWJpbGl0aWVzKGtpbmQpO1xuXG4gICAgICAgIC8vIGZpbHRlciBSVFggdW50aWwgYWRkaXRpb25hbCBzdHVmZiBuZWVkZWQgZm9yIFJUWCBpcyBpbXBsZW1lbnRlZFxuICAgICAgICAvLyBpbiBhZGFwdGVyLmpzXG4gICAgICAgIGlmIChlZGdlVmVyc2lvbiA8IDE1MDE5KSB7XG4gICAgICAgICAgbG9jYWxDYXBhYmlsaXRpZXMuY29kZWNzID0gbG9jYWxDYXBhYmlsaXRpZXMuY29kZWNzLmZpbHRlcihcbiAgICAgICAgICAgICAgZnVuY3Rpb24oY29kZWMpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gY29kZWMubmFtZSAhPT0gJ3J0eCc7XG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgc2VuZEVuY29kaW5nUGFyYW1ldGVycyA9IHRyYW5zY2VpdmVyLnNlbmRFbmNvZGluZ1BhcmFtZXRlcnMgfHwgW3tcbiAgICAgICAgICBzc3JjOiAoMiAqIHNkcE1MaW5lSW5kZXggKyAyKSAqIDEwMDFcbiAgICAgICAgfV07XG5cbiAgICAgICAgdmFyIGlzTmV3VHJhY2sgPSBmYWxzZTtcbiAgICAgICAgaWYgKGRpcmVjdGlvbiA9PT0gJ3NlbmRyZWN2JyB8fCBkaXJlY3Rpb24gPT09ICdzZW5kb25seScpIHtcbiAgICAgICAgICBpc05ld1RyYWNrID0gIXRyYW5zY2VpdmVyLnJ0cFJlY2VpdmVyO1xuICAgICAgICAgIHJ0cFJlY2VpdmVyID0gdHJhbnNjZWl2ZXIucnRwUmVjZWl2ZXIgfHxcbiAgICAgICAgICAgICAgbmV3IHdpbmRvdy5SVENSdHBSZWNlaXZlcih0cmFuc2NlaXZlci5kdGxzVHJhbnNwb3J0LCBraW5kKTtcblxuICAgICAgICAgIGlmIChpc05ld1RyYWNrKSB7XG4gICAgICAgICAgICB2YXIgc3RyZWFtO1xuICAgICAgICAgICAgdHJhY2sgPSBydHBSZWNlaXZlci50cmFjaztcbiAgICAgICAgICAgIC8vIEZJWE1FOiBkb2VzIG5vdCB3b3JrIHdpdGggUGxhbiBCLlxuICAgICAgICAgICAgaWYgKHJlbW90ZU1zaWQpIHtcbiAgICAgICAgICAgICAgaWYgKCFzdHJlYW1zW3JlbW90ZU1zaWQuc3RyZWFtXSkge1xuICAgICAgICAgICAgICAgIHN0cmVhbXNbcmVtb3RlTXNpZC5zdHJlYW1dID0gbmV3IHdpbmRvdy5NZWRpYVN0cmVhbSgpO1xuICAgICAgICAgICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShzdHJlYW1zW3JlbW90ZU1zaWQuc3RyZWFtXSwgJ2lkJywge1xuICAgICAgICAgICAgICAgICAgZ2V0OiBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlbW90ZU1zaWQuc3RyZWFtO1xuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0cmFjaywgJ2lkJywge1xuICAgICAgICAgICAgICAgIGdldDogZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICAgICAgICByZXR1cm4gcmVtb3RlTXNpZC50cmFjaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICBzdHJlYW0gPSBzdHJlYW1zW3JlbW90ZU1zaWQuc3RyZWFtXTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIGlmICghc3RyZWFtcy5kZWZhdWx0KSB7XG4gICAgICAgICAgICAgICAgc3RyZWFtcy5kZWZhdWx0ID0gbmV3IHdpbmRvdy5NZWRpYVN0cmVhbSgpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHN0cmVhbSA9IHN0cmVhbXMuZGVmYXVsdDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHN0cmVhbS5hZGRUcmFjayh0cmFjayk7XG4gICAgICAgICAgICByZWNlaXZlckxpc3QucHVzaChbdHJhY2ssIHJ0cFJlY2VpdmVyLCBzdHJlYW1dKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICB0cmFuc2NlaXZlci5sb2NhbENhcGFiaWxpdGllcyA9IGxvY2FsQ2FwYWJpbGl0aWVzO1xuICAgICAgICB0cmFuc2NlaXZlci5yZW1vdGVDYXBhYmlsaXRpZXMgPSByZW1vdGVDYXBhYmlsaXRpZXM7XG4gICAgICAgIHRyYW5zY2VpdmVyLnJ0cFJlY2VpdmVyID0gcnRwUmVjZWl2ZXI7XG4gICAgICAgIHRyYW5zY2VpdmVyLnJ0Y3BQYXJhbWV0ZXJzID0gcnRjcFBhcmFtZXRlcnM7XG4gICAgICAgIHRyYW5zY2VpdmVyLnNlbmRFbmNvZGluZ1BhcmFtZXRlcnMgPSBzZW5kRW5jb2RpbmdQYXJhbWV0ZXJzO1xuICAgICAgICB0cmFuc2NlaXZlci5yZWN2RW5jb2RpbmdQYXJhbWV0ZXJzID0gcmVjdkVuY29kaW5nUGFyYW1ldGVycztcblxuICAgICAgICAvLyBTdGFydCB0aGUgUlRDUnRwUmVjZWl2ZXIgbm93LiBUaGUgUlRQU2VuZGVyIGlzIHN0YXJ0ZWQgaW5cbiAgICAgICAgLy8gc2V0TG9jYWxEZXNjcmlwdGlvbi5cbiAgICAgICAgc2VsZi5fdHJhbnNjZWl2ZShzZWxmLnRyYW5zY2VpdmVyc1tzZHBNTGluZUluZGV4XSxcbiAgICAgICAgICAgIGZhbHNlLFxuICAgICAgICAgICAgaXNOZXdUcmFjayk7XG4gICAgICB9IGVsc2UgaWYgKGRlc2NyaXB0aW9uLnR5cGUgPT09ICdhbnN3ZXInICYmICFyZWplY3RlZCkge1xuICAgICAgICB0cmFuc2NlaXZlciA9IHNlbGYudHJhbnNjZWl2ZXJzW3NkcE1MaW5lSW5kZXhdO1xuICAgICAgICBpY2VHYXRoZXJlciA9IHRyYW5zY2VpdmVyLmljZUdhdGhlcmVyO1xuICAgICAgICBpY2VUcmFuc3BvcnQgPSB0cmFuc2NlaXZlci5pY2VUcmFuc3BvcnQ7XG4gICAgICAgIGR0bHNUcmFuc3BvcnQgPSB0cmFuc2NlaXZlci5kdGxzVHJhbnNwb3J0O1xuICAgICAgICBydHBSZWNlaXZlciA9IHRyYW5zY2VpdmVyLnJ0cFJlY2VpdmVyO1xuICAgICAgICBzZW5kRW5jb2RpbmdQYXJhbWV0ZXJzID0gdHJhbnNjZWl2ZXIuc2VuZEVuY29kaW5nUGFyYW1ldGVycztcbiAgICAgICAgbG9jYWxDYXBhYmlsaXRpZXMgPSB0cmFuc2NlaXZlci5sb2NhbENhcGFiaWxpdGllcztcblxuICAgICAgICBzZWxmLnRyYW5zY2VpdmVyc1tzZHBNTGluZUluZGV4XS5yZWN2RW5jb2RpbmdQYXJhbWV0ZXJzID1cbiAgICAgICAgICAgIHJlY3ZFbmNvZGluZ1BhcmFtZXRlcnM7XG4gICAgICAgIHNlbGYudHJhbnNjZWl2ZXJzW3NkcE1MaW5lSW5kZXhdLnJlbW90ZUNhcGFiaWxpdGllcyA9XG4gICAgICAgICAgICByZW1vdGVDYXBhYmlsaXRpZXM7XG4gICAgICAgIHNlbGYudHJhbnNjZWl2ZXJzW3NkcE1MaW5lSW5kZXhdLnJ0Y3BQYXJhbWV0ZXJzID0gcnRjcFBhcmFtZXRlcnM7XG5cbiAgICAgICAgaWYgKGNhbmRzLmxlbmd0aCAmJiBpY2VUcmFuc3BvcnQuc3RhdGUgPT09ICduZXcnKSB7XG4gICAgICAgICAgaWYgKChpc0ljZUxpdGUgfHwgaXNDb21wbGV0ZSkgJiZcbiAgICAgICAgICAgICAgKCF1c2luZ0J1bmRsZSB8fCBzZHBNTGluZUluZGV4ID09PSAwKSkge1xuICAgICAgICAgICAgaWNlVHJhbnNwb3J0LnNldFJlbW90ZUNhbmRpZGF0ZXMoY2FuZHMpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjYW5kcy5mb3JFYWNoKGZ1bmN0aW9uKGNhbmRpZGF0ZSkge1xuICAgICAgICAgICAgICBtYXliZUFkZENhbmRpZGF0ZSh0cmFuc2NlaXZlci5pY2VUcmFuc3BvcnQsIGNhbmRpZGF0ZSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIXVzaW5nQnVuZGxlIHx8IHNkcE1MaW5lSW5kZXggPT09IDApIHtcbiAgICAgICAgICBpZiAoaWNlVHJhbnNwb3J0LnN0YXRlID09PSAnbmV3Jykge1xuICAgICAgICAgICAgaWNlVHJhbnNwb3J0LnN0YXJ0KGljZUdhdGhlcmVyLCByZW1vdGVJY2VQYXJhbWV0ZXJzLFxuICAgICAgICAgICAgICAgICdjb250cm9sbGluZycpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoZHRsc1RyYW5zcG9ydC5zdGF0ZSA9PT0gJ25ldycpIHtcbiAgICAgICAgICAgIGR0bHNUcmFuc3BvcnQuc3RhcnQocmVtb3RlRHRsc1BhcmFtZXRlcnMpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHNlbGYuX3RyYW5zY2VpdmUodHJhbnNjZWl2ZXIsXG4gICAgICAgICAgICBkaXJlY3Rpb24gPT09ICdzZW5kcmVjdicgfHwgZGlyZWN0aW9uID09PSAncmVjdm9ubHknLFxuICAgICAgICAgICAgZGlyZWN0aW9uID09PSAnc2VuZHJlY3YnIHx8IGRpcmVjdGlvbiA9PT0gJ3NlbmRvbmx5Jyk7XG5cbiAgICAgICAgaWYgKHJ0cFJlY2VpdmVyICYmXG4gICAgICAgICAgICAoZGlyZWN0aW9uID09PSAnc2VuZHJlY3YnIHx8IGRpcmVjdGlvbiA9PT0gJ3NlbmRvbmx5JykpIHtcbiAgICAgICAgICB0cmFjayA9IHJ0cFJlY2VpdmVyLnRyYWNrO1xuICAgICAgICAgIGlmIChyZW1vdGVNc2lkKSB7XG4gICAgICAgICAgICBpZiAoIXN0cmVhbXNbcmVtb3RlTXNpZC5zdHJlYW1dKSB7XG4gICAgICAgICAgICAgIHN0cmVhbXNbcmVtb3RlTXNpZC5zdHJlYW1dID0gbmV3IHdpbmRvdy5NZWRpYVN0cmVhbSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgc3RyZWFtc1tyZW1vdGVNc2lkLnN0cmVhbV0uYWRkVHJhY2sodHJhY2spO1xuICAgICAgICAgICAgcmVjZWl2ZXJMaXN0LnB1c2goW3RyYWNrLCBydHBSZWNlaXZlciwgc3RyZWFtc1tyZW1vdGVNc2lkLnN0cmVhbV1dKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaWYgKCFzdHJlYW1zLmRlZmF1bHQpIHtcbiAgICAgICAgICAgICAgc3RyZWFtcy5kZWZhdWx0ID0gbmV3IHdpbmRvdy5NZWRpYVN0cmVhbSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgc3RyZWFtcy5kZWZhdWx0LmFkZFRyYWNrKHRyYWNrKTtcbiAgICAgICAgICAgIHJlY2VpdmVyTGlzdC5wdXNoKFt0cmFjaywgcnRwUmVjZWl2ZXIsIHN0cmVhbXMuZGVmYXVsdF0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyBGSVhNRTogYWN0dWFsbHkgdGhlIHJlY2VpdmVyIHNob3VsZCBiZSBjcmVhdGVkIGxhdGVyLlxuICAgICAgICAgIGRlbGV0ZSB0cmFuc2NlaXZlci5ydHBSZWNlaXZlcjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pO1xuXG4gICAgaWYgKHRoaXMuX2R0bHNSb2xlID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHRoaXMuX2R0bHNSb2xlID0gZGVzY3JpcHRpb24udHlwZSA9PT0gJ29mZmVyJyA/ICdhY3RpdmUnIDogJ3Bhc3NpdmUnO1xuICAgIH1cblxuICAgIHRoaXMucmVtb3RlRGVzY3JpcHRpb24gPSB7XG4gICAgICB0eXBlOiBkZXNjcmlwdGlvbi50eXBlLFxuICAgICAgc2RwOiBkZXNjcmlwdGlvbi5zZHBcbiAgICB9O1xuICAgIHN3aXRjaCAoZGVzY3JpcHRpb24udHlwZSkge1xuICAgICAgY2FzZSAnb2ZmZXInOlxuICAgICAgICB0aGlzLl91cGRhdGVTaWduYWxpbmdTdGF0ZSgnaGF2ZS1yZW1vdGUtb2ZmZXInKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdhbnN3ZXInOlxuICAgICAgICB0aGlzLl91cGRhdGVTaWduYWxpbmdTdGF0ZSgnc3RhYmxlJyk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcigndW5zdXBwb3J0ZWQgdHlwZSBcIicgKyBkZXNjcmlwdGlvbi50eXBlICtcbiAgICAgICAgICAgICdcIicpO1xuICAgIH1cbiAgICBPYmplY3Qua2V5cyhzdHJlYW1zKS5mb3JFYWNoKGZ1bmN0aW9uKHNpZCkge1xuICAgICAgdmFyIHN0cmVhbSA9IHN0cmVhbXNbc2lkXTtcbiAgICAgIGlmIChzdHJlYW0uZ2V0VHJhY2tzKCkubGVuZ3RoKSB7XG4gICAgICAgIGlmIChzZWxmLnJlbW90ZVN0cmVhbXMuaW5kZXhPZihzdHJlYW0pID09PSAtMSkge1xuICAgICAgICAgIHNlbGYucmVtb3RlU3RyZWFtcy5wdXNoKHN0cmVhbSk7XG4gICAgICAgICAgdmFyIGV2ZW50ID0gbmV3IEV2ZW50KCdhZGRzdHJlYW0nKTtcbiAgICAgICAgICBldmVudC5zdHJlYW0gPSBzdHJlYW07XG4gICAgICAgICAgd2luZG93LnNldFRpbWVvdXQoZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICBzZWxmLmRpc3BhdGNoRXZlbnQoZXZlbnQpO1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBzZWxmLm9uYWRkc3RyZWFtID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICAgIHNlbGYub25hZGRzdHJlYW0oZXZlbnQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgcmVjZWl2ZXJMaXN0LmZvckVhY2goZnVuY3Rpb24oaXRlbSkge1xuICAgICAgICAgIHZhciB0cmFjayA9IGl0ZW1bMF07XG4gICAgICAgICAgdmFyIHJlY2VpdmVyID0gaXRlbVsxXTtcbiAgICAgICAgICBpZiAoc3RyZWFtLmlkICE9PSBpdGVtWzJdLmlkKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuICAgICAgICAgIHZhciB0cmFja0V2ZW50ID0gbmV3IEV2ZW50KCd0cmFjaycpO1xuICAgICAgICAgIHRyYWNrRXZlbnQudHJhY2sgPSB0cmFjaztcbiAgICAgICAgICB0cmFja0V2ZW50LnJlY2VpdmVyID0gcmVjZWl2ZXI7XG4gICAgICAgICAgdHJhY2tFdmVudC50cmFuc2NlaXZlciA9IHtyZWNlaXZlcjogcmVjZWl2ZXJ9O1xuICAgICAgICAgIHRyYWNrRXZlbnQuc3RyZWFtcyA9IFtzdHJlYW1dO1xuICAgICAgICAgIHdpbmRvdy5zZXRUaW1lb3V0KGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgc2VsZi5kaXNwYXRjaEV2ZW50KHRyYWNrRXZlbnQpO1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBzZWxmLm9udHJhY2sgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgICAgc2VsZi5vbnRyYWNrKHRyYWNrRXZlbnQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIC8vIGNoZWNrIHdoZXRoZXIgYWRkSWNlQ2FuZGlkYXRlKHt9KSB3YXMgY2FsbGVkIHdpdGhpbiBmb3VyIHNlY29uZHMgYWZ0ZXJcbiAgICAvLyBzZXRSZW1vdGVEZXNjcmlwdGlvbi5cbiAgICB3aW5kb3cuc2V0VGltZW91dChmdW5jdGlvbigpIHtcbiAgICAgIGlmICghKHNlbGYgJiYgc2VsZi50cmFuc2NlaXZlcnMpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHNlbGYudHJhbnNjZWl2ZXJzLmZvckVhY2goZnVuY3Rpb24odHJhbnNjZWl2ZXIpIHtcbiAgICAgICAgaWYgKHRyYW5zY2VpdmVyLmljZVRyYW5zcG9ydCAmJlxuICAgICAgICAgICAgdHJhbnNjZWl2ZXIuaWNlVHJhbnNwb3J0LnN0YXRlID09PSAnbmV3JyAmJlxuICAgICAgICAgICAgdHJhbnNjZWl2ZXIuaWNlVHJhbnNwb3J0LmdldFJlbW90ZUNhbmRpZGF0ZXMoKS5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgY29uc29sZS53YXJuKCdUaW1lb3V0IGZvciBhZGRSZW1vdGVDYW5kaWRhdGUuIENvbnNpZGVyIHNlbmRpbmcgJyArXG4gICAgICAgICAgICAgICdhbiBlbmQtb2YtY2FuZGlkYXRlcyBub3RpZmljYXRpb24nKTtcbiAgICAgICAgICB0cmFuc2NlaXZlci5pY2VUcmFuc3BvcnQuYWRkUmVtb3RlQ2FuZGlkYXRlKHt9KTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfSwgNDAwMCk7XG5cbiAgICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24ocmVzb2x2ZSkge1xuICAgICAgaWYgKGFyZ3MubGVuZ3RoID4gMSAmJiB0eXBlb2YgYXJnc1sxXSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICBhcmdzWzFdLmFwcGx5KG51bGwpO1xuICAgICAgfVxuICAgICAgcmVzb2x2ZSgpO1xuICAgIH0pO1xuICB9O1xuXG4gIFJUQ1BlZXJDb25uZWN0aW9uLnByb3RvdHlwZS5jbG9zZSA9IGZ1bmN0aW9uKCkge1xuICAgIHRoaXMudHJhbnNjZWl2ZXJzLmZvckVhY2goZnVuY3Rpb24odHJhbnNjZWl2ZXIpIHtcbiAgICAgIC8qIG5vdCB5ZXRcbiAgICAgIGlmICh0cmFuc2NlaXZlci5pY2VHYXRoZXJlcikge1xuICAgICAgICB0cmFuc2NlaXZlci5pY2VHYXRoZXJlci5jbG9zZSgpO1xuICAgICAgfVxuICAgICAgKi9cbiAgICAgIGlmICh0cmFuc2NlaXZlci5pY2VUcmFuc3BvcnQpIHtcbiAgICAgICAgdHJhbnNjZWl2ZXIuaWNlVHJhbnNwb3J0LnN0b3AoKTtcbiAgICAgIH1cbiAgICAgIGlmICh0cmFuc2NlaXZlci5kdGxzVHJhbnNwb3J0KSB7XG4gICAgICAgIHRyYW5zY2VpdmVyLmR0bHNUcmFuc3BvcnQuc3RvcCgpO1xuICAgICAgfVxuICAgICAgaWYgKHRyYW5zY2VpdmVyLnJ0cFNlbmRlcikge1xuICAgICAgICB0cmFuc2NlaXZlci5ydHBTZW5kZXIuc3RvcCgpO1xuICAgICAgfVxuICAgICAgaWYgKHRyYW5zY2VpdmVyLnJ0cFJlY2VpdmVyKSB7XG4gICAgICAgIHRyYW5zY2VpdmVyLnJ0cFJlY2VpdmVyLnN0b3AoKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICAvLyBGSVhNRTogY2xlYW4gdXAgdHJhY2tzLCBsb2NhbCBzdHJlYW1zLCByZW1vdGUgc3RyZWFtcywgZXRjXG4gICAgdGhpcy5fdXBkYXRlU2lnbmFsaW5nU3RhdGUoJ2Nsb3NlZCcpO1xuICB9O1xuXG4gIC8vIFVwZGF0ZSB0aGUgc2lnbmFsaW5nIHN0YXRlLlxuICBSVENQZWVyQ29ubmVjdGlvbi5wcm90b3R5cGUuX3VwZGF0ZVNpZ25hbGluZ1N0YXRlID0gZnVuY3Rpb24obmV3U3RhdGUpIHtcbiAgICB0aGlzLnNpZ25hbGluZ1N0YXRlID0gbmV3U3RhdGU7XG4gICAgdmFyIGV2ZW50ID0gbmV3IEV2ZW50KCdzaWduYWxpbmdzdGF0ZWNoYW5nZScpO1xuICAgIHRoaXMuZGlzcGF0Y2hFdmVudChldmVudCk7XG4gICAgaWYgKHR5cGVvZiB0aGlzLm9uc2lnbmFsaW5nc3RhdGVjaGFuZ2UgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHRoaXMub25zaWduYWxpbmdzdGF0ZWNoYW5nZShldmVudCk7XG4gICAgfVxuICB9O1xuXG4gIC8vIERldGVybWluZSB3aGV0aGVyIHRvIGZpcmUgdGhlIG5lZ290aWF0aW9ubmVlZGVkIGV2ZW50LlxuICBSVENQZWVyQ29ubmVjdGlvbi5wcm90b3R5cGUuX21heWJlRmlyZU5lZ290aWF0aW9uTmVlZGVkID0gZnVuY3Rpb24oKSB7XG4gICAgdmFyIHNlbGYgPSB0aGlzO1xuICAgIGlmICh0aGlzLnNpZ25hbGluZ1N0YXRlICE9PSAnc3RhYmxlJyB8fCB0aGlzLm5lZWROZWdvdGlhdGlvbiA9PT0gdHJ1ZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLm5lZWROZWdvdGlhdGlvbiA9IHRydWU7XG4gICAgd2luZG93LnNldFRpbWVvdXQoZnVuY3Rpb24oKSB7XG4gICAgICBpZiAoc2VsZi5uZWVkTmVnb3RpYXRpb24gPT09IGZhbHNlKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHNlbGYubmVlZE5lZ290aWF0aW9uID0gZmFsc2U7XG4gICAgICB2YXIgZXZlbnQgPSBuZXcgRXZlbnQoJ25lZ290aWF0aW9ubmVlZGVkJyk7XG4gICAgICBzZWxmLmRpc3BhdGNoRXZlbnQoZXZlbnQpO1xuICAgICAgaWYgKHR5cGVvZiBzZWxmLm9ubmVnb3RpYXRpb25uZWVkZWQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgc2VsZi5vbm5lZ290aWF0aW9ubmVlZGVkKGV2ZW50KTtcbiAgICAgIH1cbiAgICB9LCAwKTtcbiAgfTtcblxuICAvLyBVcGRhdGUgdGhlIGNvbm5lY3Rpb24gc3RhdGUuXG4gIFJUQ1BlZXJDb25uZWN0aW9uLnByb3RvdHlwZS5fdXBkYXRlQ29ubmVjdGlvblN0YXRlID0gZnVuY3Rpb24oKSB7XG4gICAgdmFyIG5ld1N0YXRlO1xuICAgIHZhciBzdGF0ZXMgPSB7XG4gICAgICAnbmV3JzogMCxcbiAgICAgIGNsb3NlZDogMCxcbiAgICAgIGNvbm5lY3Rpbmc6IDAsXG4gICAgICBjaGVja2luZzogMCxcbiAgICAgIGNvbm5lY3RlZDogMCxcbiAgICAgIGNvbXBsZXRlZDogMCxcbiAgICAgIGRpc2Nvbm5lY3RlZDogMCxcbiAgICAgIGZhaWxlZDogMFxuICAgIH07XG4gICAgdGhpcy50cmFuc2NlaXZlcnMuZm9yRWFjaChmdW5jdGlvbih0cmFuc2NlaXZlcikge1xuICAgICAgc3RhdGVzW3RyYW5zY2VpdmVyLmljZVRyYW5zcG9ydC5zdGF0ZV0rKztcbiAgICAgIHN0YXRlc1t0cmFuc2NlaXZlci5kdGxzVHJhbnNwb3J0LnN0YXRlXSsrO1xuICAgIH0pO1xuICAgIC8vIElDRVRyYW5zcG9ydC5jb21wbGV0ZWQgYW5kIGNvbm5lY3RlZCBhcmUgdGhlIHNhbWUgZm9yIHRoaXMgcHVycG9zZS5cbiAgICBzdGF0ZXMuY29ubmVjdGVkICs9IHN0YXRlcy5jb21wbGV0ZWQ7XG5cbiAgICBuZXdTdGF0ZSA9ICduZXcnO1xuICAgIGlmIChzdGF0ZXMuZmFpbGVkID4gMCkge1xuICAgICAgbmV3U3RhdGUgPSAnZmFpbGVkJztcbiAgICB9IGVsc2UgaWYgKHN0YXRlcy5jb25uZWN0aW5nID4gMCB8fCBzdGF0ZXMuY2hlY2tpbmcgPiAwKSB7XG4gICAgICBuZXdTdGF0ZSA9ICdjb25uZWN0aW5nJztcbiAgICB9IGVsc2UgaWYgKHN0YXRlcy5kaXNjb25uZWN0ZWQgPiAwKSB7XG4gICAgICBuZXdTdGF0ZSA9ICdkaXNjb25uZWN0ZWQnO1xuICAgIH0gZWxzZSBpZiAoc3RhdGVzLm5ldyA+IDApIHtcbiAgICAgIG5ld1N0YXRlID0gJ25ldyc7XG4gICAgfSBlbHNlIGlmIChzdGF0ZXMuY29ubmVjdGVkID4gMCB8fCBzdGF0ZXMuY29tcGxldGVkID4gMCkge1xuICAgICAgbmV3U3RhdGUgPSAnY29ubmVjdGVkJztcbiAgICB9XG5cbiAgICBpZiAobmV3U3RhdGUgIT09IHRoaXMuaWNlQ29ubmVjdGlvblN0YXRlKSB7XG4gICAgICB0aGlzLmljZUNvbm5lY3Rpb25TdGF0ZSA9IG5ld1N0YXRlO1xuICAgICAgdmFyIGV2ZW50ID0gbmV3IEV2ZW50KCdpY2Vjb25uZWN0aW9uc3RhdGVjaGFuZ2UnKTtcbiAgICAgIHRoaXMuZGlzcGF0Y2hFdmVudChldmVudCk7XG4gICAgICBpZiAodHlwZW9mIHRoaXMub25pY2Vjb25uZWN0aW9uc3RhdGVjaGFuZ2UgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgdGhpcy5vbmljZWNvbm5lY3Rpb25zdGF0ZWNoYW5nZShldmVudCk7XG4gICAgICB9XG4gICAgfVxuICB9O1xuXG4gIFJUQ1BlZXJDb25uZWN0aW9uLnByb3RvdHlwZS5jcmVhdGVPZmZlciA9IGZ1bmN0aW9uKCkge1xuICAgIHZhciBzZWxmID0gdGhpcztcbiAgICB2YXIgYXJncyA9IGFyZ3VtZW50cztcblxuICAgIHZhciBvZmZlck9wdGlvbnM7XG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDEgJiYgdHlwZW9mIGFyZ3VtZW50c1swXSAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgb2ZmZXJPcHRpb25zID0gYXJndW1lbnRzWzBdO1xuICAgIH0gZWxzZSBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMykge1xuICAgICAgb2ZmZXJPcHRpb25zID0gYXJndW1lbnRzWzJdO1xuICAgIH1cblxuICAgIHZhciBudW1BdWRpb1RyYWNrcyA9IHRoaXMudHJhbnNjZWl2ZXJzLmZpbHRlcihmdW5jdGlvbih0KSB7XG4gICAgICByZXR1cm4gdC5raW5kID09PSAnYXVkaW8nO1xuICAgIH0pLmxlbmd0aDtcbiAgICB2YXIgbnVtVmlkZW9UcmFja3MgPSB0aGlzLnRyYW5zY2VpdmVycy5maWx0ZXIoZnVuY3Rpb24odCkge1xuICAgICAgcmV0dXJuIHQua2luZCA9PT0gJ3ZpZGVvJztcbiAgICB9KS5sZW5ndGg7XG5cbiAgICAvLyBEZXRlcm1pbmUgbnVtYmVyIG9mIGF1ZGlvIGFuZCB2aWRlbyB0cmFja3Mgd2UgbmVlZCB0byBzZW5kL3JlY3YuXG4gICAgaWYgKG9mZmVyT3B0aW9ucykge1xuICAgICAgLy8gUmVqZWN0IENocm9tZSBsZWdhY3kgY29uc3RyYWludHMuXG4gICAgICBpZiAob2ZmZXJPcHRpb25zLm1hbmRhdG9yeSB8fCBvZmZlck9wdGlvbnMub3B0aW9uYWwpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcbiAgICAgICAgICAgICdMZWdhY3kgbWFuZGF0b3J5L29wdGlvbmFsIGNvbnN0cmFpbnRzIG5vdCBzdXBwb3J0ZWQuJyk7XG4gICAgICB9XG4gICAgICBpZiAob2ZmZXJPcHRpb25zLm9mZmVyVG9SZWNlaXZlQXVkaW8gIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBpZiAob2ZmZXJPcHRpb25zLm9mZmVyVG9SZWNlaXZlQXVkaW8gPT09IHRydWUpIHtcbiAgICAgICAgICBudW1BdWRpb1RyYWNrcyA9IDE7XG4gICAgICAgIH0gZWxzZSBpZiAob2ZmZXJPcHRpb25zLm9mZmVyVG9SZWNlaXZlQXVkaW8gPT09IGZhbHNlKSB7XG4gICAgICAgICAgbnVtQXVkaW9UcmFja3MgPSAwO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIG51bUF1ZGlvVHJhY2tzID0gb2ZmZXJPcHRpb25zLm9mZmVyVG9SZWNlaXZlQXVkaW87XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChvZmZlck9wdGlvbnMub2ZmZXJUb1JlY2VpdmVWaWRlbyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGlmIChvZmZlck9wdGlvbnMub2ZmZXJUb1JlY2VpdmVWaWRlbyA9PT0gdHJ1ZSkge1xuICAgICAgICAgIG51bVZpZGVvVHJhY2tzID0gMTtcbiAgICAgICAgfSBlbHNlIGlmIChvZmZlck9wdGlvbnMub2ZmZXJUb1JlY2VpdmVWaWRlbyA9PT0gZmFsc2UpIHtcbiAgICAgICAgICBudW1WaWRlb1RyYWNrcyA9IDA7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgbnVtVmlkZW9UcmFja3MgPSBvZmZlck9wdGlvbnMub2ZmZXJUb1JlY2VpdmVWaWRlbztcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMudHJhbnNjZWl2ZXJzLmZvckVhY2goZnVuY3Rpb24odHJhbnNjZWl2ZXIpIHtcbiAgICAgIGlmICh0cmFuc2NlaXZlci5raW5kID09PSAnYXVkaW8nKSB7XG4gICAgICAgIG51bUF1ZGlvVHJhY2tzLS07XG4gICAgICAgIGlmIChudW1BdWRpb1RyYWNrcyA8IDApIHtcbiAgICAgICAgICB0cmFuc2NlaXZlci53YW50UmVjZWl2ZSA9IGZhbHNlO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKHRyYW5zY2VpdmVyLmtpbmQgPT09ICd2aWRlbycpIHtcbiAgICAgICAgbnVtVmlkZW9UcmFja3MtLTtcbiAgICAgICAgaWYgKG51bVZpZGVvVHJhY2tzIDwgMCkge1xuICAgICAgICAgIHRyYW5zY2VpdmVyLndhbnRSZWNlaXZlID0gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcblxuICAgIC8vIENyZWF0ZSBNLWxpbmVzIGZvciByZWN2b25seSBzdHJlYW1zLlxuICAgIHdoaWxlIChudW1BdWRpb1RyYWNrcyA+IDAgfHwgbnVtVmlkZW9UcmFja3MgPiAwKSB7XG4gICAgICBpZiAobnVtQXVkaW9UcmFja3MgPiAwKSB7XG4gICAgICAgIHRoaXMuX2NyZWF0ZVRyYW5zY2VpdmVyKCdhdWRpbycpO1xuICAgICAgICBudW1BdWRpb1RyYWNrcy0tO1xuICAgICAgfVxuICAgICAgaWYgKG51bVZpZGVvVHJhY2tzID4gMCkge1xuICAgICAgICB0aGlzLl9jcmVhdGVUcmFuc2NlaXZlcigndmlkZW8nKTtcbiAgICAgICAgbnVtVmlkZW9UcmFja3MtLTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB2YXIgc2RwID0gU0RQVXRpbHMud3JpdGVTZXNzaW9uQm9pbGVycGxhdGUodGhpcy5fc2RwU2Vzc2lvbklkLFxuICAgICAgICB0aGlzLl9zZHBTZXNzaW9uVmVyc2lvbisrKTtcbiAgICB0aGlzLnRyYW5zY2VpdmVycy5mb3JFYWNoKGZ1bmN0aW9uKHRyYW5zY2VpdmVyLCBzZHBNTGluZUluZGV4KSB7XG4gICAgICAvLyBGb3IgZWFjaCB0cmFjaywgY3JlYXRlIGFuIGljZSBnYXRoZXJlciwgaWNlIHRyYW5zcG9ydCxcbiAgICAgIC8vIGR0bHMgdHJhbnNwb3J0LCBwb3RlbnRpYWxseSBydHBzZW5kZXIgYW5kIHJ0cHJlY2VpdmVyLlxuICAgICAgdmFyIHRyYWNrID0gdHJhbnNjZWl2ZXIudHJhY2s7XG4gICAgICB2YXIga2luZCA9IHRyYW5zY2VpdmVyLmtpbmQ7XG4gICAgICB2YXIgbWlkID0gU0RQVXRpbHMuZ2VuZXJhdGVJZGVudGlmaWVyKCk7XG4gICAgICB0cmFuc2NlaXZlci5taWQgPSBtaWQ7XG5cbiAgICAgIGlmICghdHJhbnNjZWl2ZXIuaWNlR2F0aGVyZXIpIHtcbiAgICAgICAgdHJhbnNjZWl2ZXIuaWNlR2F0aGVyZXIgPSBzZWxmLl9jcmVhdGVJY2VHYXRoZXJlcihzZHBNTGluZUluZGV4LFxuICAgICAgICAgICAgc2VsZi51c2luZ0J1bmRsZSk7XG4gICAgICB9XG5cbiAgICAgIHZhciBsb2NhbENhcGFiaWxpdGllcyA9IHdpbmRvdy5SVENSdHBTZW5kZXIuZ2V0Q2FwYWJpbGl0aWVzKGtpbmQpO1xuICAgICAgLy8gZmlsdGVyIFJUWCB1bnRpbCBhZGRpdGlvbmFsIHN0dWZmIG5lZWRlZCBmb3IgUlRYIGlzIGltcGxlbWVudGVkXG4gICAgICAvLyBpbiBhZGFwdGVyLmpzXG4gICAgICBpZiAoZWRnZVZlcnNpb24gPCAxNTAxOSkge1xuICAgICAgICBsb2NhbENhcGFiaWxpdGllcy5jb2RlY3MgPSBsb2NhbENhcGFiaWxpdGllcy5jb2RlY3MuZmlsdGVyKFxuICAgICAgICAgICAgZnVuY3Rpb24oY29kZWMpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIGNvZGVjLm5hbWUgIT09ICdydHgnO1xuICAgICAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICBsb2NhbENhcGFiaWxpdGllcy5jb2RlY3MuZm9yRWFjaChmdW5jdGlvbihjb2RlYykge1xuICAgICAgICAvLyB3b3JrIGFyb3VuZCBodHRwczovL2J1Z3MuY2hyb21pdW0ub3JnL3Avd2VicnRjL2lzc3Vlcy9kZXRhaWw/aWQ9NjU1MlxuICAgICAgICAvLyBieSBhZGRpbmcgbGV2ZWwtYXN5bW1ldHJ5LWFsbG93ZWQ9MVxuICAgICAgICBpZiAoY29kZWMubmFtZSA9PT0gJ0gyNjQnICYmXG4gICAgICAgICAgICBjb2RlYy5wYXJhbWV0ZXJzWydsZXZlbC1hc3ltbWV0cnktYWxsb3dlZCddID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICBjb2RlYy5wYXJhbWV0ZXJzWydsZXZlbC1hc3ltbWV0cnktYWxsb3dlZCddID0gJzEnO1xuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgLy8gZ2VuZXJhdGUgYW4gc3NyYyBub3csIHRvIGJlIHVzZWQgbGF0ZXIgaW4gcnRwU2VuZGVyLnNlbmRcbiAgICAgIHZhciBzZW5kRW5jb2RpbmdQYXJhbWV0ZXJzID0gdHJhbnNjZWl2ZXIuc2VuZEVuY29kaW5nUGFyYW1ldGVycyB8fCBbe1xuICAgICAgICBzc3JjOiAoMiAqIHNkcE1MaW5lSW5kZXggKyAxKSAqIDEwMDFcbiAgICAgIH1dO1xuICAgICAgaWYgKHRyYWNrKSB7XG4gICAgICAgIC8vIGFkZCBSVFhcbiAgICAgICAgaWYgKGVkZ2VWZXJzaW9uID49IDE1MDE5ICYmIGtpbmQgPT09ICd2aWRlbycgJiZcbiAgICAgICAgICAgICFzZW5kRW5jb2RpbmdQYXJhbWV0ZXJzWzBdLnJ0eCkge1xuICAgICAgICAgIHNlbmRFbmNvZGluZ1BhcmFtZXRlcnNbMF0ucnR4ID0ge1xuICAgICAgICAgICAgc3NyYzogc2VuZEVuY29kaW5nUGFyYW1ldGVyc1swXS5zc3JjICsgMVxuICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKHRyYW5zY2VpdmVyLndhbnRSZWNlaXZlKSB7XG4gICAgICAgIHRyYW5zY2VpdmVyLnJ0cFJlY2VpdmVyID0gbmV3IHdpbmRvdy5SVENSdHBSZWNlaXZlcihcbiAgICAgICAgICAgIHRyYW5zY2VpdmVyLmR0bHNUcmFuc3BvcnQsIGtpbmQpO1xuICAgICAgfVxuXG4gICAgICB0cmFuc2NlaXZlci5sb2NhbENhcGFiaWxpdGllcyA9IGxvY2FsQ2FwYWJpbGl0aWVzO1xuICAgICAgdHJhbnNjZWl2ZXIuc2VuZEVuY29kaW5nUGFyYW1ldGVycyA9IHNlbmRFbmNvZGluZ1BhcmFtZXRlcnM7XG4gICAgfSk7XG5cbiAgICAvLyBhbHdheXMgb2ZmZXIgQlVORExFIGFuZCBkaXNwb3NlIG9uIHJldHVybiBpZiBub3Qgc3VwcG9ydGVkLlxuICAgIGlmICh0aGlzLl9jb25maWcuYnVuZGxlUG9saWN5ICE9PSAnbWF4LWNvbXBhdCcpIHtcbiAgICAgIHNkcCArPSAnYT1ncm91cDpCVU5ETEUgJyArIHRoaXMudHJhbnNjZWl2ZXJzLm1hcChmdW5jdGlvbih0KSB7XG4gICAgICAgIHJldHVybiB0Lm1pZDtcbiAgICAgIH0pLmpvaW4oJyAnKSArICdcXHJcXG4nO1xuICAgIH1cbiAgICBzZHAgKz0gJ2E9aWNlLW9wdGlvbnM6dHJpY2tsZVxcclxcbic7XG5cbiAgICB0aGlzLnRyYW5zY2VpdmVycy5mb3JFYWNoKGZ1bmN0aW9uKHRyYW5zY2VpdmVyLCBzZHBNTGluZUluZGV4KSB7XG4gICAgICBzZHAgKz0gd3JpdGVNZWRpYVNlY3Rpb24odHJhbnNjZWl2ZXIsIHRyYW5zY2VpdmVyLmxvY2FsQ2FwYWJpbGl0aWVzLFxuICAgICAgICAgICdvZmZlcicsIHRyYW5zY2VpdmVyLnN0cmVhbSwgc2VsZi5fZHRsc1JvbGUpO1xuICAgICAgc2RwICs9ICdhPXJ0Y3AtcnNpemVcXHJcXG4nO1xuXG4gICAgICBpZiAodHJhbnNjZWl2ZXIuaWNlR2F0aGVyZXIgJiYgc2VsZi5pY2VHYXRoZXJpbmdTdGF0ZSAhPT0gJ25ldycgJiZcbiAgICAgICAgICAoc2RwTUxpbmVJbmRleCA9PT0gMCB8fCAhc2VsZi51c2luZ0J1bmRsZSkpIHtcbiAgICAgICAgdHJhbnNjZWl2ZXIuaWNlR2F0aGVyZXIuZ2V0TG9jYWxDYW5kaWRhdGVzKCkuZm9yRWFjaChmdW5jdGlvbihjYW5kKSB7XG4gICAgICAgICAgY2FuZC5jb21wb25lbnQgPSAxO1xuICAgICAgICAgIHNkcCArPSAnYT0nICsgU0RQVXRpbHMud3JpdGVDYW5kaWRhdGUoY2FuZCkgKyAnXFxyXFxuJztcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaWYgKHRyYW5zY2VpdmVyLmljZUdhdGhlcmVyLnN0YXRlID09PSAnY29tcGxldGVkJykge1xuICAgICAgICAgIHNkcCArPSAnYT1lbmQtb2YtY2FuZGlkYXRlc1xcclxcbic7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcblxuICAgIHZhciBkZXNjID0gbmV3IHdpbmRvdy5SVENTZXNzaW9uRGVzY3JpcHRpb24oe1xuICAgICAgdHlwZTogJ29mZmVyJyxcbiAgICAgIHNkcDogc2RwXG4gICAgfSk7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uKHJlc29sdmUpIHtcbiAgICAgIGlmIChhcmdzLmxlbmd0aCA+IDAgJiYgdHlwZW9mIGFyZ3NbMF0gPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgYXJnc1swXS5hcHBseShudWxsLCBbZGVzY10pO1xuICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHJlc29sdmUoZGVzYyk7XG4gICAgfSk7XG4gIH07XG5cbiAgUlRDUGVlckNvbm5lY3Rpb24ucHJvdG90eXBlLmNyZWF0ZUFuc3dlciA9IGZ1bmN0aW9uKCkge1xuICAgIHZhciBzZWxmID0gdGhpcztcbiAgICB2YXIgYXJncyA9IGFyZ3VtZW50cztcblxuICAgIHZhciBzZHAgPSBTRFBVdGlscy53cml0ZVNlc3Npb25Cb2lsZXJwbGF0ZSh0aGlzLl9zZHBTZXNzaW9uSWQsXG4gICAgICAgIHRoaXMuX3NkcFNlc3Npb25WZXJzaW9uKyspO1xuICAgIGlmICh0aGlzLnVzaW5nQnVuZGxlKSB7XG4gICAgICBzZHAgKz0gJ2E9Z3JvdXA6QlVORExFICcgKyB0aGlzLnRyYW5zY2VpdmVycy5tYXAoZnVuY3Rpb24odCkge1xuICAgICAgICByZXR1cm4gdC5taWQ7XG4gICAgICB9KS5qb2luKCcgJykgKyAnXFxyXFxuJztcbiAgICB9XG4gICAgdmFyIG1lZGlhU2VjdGlvbnNJbk9mZmVyID0gU0RQVXRpbHMuc3BsaXRTZWN0aW9ucyhcbiAgICAgICAgdGhpcy5yZW1vdGVEZXNjcmlwdGlvbi5zZHApLmxlbmd0aCAtIDE7XG4gICAgdGhpcy50cmFuc2NlaXZlcnMuZm9yRWFjaChmdW5jdGlvbih0cmFuc2NlaXZlciwgc2RwTUxpbmVJbmRleCkge1xuICAgICAgaWYgKHNkcE1MaW5lSW5kZXggKyAxID4gbWVkaWFTZWN0aW9uc0luT2ZmZXIpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgaWYgKHRyYW5zY2VpdmVyLmlzRGF0YWNoYW5uZWwpIHtcbiAgICAgICAgc2RwICs9ICdtPWFwcGxpY2F0aW9uIDAgRFRMUy9TQ1RQIDUwMDBcXHJcXG4nICtcbiAgICAgICAgICAgICdjPUlOIElQNCAwLjAuMC4wXFxyXFxuJyArXG4gICAgICAgICAgICAnYT1taWQ6JyArIHRyYW5zY2VpdmVyLm1pZCArICdcXHJcXG4nO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIC8vIEZJWE1FOiBsb29rIGF0IGRpcmVjdGlvbi5cbiAgICAgIGlmICh0cmFuc2NlaXZlci5zdHJlYW0pIHtcbiAgICAgICAgdmFyIGxvY2FsVHJhY2s7XG4gICAgICAgIGlmICh0cmFuc2NlaXZlci5raW5kID09PSAnYXVkaW8nKSB7XG4gICAgICAgICAgbG9jYWxUcmFjayA9IHRyYW5zY2VpdmVyLnN0cmVhbS5nZXRBdWRpb1RyYWNrcygpWzBdO1xuICAgICAgICB9IGVsc2UgaWYgKHRyYW5zY2VpdmVyLmtpbmQgPT09ICd2aWRlbycpIHtcbiAgICAgICAgICBsb2NhbFRyYWNrID0gdHJhbnNjZWl2ZXIuc3RyZWFtLmdldFZpZGVvVHJhY2tzKClbMF07XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGxvY2FsVHJhY2spIHtcbiAgICAgICAgICAvLyBhZGQgUlRYXG4gICAgICAgICAgaWYgKGVkZ2VWZXJzaW9uID49IDE1MDE5ICYmIHRyYW5zY2VpdmVyLmtpbmQgPT09ICd2aWRlbycgJiZcbiAgICAgICAgICAgICAgIXRyYW5zY2VpdmVyLnNlbmRFbmNvZGluZ1BhcmFtZXRlcnNbMF0ucnR4KSB7XG4gICAgICAgICAgICB0cmFuc2NlaXZlci5zZW5kRW5jb2RpbmdQYXJhbWV0ZXJzWzBdLnJ0eCA9IHtcbiAgICAgICAgICAgICAgc3NyYzogdHJhbnNjZWl2ZXIuc2VuZEVuY29kaW5nUGFyYW1ldGVyc1swXS5zc3JjICsgMVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gQ2FsY3VsYXRlIGludGVyc2VjdGlvbiBvZiBjYXBhYmlsaXRpZXMuXG4gICAgICB2YXIgY29tbW9uQ2FwYWJpbGl0aWVzID0gZ2V0Q29tbW9uQ2FwYWJpbGl0aWVzKFxuICAgICAgICAgIHRyYW5zY2VpdmVyLmxvY2FsQ2FwYWJpbGl0aWVzLFxuICAgICAgICAgIHRyYW5zY2VpdmVyLnJlbW90ZUNhcGFiaWxpdGllcyk7XG5cbiAgICAgIHZhciBoYXNSdHggPSBjb21tb25DYXBhYmlsaXRpZXMuY29kZWNzLmZpbHRlcihmdW5jdGlvbihjKSB7XG4gICAgICAgIHJldHVybiBjLm5hbWUudG9Mb3dlckNhc2UoKSA9PT0gJ3J0eCc7XG4gICAgICB9KS5sZW5ndGg7XG4gICAgICBpZiAoIWhhc1J0eCAmJiB0cmFuc2NlaXZlci5zZW5kRW5jb2RpbmdQYXJhbWV0ZXJzWzBdLnJ0eCkge1xuICAgICAgICBkZWxldGUgdHJhbnNjZWl2ZXIuc2VuZEVuY29kaW5nUGFyYW1ldGVyc1swXS5ydHg7XG4gICAgICB9XG5cbiAgICAgIHNkcCArPSB3cml0ZU1lZGlhU2VjdGlvbih0cmFuc2NlaXZlciwgY29tbW9uQ2FwYWJpbGl0aWVzLFxuICAgICAgICAgICdhbnN3ZXInLCB0cmFuc2NlaXZlci5zdHJlYW0sIHNlbGYuX2R0bHNSb2xlKTtcbiAgICAgIGlmICh0cmFuc2NlaXZlci5ydGNwUGFyYW1ldGVycyAmJlxuICAgICAgICAgIHRyYW5zY2VpdmVyLnJ0Y3BQYXJhbWV0ZXJzLnJlZHVjZWRTaXplKSB7XG4gICAgICAgIHNkcCArPSAnYT1ydGNwLXJzaXplXFxyXFxuJztcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIHZhciBkZXNjID0gbmV3IHdpbmRvdy5SVENTZXNzaW9uRGVzY3JpcHRpb24oe1xuICAgICAgdHlwZTogJ2Fuc3dlcicsXG4gICAgICBzZHA6IHNkcFxuICAgIH0pO1xuICAgIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbihyZXNvbHZlKSB7XG4gICAgICBpZiAoYXJncy5sZW5ndGggPiAwICYmIHR5cGVvZiBhcmdzWzBdID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIGFyZ3NbMF0uYXBwbHkobnVsbCwgW2Rlc2NdKTtcbiAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICByZXNvbHZlKGRlc2MpO1xuICAgIH0pO1xuICB9O1xuXG4gIFJUQ1BlZXJDb25uZWN0aW9uLnByb3RvdHlwZS5hZGRJY2VDYW5kaWRhdGUgPSBmdW5jdGlvbihjYW5kaWRhdGUpIHtcbiAgICB2YXIgZXJyO1xuICAgIHZhciBzZWN0aW9ucztcbiAgICBpZiAoIWNhbmRpZGF0ZSB8fCBjYW5kaWRhdGUuY2FuZGlkYXRlID09PSAnJykge1xuICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCB0aGlzLnRyYW5zY2VpdmVycy5sZW5ndGg7IGorKykge1xuICAgICAgICBpZiAodGhpcy50cmFuc2NlaXZlcnNbal0uaXNEYXRhY2hhbm5lbCkge1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMudHJhbnNjZWl2ZXJzW2pdLmljZVRyYW5zcG9ydC5hZGRSZW1vdGVDYW5kaWRhdGUoe30pO1xuICAgICAgICBzZWN0aW9ucyA9IFNEUFV0aWxzLnNwbGl0U2VjdGlvbnModGhpcy5yZW1vdGVEZXNjcmlwdGlvbi5zZHApO1xuICAgICAgICBzZWN0aW9uc1tqICsgMV0gKz0gJ2E9ZW5kLW9mLWNhbmRpZGF0ZXNcXHJcXG4nO1xuICAgICAgICB0aGlzLnJlbW90ZURlc2NyaXB0aW9uLnNkcCA9IHNlY3Rpb25zLmpvaW4oJycpO1xuICAgICAgICBpZiAodGhpcy51c2luZ0J1bmRsZSkge1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIGlmICghKGNhbmRpZGF0ZS5zZHBNTGluZUluZGV4ICE9PSB1bmRlZmluZWQgfHwgY2FuZGlkYXRlLnNkcE1pZCkpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ3NkcE1MaW5lSW5kZXggb3Igc2RwTWlkIHJlcXVpcmVkJyk7XG4gICAgfSBlbHNlIGlmICghdGhpcy5yZW1vdGVEZXNjcmlwdGlvbikge1xuICAgICAgZXJyID0gbmV3IEVycm9yKCdDYW4gbm90IGFkZCBJQ0UgY2FuZGlkYXRlIHdpdGhvdXQgJyArXG4gICAgICAgICAgJ2EgcmVtb3RlIGRlc2NyaXB0aW9uJyk7XG4gICAgICBlcnIubmFtZSA9ICdJbnZhbGlkU3RhdGVFcnJvcic7XG4gICAgfSBlbHNlIHtcbiAgICAgIHZhciBzZHBNTGluZUluZGV4ID0gY2FuZGlkYXRlLnNkcE1MaW5lSW5kZXg7XG4gICAgICBpZiAoY2FuZGlkYXRlLnNkcE1pZCkge1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMudHJhbnNjZWl2ZXJzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgaWYgKHRoaXMudHJhbnNjZWl2ZXJzW2ldLm1pZCA9PT0gY2FuZGlkYXRlLnNkcE1pZCkge1xuICAgICAgICAgICAgc2RwTUxpbmVJbmRleCA9IGk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHZhciB0cmFuc2NlaXZlciA9IHRoaXMudHJhbnNjZWl2ZXJzW3NkcE1MaW5lSW5kZXhdO1xuICAgICAgaWYgKHRyYW5zY2VpdmVyKSB7XG4gICAgICAgIGlmICh0cmFuc2NlaXZlci5pc0RhdGFjaGFubmVsKSB7XG4gICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICAgICAgICB9XG4gICAgICAgIHZhciBjYW5kID0gT2JqZWN0LmtleXMoY2FuZGlkYXRlLmNhbmRpZGF0ZSkubGVuZ3RoID4gMCA/XG4gICAgICAgICAgICBTRFBVdGlscy5wYXJzZUNhbmRpZGF0ZShjYW5kaWRhdGUuY2FuZGlkYXRlKSA6IHt9O1xuICAgICAgICAvLyBJZ25vcmUgQ2hyb21lJ3MgaW52YWxpZCBjYW5kaWRhdGVzIHNpbmNlIEVkZ2UgZG9lcyBub3QgbGlrZSB0aGVtLlxuICAgICAgICBpZiAoY2FuZC5wcm90b2NvbCA9PT0gJ3RjcCcgJiYgKGNhbmQucG9ydCA9PT0gMCB8fCBjYW5kLnBvcnQgPT09IDkpKSB7XG4gICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICAgICAgICB9XG4gICAgICAgIC8vIElnbm9yZSBSVENQIGNhbmRpZGF0ZXMsIHdlIGFzc3VtZSBSVENQLU1VWC5cbiAgICAgICAgaWYgKGNhbmQuY29tcG9uZW50ICYmIGNhbmQuY29tcG9uZW50ICE9PSAxKSB7XG4gICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICAgICAgICB9XG4gICAgICAgIC8vIHdoZW4gdXNpbmcgYnVuZGxlLCBhdm9pZCBhZGRpbmcgY2FuZGlkYXRlcyB0byB0aGUgd3JvbmdcbiAgICAgICAgLy8gaWNlIHRyYW5zcG9ydC4gQW5kIGF2b2lkIGFkZGluZyBjYW5kaWRhdGVzIGFkZGVkIGluIHRoZSBTRFAuXG4gICAgICAgIGlmIChzZHBNTGluZUluZGV4ID09PSAwIHx8IChzZHBNTGluZUluZGV4ID4gMCAmJlxuICAgICAgICAgICAgdHJhbnNjZWl2ZXIuaWNlVHJhbnNwb3J0ICE9PSB0aGlzLnRyYW5zY2VpdmVyc1swXS5pY2VUcmFuc3BvcnQpKSB7XG4gICAgICAgICAgaWYgKCFtYXliZUFkZENhbmRpZGF0ZSh0cmFuc2NlaXZlci5pY2VUcmFuc3BvcnQsIGNhbmQpKSB7XG4gICAgICAgICAgICBlcnIgPSBuZXcgRXJyb3IoJ0NhbiBub3QgYWRkIElDRSBjYW5kaWRhdGUnKTtcbiAgICAgICAgICAgIGVyci5uYW1lID0gJ09wZXJhdGlvbkVycm9yJztcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIWVycikge1xuICAgICAgICAgIC8vIHVwZGF0ZSB0aGUgcmVtb3RlRGVzY3JpcHRpb24uXG4gICAgICAgICAgdmFyIGNhbmRpZGF0ZVN0cmluZyA9IGNhbmRpZGF0ZS5jYW5kaWRhdGUudHJpbSgpO1xuICAgICAgICAgIGlmIChjYW5kaWRhdGVTdHJpbmcuaW5kZXhPZignYT0nKSA9PT0gMCkge1xuICAgICAgICAgICAgY2FuZGlkYXRlU3RyaW5nID0gY2FuZGlkYXRlU3RyaW5nLnN1YnN0cigyKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgc2VjdGlvbnMgPSBTRFBVdGlscy5zcGxpdFNlY3Rpb25zKHRoaXMucmVtb3RlRGVzY3JpcHRpb24uc2RwKTtcbiAgICAgICAgICBzZWN0aW9uc1tzZHBNTGluZUluZGV4ICsgMV0gKz0gJ2E9JyArXG4gICAgICAgICAgICAgIChjYW5kLnR5cGUgPyBjYW5kaWRhdGVTdHJpbmcgOiAnZW5kLW9mLWNhbmRpZGF0ZXMnKVxuICAgICAgICAgICAgICArICdcXHJcXG4nO1xuICAgICAgICAgIHRoaXMucmVtb3RlRGVzY3JpcHRpb24uc2RwID0gc2VjdGlvbnMuam9pbignJyk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGVyciA9IG5ldyBFcnJvcignQ2FuIG5vdCBhZGQgSUNFIGNhbmRpZGF0ZScpO1xuICAgICAgICBlcnIubmFtZSA9ICdPcGVyYXRpb25FcnJvcic7XG4gICAgICB9XG4gICAgfVxuICAgIHZhciBhcmdzID0gYXJndW1lbnRzO1xuICAgIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbihyZXNvbHZlLCByZWplY3QpIHtcbiAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgaWYgKGFyZ3MubGVuZ3RoID4gMiAmJiB0eXBlb2YgYXJnc1syXSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgIGFyZ3NbMl0uYXBwbHkobnVsbCwgW2Vycl0pO1xuICAgICAgICB9XG4gICAgICAgIHJlamVjdChlcnIpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKGFyZ3MubGVuZ3RoID4gMSAmJiB0eXBlb2YgYXJnc1sxXSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgIGFyZ3NbMV0uYXBwbHkobnVsbCk7XG4gICAgICAgIH1cbiAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgfVxuICAgIH0pO1xuICB9O1xuXG4gIFJUQ1BlZXJDb25uZWN0aW9uLnByb3RvdHlwZS5nZXRTdGF0cyA9IGZ1bmN0aW9uKCkge1xuICAgIHZhciBwcm9taXNlcyA9IFtdO1xuICAgIHRoaXMudHJhbnNjZWl2ZXJzLmZvckVhY2goZnVuY3Rpb24odHJhbnNjZWl2ZXIpIHtcbiAgICAgIFsncnRwU2VuZGVyJywgJ3J0cFJlY2VpdmVyJywgJ2ljZUdhdGhlcmVyJywgJ2ljZVRyYW5zcG9ydCcsXG4gICAgICAgICAgJ2R0bHNUcmFuc3BvcnQnXS5mb3JFYWNoKGZ1bmN0aW9uKG1ldGhvZCkge1xuICAgICAgICAgICAgaWYgKHRyYW5zY2VpdmVyW21ldGhvZF0pIHtcbiAgICAgICAgICAgICAgcHJvbWlzZXMucHVzaCh0cmFuc2NlaXZlclttZXRob2RdLmdldFN0YXRzKCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pO1xuICAgIH0pO1xuICAgIHZhciBjYiA9IGFyZ3VtZW50cy5sZW5ndGggPiAxICYmIHR5cGVvZiBhcmd1bWVudHNbMV0gPT09ICdmdW5jdGlvbicgJiZcbiAgICAgICAgYXJndW1lbnRzWzFdO1xuICAgIHZhciBmaXhTdGF0c1R5cGUgPSBmdW5jdGlvbihzdGF0KSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBpbmJvdW5kcnRwOiAnaW5ib3VuZC1ydHAnLFxuICAgICAgICBvdXRib3VuZHJ0cDogJ291dGJvdW5kLXJ0cCcsXG4gICAgICAgIGNhbmRpZGF0ZXBhaXI6ICdjYW5kaWRhdGUtcGFpcicsXG4gICAgICAgIGxvY2FsY2FuZGlkYXRlOiAnbG9jYWwtY2FuZGlkYXRlJyxcbiAgICAgICAgcmVtb3RlY2FuZGlkYXRlOiAncmVtb3RlLWNhbmRpZGF0ZSdcbiAgICAgIH1bc3RhdC50eXBlXSB8fCBzdGF0LnR5cGU7XG4gICAgfTtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24ocmVzb2x2ZSkge1xuICAgICAgLy8gc2hpbSBnZXRTdGF0cyB3aXRoIG1hcGxpa2Ugc3VwcG9ydFxuICAgICAgdmFyIHJlc3VsdHMgPSBuZXcgTWFwKCk7XG4gICAgICBQcm9taXNlLmFsbChwcm9taXNlcykudGhlbihmdW5jdGlvbihyZXMpIHtcbiAgICAgICAgcmVzLmZvckVhY2goZnVuY3Rpb24ocmVzdWx0KSB7XG4gICAgICAgICAgT2JqZWN0LmtleXMocmVzdWx0KS5mb3JFYWNoKGZ1bmN0aW9uKGlkKSB7XG4gICAgICAgICAgICByZXN1bHRbaWRdLnR5cGUgPSBmaXhTdGF0c1R5cGUocmVzdWx0W2lkXSk7XG4gICAgICAgICAgICByZXN1bHRzLnNldChpZCwgcmVzdWx0W2lkXSk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgICAgICBpZiAoY2IpIHtcbiAgICAgICAgICBjYi5hcHBseShudWxsLCByZXN1bHRzKTtcbiAgICAgICAgfVxuICAgICAgICByZXNvbHZlKHJlc3VsdHMpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH07XG4gIHJldHVybiBSVENQZWVyQ29ubmVjdGlvbjtcbn07XG4iLCJ2YXIgZ3JhbW1hciA9IG1vZHVsZS5leHBvcnRzID0ge1xuICB2OiBbe1xuICAgICAgbmFtZTogJ3ZlcnNpb24nLFxuICAgICAgcmVnOiAvXihcXGQqKSQvXG4gIH1dLFxuICBvOiBbeyAvL289LSAyMDUxOCAwIElOIElQNCAyMDMuMC4xMTMuMVxuICAgIC8vIE5COiBzZXNzaW9uSWQgd2lsbCBiZSBhIFN0cmluZyBpbiBtb3N0IGNhc2VzIGJlY2F1c2UgaXQgaXMgaHVnZVxuICAgIG5hbWU6ICdvcmlnaW4nLFxuICAgIHJlZzogL14oXFxTKikgKFxcZCopIChcXGQqKSAoXFxTKikgSVAoXFxkKSAoXFxTKikvLFxuICAgIG5hbWVzOiBbJ3VzZXJuYW1lJywgJ3Nlc3Npb25JZCcsICdzZXNzaW9uVmVyc2lvbicsICduZXRUeXBlJywgJ2lwVmVyJywgJ2FkZHJlc3MnXSxcbiAgICBmb3JtYXQ6IFwiJXMgJXMgJWQgJXMgSVAlZCAlc1wiXG4gIH1dLFxuICAvLyBkZWZhdWx0IHBhcnNpbmcgb2YgdGhlc2Ugb25seSAodGhvdWdoIHNvbWUgb2YgdGhlc2UgZmVlbCBvdXRkYXRlZClcbiAgczogW3sgbmFtZTogJ25hbWUnIH1dLFxuICBpOiBbeyBuYW1lOiAnZGVzY3JpcHRpb24nIH1dLFxuICB1OiBbeyBuYW1lOiAndXJpJyB9XSxcbiAgZTogW3sgbmFtZTogJ2VtYWlsJyB9XSxcbiAgcDogW3sgbmFtZTogJ3Bob25lJyB9XSxcbiAgejogW3sgbmFtZTogJ3RpbWV6b25lcycgfV0sIC8vIFRPRE86IHRoaXMgb25lIGNhbiBhY3R1YWxseSBiZSBwYXJzZWQgcHJvcGVybHkuLlxuICByOiBbeyBuYW1lOiAncmVwZWF0cycgfV0sICAgLy8gVE9ETzogdGhpcyBvbmUgY2FuIGFsc28gYmUgcGFyc2VkIHByb3Blcmx5XG4gIC8vazogW3t9XSwgLy8gb3V0ZGF0ZWQgdGhpbmcgaWdub3JlZFxuICB0OiBbeyAvL3Q9MCAwXG4gICAgbmFtZTogJ3RpbWluZycsXG4gICAgcmVnOiAvXihcXGQqKSAoXFxkKikvLFxuICAgIG5hbWVzOiBbJ3N0YXJ0JywgJ3N0b3AnXSxcbiAgICBmb3JtYXQ6IFwiJWQgJWRcIlxuICB9XSxcbiAgYzogW3sgLy9jPUlOIElQNCAxMC40Ny4xOTcuMjZcbiAgICAgIG5hbWU6ICdjb25uZWN0aW9uJyxcbiAgICAgIHJlZzogL15JTiBJUChcXGQpIChcXFMqKS8sXG4gICAgICBuYW1lczogWyd2ZXJzaW9uJywgJ2lwJ10sXG4gICAgICBmb3JtYXQ6IFwiSU4gSVAlZCAlc1wiXG4gIH1dLFxuICBiOiBbeyAvL2I9QVM6NDAwMFxuICAgICAgcHVzaDogJ2JhbmR3aWR0aCcsXG4gICAgICByZWc6IC9eKFRJQVN8QVN8Q1R8UlJ8UlMpOihcXGQqKS8sXG4gICAgICBuYW1lczogWyd0eXBlJywgJ2xpbWl0J10sXG4gICAgICBmb3JtYXQ6IFwiJXM6JXNcIlxuICB9XSxcbiAgbTogW3sgLy9tPXZpZGVvIDUxNzQ0IFJUUC9BVlAgMTI2IDk3IDk4IDM0IDMxXG4gICAgICAvLyBOQjogc3BlY2lhbCAtIHB1c2hlcyB0byBzZXNzaW9uXG4gICAgICAvLyBUT0RPOiBydHAvZm10cCBzaG91bGQgYmUgZmlsdGVyZWQgYnkgdGhlIHBheWxvYWRzIGZvdW5kIGhlcmU/XG4gICAgICByZWc6IC9eKFxcdyopIChcXGQqKSAoW1xcd1xcL10qKSg/OiAoLiopKT8vLFxuICAgICAgbmFtZXM6IFsndHlwZScsICdwb3J0JywgJ3Byb3RvY29sJywgJ3BheWxvYWRzJ10sXG4gICAgICBmb3JtYXQ6IFwiJXMgJWQgJXMgJXNcIlxuICB9XSxcbiAgYTogW1xuICAgIHsgLy9hPXJ0cG1hcDoxMTAgb3B1cy80ODAwMC8yXG4gICAgICBwdXNoOiAncnRwJyxcbiAgICAgIHJlZzogL15ydHBtYXA6KFxcZCopIChbXFx3XFwtXSopKD86XFxzKlxcLyhcXGQqKSg/OlxccypcXC8oXFxTKikpPyk/LyxcbiAgICAgIG5hbWVzOiBbJ3BheWxvYWQnLCAnY29kZWMnLCAncmF0ZScsICdlbmNvZGluZyddLFxuICAgICAgZm9ybWF0OiBmdW5jdGlvbiAobykge1xuICAgICAgICByZXR1cm4gKG8uZW5jb2RpbmcpID9cbiAgICAgICAgICBcInJ0cG1hcDolZCAlcy8lcy8lc1wiOlxuICAgICAgICAgIG8ucmF0ZSA/XG4gICAgICAgICAgXCJydHBtYXA6JWQgJXMvJXNcIjpcbiAgICAgICAgICBcInJ0cG1hcDolZCAlc1wiO1xuICAgICAgfVxuICAgIH0sXG4gICAge1xuICAgICAgLy9hPWZtdHA6MTA4IHByb2ZpbGUtbGV2ZWwtaWQ9MjQ7b2JqZWN0PTIzO2JpdHJhdGU9NjQwMDBcbiAgICAgIC8vYT1mbXRwOjExMSBtaW5wdGltZT0xMDsgdXNlaW5iYW5kZmVjPTFcbiAgICAgIHB1c2g6ICdmbXRwJyxcbiAgICAgIHJlZzogL15mbXRwOihcXGQqKSAoW1xcU3wgXSopLyxcbiAgICAgIG5hbWVzOiBbJ3BheWxvYWQnLCAnY29uZmlnJ10sXG4gICAgICBmb3JtYXQ6IFwiZm10cDolZCAlc1wiXG4gICAgfSxcbiAgICB7IC8vYT1jb250cm9sOnN0cmVhbWlkPTBcbiAgICAgICAgbmFtZTogJ2NvbnRyb2wnLFxuICAgICAgICByZWc6IC9eY29udHJvbDooLiopLyxcbiAgICAgICAgZm9ybWF0OiBcImNvbnRyb2w6JXNcIlxuICAgIH0sXG4gICAgeyAvL2E9cnRjcDo2NTE3OSBJTiBJUDQgMTkzLjg0Ljc3LjE5NFxuICAgICAgbmFtZTogJ3J0Y3AnLFxuICAgICAgcmVnOiAvXnJ0Y3A6KFxcZCopKD86IChcXFMqKSBJUChcXGQpIChcXFMqKSk/LyxcbiAgICAgIG5hbWVzOiBbJ3BvcnQnLCAnbmV0VHlwZScsICdpcFZlcicsICdhZGRyZXNzJ10sXG4gICAgICBmb3JtYXQ6IGZ1bmN0aW9uIChvKSB7XG4gICAgICAgIHJldHVybiAoby5hZGRyZXNzICE9IG51bGwpID9cbiAgICAgICAgICBcInJ0Y3A6JWQgJXMgSVAlZCAlc1wiOlxuICAgICAgICAgIFwicnRjcDolZFwiO1xuICAgICAgfVxuICAgIH0sXG4gICAgeyAvL2E9cnRjcC1mYjo5OCB0cnItaW50IDEwMFxuICAgICAgcHVzaDogJ3J0Y3BGYlRyckludCcsXG4gICAgICByZWc6IC9ecnRjcC1mYjooXFwqfFxcZCopIHRyci1pbnQgKFxcZCopLyxcbiAgICAgIG5hbWVzOiBbJ3BheWxvYWQnLCAndmFsdWUnXSxcbiAgICAgIGZvcm1hdDogXCJydGNwLWZiOiVkIHRyci1pbnQgJWRcIlxuICAgIH0sXG4gICAgeyAvL2E9cnRjcC1mYjo5OCBuYWNrIHJwc2lcbiAgICAgIHB1c2g6ICdydGNwRmInLFxuICAgICAgcmVnOiAvXnJ0Y3AtZmI6KFxcKnxcXGQqKSAoW1xcdy1fXSopKD86IChbXFx3LV9dKikpPy8sXG4gICAgICBuYW1lczogWydwYXlsb2FkJywgJ3R5cGUnLCAnc3VidHlwZSddLFxuICAgICAgZm9ybWF0OiBmdW5jdGlvbiAobykge1xuICAgICAgICByZXR1cm4gKG8uc3VidHlwZSAhPSBudWxsKSA/XG4gICAgICAgICAgXCJydGNwLWZiOiVzICVzICVzXCI6XG4gICAgICAgICAgXCJydGNwLWZiOiVzICVzXCI7XG4gICAgICB9XG4gICAgfSxcbiAgICB7IC8vYT1leHRtYXA6MiB1cm46aWV0ZjpwYXJhbXM6cnRwLWhkcmV4dDp0b2Zmc2V0XG4gICAgICAvL2E9ZXh0bWFwOjEvcmVjdm9ubHkgVVJJLWdwcy1zdHJpbmdcbiAgICAgIHB1c2g6ICdleHQnLFxuICAgICAgcmVnOiAvXmV4dG1hcDooW1xcd19cXC9dKikgKFxcUyopKD86IChcXFMqKSk/LyxcbiAgICAgIG5hbWVzOiBbJ3ZhbHVlJywgJ3VyaScsICdjb25maWcnXSwgLy8gdmFsdWUgbWF5IGluY2x1ZGUgXCIvZGlyZWN0aW9uXCIgc3VmZml4XG4gICAgICBmb3JtYXQ6IGZ1bmN0aW9uIChvKSB7XG4gICAgICAgIHJldHVybiAoby5jb25maWcgIT0gbnVsbCkgP1xuICAgICAgICAgIFwiZXh0bWFwOiVzICVzICVzXCI6XG4gICAgICAgICAgXCJleHRtYXA6JXMgJXNcIjtcbiAgICAgIH1cbiAgICB9LFxuICAgIHtcbiAgICAgIC8vYT1jcnlwdG86MSBBRVNfQ01fMTI4X0hNQUNfU0hBMV84MCBpbmxpbmU6UFMxdVFDVmVlQ0ZDYW5WbWNqa3BQeXdqTldoY1lEMG1YWHR4YVZCUnwyXjIwfDE6MzJcbiAgICAgIHB1c2g6ICdjcnlwdG8nLFxuICAgICAgcmVnOiAvXmNyeXB0bzooXFxkKikgKFtcXHdfXSopIChcXFMqKSg/OiAoXFxTKikpPy8sXG4gICAgICBuYW1lczogWydpZCcsICdzdWl0ZScsICdjb25maWcnLCAnc2Vzc2lvbkNvbmZpZyddLFxuICAgICAgZm9ybWF0OiBmdW5jdGlvbiAobykge1xuICAgICAgICByZXR1cm4gKG8uc2Vzc2lvbkNvbmZpZyAhPSBudWxsKSA/XG4gICAgICAgICAgXCJjcnlwdG86JWQgJXMgJXMgJXNcIjpcbiAgICAgICAgICBcImNyeXB0bzolZCAlcyAlc1wiO1xuICAgICAgfVxuICAgIH0sXG4gICAgeyAvL2E9c2V0dXA6YWN0cGFzc1xuICAgICAgbmFtZTogJ3NldHVwJyxcbiAgICAgIHJlZzogL15zZXR1cDooXFx3KikvLFxuICAgICAgZm9ybWF0OiBcInNldHVwOiVzXCJcbiAgICB9LFxuICAgIHsgLy9hPW1pZDoxXG4gICAgICBuYW1lOiAnbWlkJyxcbiAgICAgIHJlZzogL15taWQ6KFteXFxzXSopLyxcbiAgICAgIGZvcm1hdDogXCJtaWQ6JXNcIlxuICAgIH0sXG4gICAgeyAvL2E9bXNpZDowYzhiMDY0ZC1kODA3LTQzYjQtYjQzNC1mOTJhODg5ZDg1ODcgOTgxNzg2ODUtZDQwOS00NmUwLThlMTYtN2VmMGRiMGRiNjRhXG4gICAgICBuYW1lOiAnbXNpZCcsXG4gICAgICByZWc6IC9ebXNpZDooLiopLyxcbiAgICAgIGZvcm1hdDogXCJtc2lkOiVzXCJcbiAgICB9LFxuICAgIHsgLy9hPXB0aW1lOjIwXG4gICAgICBuYW1lOiAncHRpbWUnLFxuICAgICAgcmVnOiAvXnB0aW1lOihcXGQqKS8sXG4gICAgICBmb3JtYXQ6IFwicHRpbWU6JWRcIlxuICAgIH0sXG4gICAgeyAvL2E9bWF4cHRpbWU6NjBcbiAgICAgIG5hbWU6ICdtYXhwdGltZScsXG4gICAgICByZWc6IC9ebWF4cHRpbWU6KFxcZCopLyxcbiAgICAgIGZvcm1hdDogXCJtYXhwdGltZTolZFwiXG4gICAgfSxcbiAgICB7IC8vYT1zZW5kcmVjdlxuICAgICAgbmFtZTogJ2RpcmVjdGlvbicsXG4gICAgICByZWc6IC9eKHNlbmRyZWN2fHJlY3Zvbmx5fHNlbmRvbmx5fGluYWN0aXZlKS9cbiAgICB9LFxuICAgIHsgLy9hPWljZS1saXRlXG4gICAgICBuYW1lOiAnaWNlbGl0ZScsXG4gICAgICByZWc6IC9eKGljZS1saXRlKS9cbiAgICB9LFxuICAgIHsgLy9hPWljZS11ZnJhZzpGN2dJXG4gICAgICBuYW1lOiAnaWNlVWZyYWcnLFxuICAgICAgcmVnOiAvXmljZS11ZnJhZzooXFxTKikvLFxuICAgICAgZm9ybWF0OiBcImljZS11ZnJhZzolc1wiXG4gICAgfSxcbiAgICB7IC8vYT1pY2UtcHdkOng5Y21sL1l6aWNoVjIrWGxoaU11OGdcbiAgICAgIG5hbWU6ICdpY2VQd2QnLFxuICAgICAgcmVnOiAvXmljZS1wd2Q6KFxcUyopLyxcbiAgICAgIGZvcm1hdDogXCJpY2UtcHdkOiVzXCJcbiAgICB9LFxuICAgIHsgLy9hPWZpbmdlcnByaW50OlNIQS0xIDAwOjExOjIyOjMzOjQ0OjU1OjY2Ojc3Ojg4Ojk5OkFBOkJCOkNDOkREOkVFOkZGOjAwOjExOjIyOjMzXG4gICAgICBuYW1lOiAnZmluZ2VycHJpbnQnLFxuICAgICAgcmVnOiAvXmZpbmdlcnByaW50OihcXFMqKSAoXFxTKikvLFxuICAgICAgbmFtZXM6IFsndHlwZScsICdoYXNoJ10sXG4gICAgICBmb3JtYXQ6IFwiZmluZ2VycHJpbnQ6JXMgJXNcIlxuICAgIH0sXG4gICAge1xuICAgICAgLy9hPWNhbmRpZGF0ZTowIDEgVURQIDIxMTM2NjczMjcgMjAzLjAuMTEzLjEgNTQ0MDAgdHlwIGhvc3RcbiAgICAgIC8vYT1jYW5kaWRhdGU6MTE2Mjg3NTA4MSAxIHVkcCAyMTEzOTM3MTUxIDE5Mi4xNjguMzQuNzUgNjAwMTcgdHlwIGhvc3QgZ2VuZXJhdGlvbiAwXG4gICAgICAvL2E9Y2FuZGlkYXRlOjMyODk5MTI5NTcgMiB1ZHAgMTg0NTUwMTY5NSAxOTMuODQuNzcuMTk0IDYwMDE3IHR5cCBzcmZseCByYWRkciAxOTIuMTY4LjM0Ljc1IHJwb3J0IDYwMDE3IGdlbmVyYXRpb24gMFxuICAgICAgLy9hPWNhbmRpZGF0ZToyMjk4MTU2MjAgMSB0Y3AgMTUxODI4MDQ0NyAxOTIuMTY4LjE1MC4xOSA2MDAxNyB0eXAgaG9zdCB0Y3B0eXBlIGFjdGl2ZSBnZW5lcmF0aW9uIDBcbiAgICAgIC8vYT1jYW5kaWRhdGU6MzI4OTkxMjk1NyAyIHRjcCAxODQ1NTAxNjk1IDE5My44NC43Ny4xOTQgNjAwMTcgdHlwIHNyZmx4IHJhZGRyIDE5Mi4xNjguMzQuNzUgcnBvcnQgNjAwMTcgdGNwdHlwZSBwYXNzaXZlIGdlbmVyYXRpb24gMFxuICAgICAgcHVzaDonY2FuZGlkYXRlcycsXG4gICAgICByZWc6IC9eY2FuZGlkYXRlOihcXFMqKSAoXFxkKikgKFxcUyopIChcXGQqKSAoXFxTKikgKFxcZCopIHR5cCAoXFxTKikoPzogcmFkZHIgKFxcUyopIHJwb3J0IChcXGQqKSk/KD86IHRjcHR5cGUgKFxcUyopKT8oPzogZ2VuZXJhdGlvbiAoXFxkKikpPy8sXG4gICAgICBuYW1lczogWydmb3VuZGF0aW9uJywgJ2NvbXBvbmVudCcsICd0cmFuc3BvcnQnLCAncHJpb3JpdHknLCAnaXAnLCAncG9ydCcsICd0eXBlJywgJ3JhZGRyJywgJ3Jwb3J0JywgJ3RjcHR5cGUnLCAnZ2VuZXJhdGlvbiddLFxuICAgICAgZm9ybWF0OiBmdW5jdGlvbiAobykge1xuICAgICAgICB2YXIgc3RyID0gXCJjYW5kaWRhdGU6JXMgJWQgJXMgJWQgJXMgJWQgdHlwICVzXCI7XG5cbiAgICAgICAgc3RyICs9IChvLnJhZGRyICE9IG51bGwpID8gXCIgcmFkZHIgJXMgcnBvcnQgJWRcIiA6IFwiJXYldlwiO1xuXG4gICAgICAgIC8vIE5COiBjYW5kaWRhdGUgaGFzIHRocmVlIG9wdGlvbmFsIGNodW5rcywgc28gJXZvaWQgbWlkZGxlcyBvbmUgaWYgaXQncyBtaXNzaW5nXG4gICAgICAgIHN0ciArPSAoby50Y3B0eXBlICE9IG51bGwpID8gXCIgdGNwdHlwZSAlc1wiIDogXCIldlwiO1xuXG4gICAgICAgIGlmIChvLmdlbmVyYXRpb24gIT0gbnVsbCkge1xuICAgICAgICAgIHN0ciArPSBcIiBnZW5lcmF0aW9uICVkXCI7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHN0cjtcbiAgICAgIH1cbiAgICB9LFxuICAgIHsgLy9hPWVuZC1vZi1jYW5kaWRhdGVzIChrZWVwIGFmdGVyIHRoZSBjYW5kaWRhdGVzIGxpbmUgZm9yIHJlYWRhYmlsaXR5KVxuICAgICAgbmFtZTogJ2VuZE9mQ2FuZGlkYXRlcycsXG4gICAgICByZWc6IC9eKGVuZC1vZi1jYW5kaWRhdGVzKS9cbiAgICB9LFxuICAgIHsgLy9hPXJlbW90ZS1jYW5kaWRhdGVzOjEgMjAzLjAuMTEzLjEgNTQ0MDAgMiAyMDMuMC4xMTMuMSA1NDQwMSAuLi5cbiAgICAgIG5hbWU6ICdyZW1vdGVDYW5kaWRhdGVzJyxcbiAgICAgIHJlZzogL15yZW1vdGUtY2FuZGlkYXRlczooLiopLyxcbiAgICAgIGZvcm1hdDogXCJyZW1vdGUtY2FuZGlkYXRlczolc1wiXG4gICAgfSxcbiAgICB7IC8vYT1pY2Utb3B0aW9uczpnb29nbGUtaWNlXG4gICAgICBuYW1lOiAnaWNlT3B0aW9ucycsXG4gICAgICByZWc6IC9eaWNlLW9wdGlvbnM6KFxcUyopLyxcbiAgICAgIGZvcm1hdDogXCJpY2Utb3B0aW9uczolc1wiXG4gICAgfSxcbiAgICB7IC8vYT1zc3JjOjI1NjYxMDc1NjkgY25hbWU6dDlZVThNMVV4VEY4WTFBMVxuICAgICAgcHVzaDogXCJzc3Jjc1wiLFxuICAgICAgcmVnOiAvXnNzcmM6KFxcZCopIChbXFx3X10qKTooLiopLyxcbiAgICAgIG5hbWVzOiBbJ2lkJywgJ2F0dHJpYnV0ZScsICd2YWx1ZSddLFxuICAgICAgZm9ybWF0OiBcInNzcmM6JWQgJXM6JXNcIlxuICAgIH0sXG4gICAgeyAvL2E9c3NyYy1ncm91cDpGRUMgMSAyXG4gICAgICBwdXNoOiBcInNzcmNHcm91cHNcIixcbiAgICAgIHJlZzogL15zc3JjLWdyb3VwOihcXHcqKSAoLiopLyxcbiAgICAgIG5hbWVzOiBbJ3NlbWFudGljcycsICdzc3JjcyddLFxuICAgICAgZm9ybWF0OiBcInNzcmMtZ3JvdXA6JXMgJXNcIlxuICAgIH0sXG4gICAgeyAvL2E9bXNpZC1zZW1hbnRpYzogV01TIEp2bGFtNVgzU1gxT1A2cG4yMHpXb2d2YUtKejVIamY5T25sVlxuICAgICAgbmFtZTogXCJtc2lkU2VtYW50aWNcIixcbiAgICAgIHJlZzogL15tc2lkLXNlbWFudGljOlxccz8oXFx3KikgKFxcUyopLyxcbiAgICAgIG5hbWVzOiBbJ3NlbWFudGljJywgJ3Rva2VuJ10sXG4gICAgICBmb3JtYXQ6IFwibXNpZC1zZW1hbnRpYzogJXMgJXNcIiAvLyBzcGFjZSBhZnRlciBcIjpcIiBpcyBub3QgYWNjaWRlbnRhbFxuICAgIH0sXG4gICAgeyAvL2E9Z3JvdXA6QlVORExFIGF1ZGlvIHZpZGVvXG4gICAgICBwdXNoOiAnZ3JvdXBzJyxcbiAgICAgIHJlZzogL15ncm91cDooXFx3KikgKC4qKS8sXG4gICAgICBuYW1lczogWyd0eXBlJywgJ21pZHMnXSxcbiAgICAgIGZvcm1hdDogXCJncm91cDolcyAlc1wiXG4gICAgfSxcbiAgICB7IC8vYT1ydGNwLW11eFxuICAgICAgbmFtZTogJ3J0Y3BNdXgnLFxuICAgICAgcmVnOiAvXihydGNwLW11eCkvXG4gICAgfSxcbiAgICB7IC8vYT1ydGNwLXJzaXplXG4gICAgICBuYW1lOiAncnRjcFJzaXplJyxcbiAgICAgIHJlZzogL14ocnRjcC1yc2l6ZSkvXG4gICAgfSxcbiAgICB7IC8vIGFueSBhPSB0aGF0IHdlIGRvbid0IHVuZGVyc3RhbmQgaXMga2VwdHMgdmVyYmF0aW0gb24gbWVkaWEuaW52YWxpZFxuICAgICAgcHVzaDogJ2ludmFsaWQnLFxuICAgICAgbmFtZXM6IFtcInZhbHVlXCJdXG4gICAgfVxuICBdXG59O1xuXG4vLyBzZXQgc2Vuc2libGUgZGVmYXVsdHMgdG8gYXZvaWQgcG9sbHV0aW5nIHRoZSBncmFtbWFyIHdpdGggYm9yaW5nIGRldGFpbHNcbk9iamVjdC5rZXlzKGdyYW1tYXIpLmZvckVhY2goZnVuY3Rpb24gKGtleSkge1xuICB2YXIgb2JqcyA9IGdyYW1tYXJba2V5XTtcbiAgb2Jqcy5mb3JFYWNoKGZ1bmN0aW9uIChvYmopIHtcbiAgICBpZiAoIW9iai5yZWcpIHtcbiAgICAgIG9iai5yZWcgPSAvKC4qKS87XG4gICAgfVxuICAgIGlmICghb2JqLmZvcm1hdCkge1xuICAgICAgb2JqLmZvcm1hdCA9IFwiJXNcIjtcbiAgICB9XG4gIH0pO1xufSk7XG4iLCJ2YXIgcGFyc2VyID0gcmVxdWlyZSgnLi9wYXJzZXInKTtcbnZhciB3cml0ZXIgPSByZXF1aXJlKCcuL3dyaXRlcicpO1xuXG5leHBvcnRzLndyaXRlID0gd3JpdGVyO1xuZXhwb3J0cy5wYXJzZSA9IHBhcnNlci5wYXJzZTtcbmV4cG9ydHMucGFyc2VGbXRwQ29uZmlnID0gcGFyc2VyLnBhcnNlRm10cENvbmZpZztcbmV4cG9ydHMucGFyc2VQYXlsb2FkcyA9IHBhcnNlci5wYXJzZVBheWxvYWRzO1xuZXhwb3J0cy5wYXJzZVJlbW90ZUNhbmRpZGF0ZXMgPSBwYXJzZXIucGFyc2VSZW1vdGVDYW5kaWRhdGVzO1xuIiwidmFyIHRvSW50SWZJbnQgPSBmdW5jdGlvbiAodikge1xuICByZXR1cm4gU3RyaW5nKE51bWJlcih2KSkgPT09IHYgPyBOdW1iZXIodikgOiB2O1xufTtcblxudmFyIGF0dGFjaFByb3BlcnRpZXMgPSBmdW5jdGlvbiAobWF0Y2gsIGxvY2F0aW9uLCBuYW1lcywgcmF3TmFtZSkge1xuICBpZiAocmF3TmFtZSAmJiAhbmFtZXMpIHtcbiAgICBsb2NhdGlvbltyYXdOYW1lXSA9IHRvSW50SWZJbnQobWF0Y2hbMV0pO1xuICB9XG4gIGVsc2Uge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbmFtZXMubGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgIGlmIChtYXRjaFtpKzFdICE9IG51bGwpIHtcbiAgICAgICAgbG9jYXRpb25bbmFtZXNbaV1dID0gdG9JbnRJZkludChtYXRjaFtpKzFdKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn07XG5cbnZhciBwYXJzZVJlZyA9IGZ1bmN0aW9uIChvYmosIGxvY2F0aW9uLCBjb250ZW50KSB7XG4gIHZhciBuZWVkc0JsYW5rID0gb2JqLm5hbWUgJiYgb2JqLm5hbWVzO1xuICBpZiAob2JqLnB1c2ggJiYgIWxvY2F0aW9uW29iai5wdXNoXSkge1xuICAgIGxvY2F0aW9uW29iai5wdXNoXSA9IFtdO1xuICB9XG4gIGVsc2UgaWYgKG5lZWRzQmxhbmsgJiYgIWxvY2F0aW9uW29iai5uYW1lXSkge1xuICAgIGxvY2F0aW9uW29iai5uYW1lXSA9IHt9O1xuICB9XG4gIHZhciBrZXlMb2NhdGlvbiA9IG9iai5wdXNoID9cbiAgICB7fSA6ICAvLyBibGFuayBvYmplY3QgdGhhdCB3aWxsIGJlIHB1c2hlZFxuICAgIG5lZWRzQmxhbmsgPyBsb2NhdGlvbltvYmoubmFtZV0gOiBsb2NhdGlvbjsgLy8gb3RoZXJ3aXNlLCBuYW1lZCBsb2NhdGlvbiBvciByb290XG5cbiAgYXR0YWNoUHJvcGVydGllcyhjb250ZW50Lm1hdGNoKG9iai5yZWcpLCBrZXlMb2NhdGlvbiwgb2JqLm5hbWVzLCBvYmoubmFtZSk7XG5cbiAgaWYgKG9iai5wdXNoKSB7XG4gICAgbG9jYXRpb25bb2JqLnB1c2hdLnB1c2goa2V5TG9jYXRpb24pO1xuICB9XG59O1xuXG52YXIgZ3JhbW1hciA9IHJlcXVpcmUoJy4vZ3JhbW1hcicpO1xudmFyIHZhbGlkTGluZSA9IFJlZ0V4cC5wcm90b3R5cGUudGVzdC5iaW5kKC9eKFthLXpdKT0oLiopLyk7XG5cbmV4cG9ydHMucGFyc2UgPSBmdW5jdGlvbiAoc2RwKSB7XG4gIHZhciBzZXNzaW9uID0ge31cbiAgICAsIG1lZGlhID0gW11cbiAgICAsIGxvY2F0aW9uID0gc2Vzc2lvbjsgLy8gcG9pbnRzIGF0IHdoZXJlIHByb3BlcnRpZXMgZ28gdW5kZXIgKG9uZSBvZiB0aGUgYWJvdmUpXG5cbiAgLy8gcGFyc2UgbGluZXMgd2UgdW5kZXJzdGFuZFxuICBzZHAuc3BsaXQoLyhcXHJcXG58XFxyfFxcbikvKS5maWx0ZXIodmFsaWRMaW5lKS5mb3JFYWNoKGZ1bmN0aW9uIChsKSB7XG4gICAgdmFyIHR5cGUgPSBsWzBdO1xuICAgIHZhciBjb250ZW50ID0gbC5zbGljZSgyKTtcbiAgICBpZiAodHlwZSA9PT0gJ20nKSB7XG4gICAgICBtZWRpYS5wdXNoKHtydHA6IFtdLCBmbXRwOiBbXX0pO1xuICAgICAgbG9jYXRpb24gPSBtZWRpYVttZWRpYS5sZW5ndGgtMV07IC8vIHBvaW50IGF0IGxhdGVzdCBtZWRpYSBsaW5lXG4gICAgfVxuXG4gICAgZm9yICh2YXIgaiA9IDA7IGogPCAoZ3JhbW1hclt0eXBlXSB8fCBbXSkubGVuZ3RoOyBqICs9IDEpIHtcbiAgICAgIHZhciBvYmogPSBncmFtbWFyW3R5cGVdW2pdO1xuICAgICAgaWYgKG9iai5yZWcudGVzdChjb250ZW50KSkge1xuICAgICAgICByZXR1cm4gcGFyc2VSZWcob2JqLCBsb2NhdGlvbiwgY29udGVudCk7XG4gICAgICB9XG4gICAgfVxuICB9KTtcblxuICBzZXNzaW9uLm1lZGlhID0gbWVkaWE7IC8vIGxpbmsgaXQgdXBcbiAgcmV0dXJuIHNlc3Npb247XG59O1xuXG52YXIgZm10cFJlZHVjZXIgPSBmdW5jdGlvbiAoYWNjLCBleHByKSB7XG4gIHZhciBzID0gZXhwci5zcGxpdCgnPScpO1xuICBpZiAocy5sZW5ndGggPT09IDIpIHtcbiAgICBhY2Nbc1swXV0gPSB0b0ludElmSW50KHNbMV0pO1xuICB9XG4gIHJldHVybiBhY2M7XG59O1xuXG5leHBvcnRzLnBhcnNlRm10cENvbmZpZyA9IGZ1bmN0aW9uIChzdHIpIHtcbiAgcmV0dXJuIHN0ci5zcGxpdCgvXFw7XFxzPy8pLnJlZHVjZShmbXRwUmVkdWNlciwge30pO1xufTtcblxuZXhwb3J0cy5wYXJzZVBheWxvYWRzID0gZnVuY3Rpb24gKHN0cikge1xuICByZXR1cm4gc3RyLnNwbGl0KCcgJykubWFwKE51bWJlcik7XG59O1xuXG5leHBvcnRzLnBhcnNlUmVtb3RlQ2FuZGlkYXRlcyA9IGZ1bmN0aW9uIChzdHIpIHtcbiAgdmFyIGNhbmRpZGF0ZXMgPSBbXTtcbiAgdmFyIHBhcnRzID0gc3RyLnNwbGl0KCcgJykubWFwKHRvSW50SWZJbnQpO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHBhcnRzLmxlbmd0aDsgaSArPSAzKSB7XG4gICAgY2FuZGlkYXRlcy5wdXNoKHtcbiAgICAgIGNvbXBvbmVudDogcGFydHNbaV0sXG4gICAgICBpcDogcGFydHNbaSArIDFdLFxuICAgICAgcG9ydDogcGFydHNbaSArIDJdXG4gICAgfSk7XG4gIH1cbiAgcmV0dXJuIGNhbmRpZGF0ZXM7XG59O1xuIiwidmFyIGdyYW1tYXIgPSByZXF1aXJlKCcuL2dyYW1tYXInKTtcblxuLy8gY3VzdG9taXplZCB1dGlsLmZvcm1hdCAtIGRpc2NhcmRzIGV4Y2VzcyBhcmd1bWVudHMgYW5kIGNhbiB2b2lkIG1pZGRsZSBvbmVzXG52YXIgZm9ybWF0UmVnRXhwID0gLyVbc2R2JV0vZztcbnZhciBmb3JtYXQgPSBmdW5jdGlvbiAoZm9ybWF0U3RyKSB7XG4gIHZhciBpID0gMTtcbiAgdmFyIGFyZ3MgPSBhcmd1bWVudHM7XG4gIHZhciBsZW4gPSBhcmdzLmxlbmd0aDtcbiAgcmV0dXJuIGZvcm1hdFN0ci5yZXBsYWNlKGZvcm1hdFJlZ0V4cCwgZnVuY3Rpb24gKHgpIHtcbiAgICBpZiAoaSA+PSBsZW4pIHtcbiAgICAgIHJldHVybiB4OyAvLyBtaXNzaW5nIGFyZ3VtZW50XG4gICAgfVxuICAgIHZhciBhcmcgPSBhcmdzW2ldO1xuICAgIGkgKz0gMTtcbiAgICBzd2l0Y2ggKHgpIHtcbiAgICAgIGNhc2UgJyUlJzpcbiAgICAgICAgcmV0dXJuICclJztcbiAgICAgIGNhc2UgJyVzJzpcbiAgICAgICAgcmV0dXJuIFN0cmluZyhhcmcpO1xuICAgICAgY2FzZSAnJWQnOlxuICAgICAgICByZXR1cm4gTnVtYmVyKGFyZyk7XG4gICAgICBjYXNlICcldic6XG4gICAgICAgIHJldHVybiAnJztcbiAgICB9XG4gIH0pO1xuICAvLyBOQjogd2UgZGlzY2FyZCBleGNlc3MgYXJndW1lbnRzIC0gdGhleSBhcmUgdHlwaWNhbGx5IHVuZGVmaW5lZCBmcm9tIG1ha2VMaW5lXG59O1xuXG52YXIgbWFrZUxpbmUgPSBmdW5jdGlvbiAodHlwZSwgb2JqLCBsb2NhdGlvbikge1xuICB2YXIgc3RyID0gb2JqLmZvcm1hdCBpbnN0YW5jZW9mIEZ1bmN0aW9uID9cbiAgICAob2JqLmZvcm1hdChvYmoucHVzaCA/IGxvY2F0aW9uIDogbG9jYXRpb25bb2JqLm5hbWVdKSkgOlxuICAgIG9iai5mb3JtYXQ7XG5cbiAgdmFyIGFyZ3MgPSBbdHlwZSArICc9JyArIHN0cl07XG4gIGlmIChvYmoubmFtZXMpIHtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IG9iai5uYW1lcy5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgdmFyIG4gPSBvYmoubmFtZXNbaV07XG4gICAgICBpZiAob2JqLm5hbWUpIHtcbiAgICAgICAgYXJncy5wdXNoKGxvY2F0aW9uW29iai5uYW1lXVtuXSk7XG4gICAgICB9XG4gICAgICBlbHNlIHsgLy8gZm9yIG1MaW5lIGFuZCBwdXNoIGF0dHJpYnV0ZXNcbiAgICAgICAgYXJncy5wdXNoKGxvY2F0aW9uW29iai5uYW1lc1tpXV0pO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICBlbHNlIHtcbiAgICBhcmdzLnB1c2gobG9jYXRpb25bb2JqLm5hbWVdKTtcbiAgfVxuICByZXR1cm4gZm9ybWF0LmFwcGx5KG51bGwsIGFyZ3MpO1xufTtcblxuLy8gUkZDIHNwZWNpZmllZCBvcmRlclxuLy8gVE9ETzogZXh0ZW5kIHRoaXMgd2l0aCBhbGwgdGhlIHJlc3RcbnZhciBkZWZhdWx0T3V0ZXJPcmRlciA9IFtcbiAgJ3YnLCAnbycsICdzJywgJ2knLFxuICAndScsICdlJywgJ3AnLCAnYycsXG4gICdiJywgJ3QnLCAncicsICd6JywgJ2EnXG5dO1xudmFyIGRlZmF1bHRJbm5lck9yZGVyID0gWydpJywgJ2MnLCAnYicsICdhJ107XG5cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoc2Vzc2lvbiwgb3B0cykge1xuICBvcHRzID0gb3B0cyB8fCB7fTtcbiAgLy8gZW5zdXJlIGNlcnRhaW4gcHJvcGVydGllcyBleGlzdFxuICBpZiAoc2Vzc2lvbi52ZXJzaW9uID09IG51bGwpIHtcbiAgICBzZXNzaW9uLnZlcnNpb24gPSAwOyAvLyBcInY9MFwiIG11c3QgYmUgdGhlcmUgKG9ubHkgZGVmaW5lZCB2ZXJzaW9uIGF0bSlcbiAgfVxuICBpZiAoc2Vzc2lvbi5uYW1lID09IG51bGwpIHtcbiAgICBzZXNzaW9uLm5hbWUgPSBcIiBcIjsgLy8gXCJzPSBcIiBtdXN0IGJlIHRoZXJlIGlmIG5vIG1lYW5pbmdmdWwgbmFtZSBzZXRcbiAgfVxuICBzZXNzaW9uLm1lZGlhLmZvckVhY2goZnVuY3Rpb24gKG1MaW5lKSB7XG4gICAgaWYgKG1MaW5lLnBheWxvYWRzID09IG51bGwpIHtcbiAgICAgIG1MaW5lLnBheWxvYWRzID0gXCJcIjtcbiAgICB9XG4gIH0pO1xuXG4gIHZhciBvdXRlck9yZGVyID0gb3B0cy5vdXRlck9yZGVyIHx8IGRlZmF1bHRPdXRlck9yZGVyO1xuICB2YXIgaW5uZXJPcmRlciA9IG9wdHMuaW5uZXJPcmRlciB8fCBkZWZhdWx0SW5uZXJPcmRlcjtcbiAgdmFyIHNkcCA9IFtdO1xuXG4gIC8vIGxvb3AgdGhyb3VnaCBvdXRlck9yZGVyIGZvciBtYXRjaGluZyBwcm9wZXJ0aWVzIG9uIHNlc3Npb25cbiAgb3V0ZXJPcmRlci5mb3JFYWNoKGZ1bmN0aW9uICh0eXBlKSB7XG4gICAgZ3JhbW1hclt0eXBlXS5mb3JFYWNoKGZ1bmN0aW9uIChvYmopIHtcbiAgICAgIGlmIChvYmoubmFtZSBpbiBzZXNzaW9uICYmIHNlc3Npb25bb2JqLm5hbWVdICE9IG51bGwpIHtcbiAgICAgICAgc2RwLnB1c2gobWFrZUxpbmUodHlwZSwgb2JqLCBzZXNzaW9uKSk7XG4gICAgICB9XG4gICAgICBlbHNlIGlmIChvYmoucHVzaCBpbiBzZXNzaW9uICYmIHNlc3Npb25bb2JqLnB1c2hdICE9IG51bGwpIHtcbiAgICAgICAgc2Vzc2lvbltvYmoucHVzaF0uZm9yRWFjaChmdW5jdGlvbiAoZWwpIHtcbiAgICAgICAgICBzZHAucHVzaChtYWtlTGluZSh0eXBlLCBvYmosIGVsKSk7XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0pO1xuICB9KTtcblxuICAvLyB0aGVuIGZvciBlYWNoIG1lZGlhIGxpbmUsIGZvbGxvdyB0aGUgaW5uZXJPcmRlclxuICBzZXNzaW9uLm1lZGlhLmZvckVhY2goZnVuY3Rpb24gKG1MaW5lKSB7XG4gICAgc2RwLnB1c2gobWFrZUxpbmUoJ20nLCBncmFtbWFyLm1bMF0sIG1MaW5lKSk7XG5cbiAgICBpbm5lck9yZGVyLmZvckVhY2goZnVuY3Rpb24gKHR5cGUpIHtcbiAgICAgIGdyYW1tYXJbdHlwZV0uZm9yRWFjaChmdW5jdGlvbiAob2JqKSB7XG4gICAgICAgIGlmIChvYmoubmFtZSBpbiBtTGluZSAmJiBtTGluZVtvYmoubmFtZV0gIT0gbnVsbCkge1xuICAgICAgICAgIHNkcC5wdXNoKG1ha2VMaW5lKHR5cGUsIG9iaiwgbUxpbmUpKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChvYmoucHVzaCBpbiBtTGluZSAmJiBtTGluZVtvYmoucHVzaF0gIT0gbnVsbCkge1xuICAgICAgICAgIG1MaW5lW29iai5wdXNoXS5mb3JFYWNoKGZ1bmN0aW9uIChlbCkge1xuICAgICAgICAgICAgc2RwLnB1c2gobWFrZUxpbmUodHlwZSwgb2JqLCBlbCkpO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgcmV0dXJuIHNkcC5qb2luKCdcXHJcXG4nKSArICdcXHJcXG4nO1xufTtcbiIsIi8qIENvcHlyaWdodCBAIDIwMTUgQXRsYXNzaWFuIFB0eSBMdGRcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBhcnJheUVxdWFscyhhcnJheSkge1xuICAgIC8vIGlmIHRoZSBvdGhlciBhcnJheSBpcyBhIGZhbHN5IHZhbHVlLCByZXR1cm5cbiAgICBpZiAoIWFycmF5KVxuICAgICAgICByZXR1cm4gZmFsc2U7XG5cbiAgICAvLyBjb21wYXJlIGxlbmd0aHMgLSBjYW4gc2F2ZSBhIGxvdCBvZiB0aW1lXG4gICAgaWYgKHRoaXMubGVuZ3RoICE9IGFycmF5Lmxlbmd0aClcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuXG4gICAgZm9yICh2YXIgaSA9IDAsIGwgPSB0aGlzLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgICAgICAvLyBDaGVjayBpZiB3ZSBoYXZlIG5lc3RlZCBhcnJheXNcbiAgICAgICAgaWYgKHRoaXNbaV0gaW5zdGFuY2VvZiBBcnJheSAmJiBhcnJheVtpXSBpbnN0YW5jZW9mIEFycmF5KSB7XG4gICAgICAgICAgICAvLyByZWN1cnNlIGludG8gdGhlIG5lc3RlZCBhcnJheXNcbiAgICAgICAgICAgIGlmICghYXJyYXlFcXVhbHMuYXBwbHkodGhpc1tpXSwgW2FycmF5W2ldXSkpXG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9IGVsc2UgaWYgKHRoaXNbaV0gIT0gYXJyYXlbaV0pIHtcbiAgICAgICAgICAgIC8vIFdhcm5pbmcgLSB0d28gZGlmZmVyZW50IG9iamVjdCBpbnN0YW5jZXMgd2lsbCBuZXZlciBiZSBlcXVhbDpcbiAgICAgICAgICAgIC8vIHt4OjIwfSAhPSB7eDoyMH1cbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbn07XG5cbiIsIi8qIENvcHlyaWdodCBAIDIwMTUgQXRsYXNzaWFuIFB0eSBMdGRcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKi9cblxuZXhwb3J0cy5JbnRlcm9wID0gcmVxdWlyZSgnLi9pbnRlcm9wJyk7XG4iLCIvKiBDb3B5cmlnaHQgQCAyMDE1IEF0bGFzc2lhbiBQdHkgTHRkXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICovXG5cbi8qIGdsb2JhbCBSVENTZXNzaW9uRGVzY3JpcHRpb24gKi9cbi8qIGdsb2JhbCBSVENJY2VDYW5kaWRhdGUgKi9cbi8qIGpzaGludCAtVzA5NyAqL1xuXCJ1c2Ugc3RyaWN0XCI7XG5cbnZhciB0cmFuc2Zvcm0gPSByZXF1aXJlKCcuL3RyYW5zZm9ybScpO1xudmFyIGFycmF5RXF1YWxzID0gcmVxdWlyZSgnLi9hcnJheS1lcXVhbHMnKTtcblxuZnVuY3Rpb24gSW50ZXJvcCgpIHtcblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWFwIGhvbGRzIHRoZSBtb3N0IHJlY2VudCBVbmlmaWVkIFBsYW4gb2ZmZXIvYW5zd2VyIFNEUCB0aGF0IHdhc1xuICAgICAqIGNvbnZlcnRlZCB0byBQbGFuIEIsIHdpdGggdGhlIFNEUCB0eXBlICgnb2ZmZXInIG9yICdhbnN3ZXInKSBhcyBrZXlzIGFuZFxuICAgICAqIHRoZSBTRFAgc3RyaW5nIGFzIHZhbHVlcy5cbiAgICAgKlxuICAgICAqIEB0eXBlIHt7fX1cbiAgICAgKi9cbiAgICB0aGlzLmNhY2hlID0ge1xuICAgICAgICBtbEIyVU1hcCA6IHt9LFxuICAgICAgICBtbFUyQk1hcCA6IHt9XG4gICAgfTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBJbnRlcm9wO1xuXG4vKipcbiAqIENoYW5nZXMgdGhlIGNhbmRpZGF0ZSBhcmdzIHRvIG1hdGNoIHdpdGggdGhlIHJlbGF0ZWQgVW5pZmllZCBQbGFuXG4gKi9cbkludGVyb3AucHJvdG90eXBlLmNhbmRpZGF0ZVRvVW5pZmllZFBsYW4gPSBmdW5jdGlvbihjYW5kaWRhdGUpIHtcbiAgICB2YXIgY2FuZCA9IG5ldyBSVENJY2VDYW5kaWRhdGUoY2FuZGlkYXRlKTtcblxuICAgIGNhbmQuc2RwTUxpbmVJbmRleCA9IHRoaXMuY2FjaGUubWxCMlVNYXBbY2FuZC5zZHBNTGluZUluZGV4XTtcbiAgICAvKiBUT0RPOiBjaGFuZ2Ugc2RwTWlkIHRvIChhdWRpb3x2aWRlbyktU1NSQyAqL1xuXG4gICAgcmV0dXJuIGNhbmQ7XG59O1xuXG4vKipcbiAqIENoYW5nZXMgdGhlIGNhbmRpZGF0ZSBhcmdzIHRvIG1hdGNoIHdpdGggdGhlIHJlbGF0ZWQgUGxhbiBCXG4gKi9cbkludGVyb3AucHJvdG90eXBlLmNhbmRpZGF0ZVRvUGxhbkIgPSBmdW5jdGlvbihjYW5kaWRhdGUpIHtcbiAgICB2YXIgY2FuZCA9IG5ldyBSVENJY2VDYW5kaWRhdGUoY2FuZGlkYXRlKTtcblxuICAgIGlmIChjYW5kLnNkcE1pZC5pbmRleE9mKCdhdWRpbycpID09PSAwKSB7XG4gICAgICBjYW5kLnNkcE1pZCA9ICdhdWRpbyc7XG4gICAgfSBlbHNlIGlmIChjYW5kLnNkcE1pZC5pbmRleE9mKCd2aWRlbycpID09PSAwKSB7XG4gICAgICBjYW5kLnNkcE1pZCA9ICd2aWRlbyc7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignY2FuZGlkYXRlIHdpdGggJyArIGNhbmQuc2RwTWlkICsgJyBub3QgYWxsb3dlZCcpO1xuICAgIH1cblxuICAgIGNhbmQuc2RwTUxpbmVJbmRleCA9IHRoaXMuY2FjaGUubWxVMkJNYXBbY2FuZC5zZHBNTGluZUluZGV4XTtcblxuICAgIHJldHVybiBjYW5kO1xufTtcblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBpbmRleCBvZiB0aGUgZmlyc3QgbS1saW5lIHdpdGggdGhlIGdpdmVuIG1lZGlhIHR5cGUgYW5kIHdpdGggYVxuICogZGlyZWN0aW9uIHdoaWNoIGFsbG93cyBzZW5kaW5nLCBpbiB0aGUgbGFzdCBVbmlmaWVkIFBsYW4gZGVzY3JpcHRpb24gd2l0aFxuICogdHlwZSBcImFuc3dlclwiIGNvbnZlcnRlZCB0byBQbGFuIEIuIFJldHVybnMge251bGx9IGlmIHRoZXJlIGlzIG5vIHNhdmVkXG4gKiBhbnN3ZXIsIG9yIGlmIG5vbmUgb2YgaXRzIG0tbGluZXMgd2l0aCB0aGUgZ2l2ZW4gdHlwZSBhbGxvdyBzZW5kaW5nLlxuICogQHBhcmFtIHR5cGUgdGhlIG1lZGlhIHR5cGUgKFwiYXVkaW9cIiBvciBcInZpZGVvXCIpLlxuICogQHJldHVybnMgeyp9XG4gKi9cbkludGVyb3AucHJvdG90eXBlLmdldEZpcnN0U2VuZGluZ0luZGV4RnJvbUFuc3dlciA9IGZ1bmN0aW9uKHR5cGUpIHtcbiAgICBpZiAoIXRoaXMuY2FjaGUuYW5zd2VyKSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIHZhciBzZXNzaW9uID0gdHJhbnNmb3JtLnBhcnNlKHRoaXMuY2FjaGUuYW5zd2VyKTtcbiAgICBpZiAoc2Vzc2lvbiAmJiBzZXNzaW9uLm1lZGlhICYmIEFycmF5LmlzQXJyYXkoc2Vzc2lvbi5tZWRpYSkpe1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHNlc3Npb24ubWVkaWEubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGlmIChzZXNzaW9uLm1lZGlhW2ldLnR5cGUgPT0gdHlwZSAmJlxuICAgICAgICAgICAgICAgICghc2Vzc2lvbi5tZWRpYVtpXS5kaXJlY3Rpb24gLyogZGVmYXVsdCB0byBzZW5kcmVjdiAqLyB8fFxuICAgICAgICAgICAgICAgICAgICBzZXNzaW9uLm1lZGlhW2ldLmRpcmVjdGlvbiA9PT0gJ3NlbmRyZWN2JyB8fFxuICAgICAgICAgICAgICAgICAgICBzZXNzaW9uLm1lZGlhW2ldLmRpcmVjdGlvbiA9PT0gJ3NlbmRvbmx5Jykpe1xuICAgICAgICAgICAgICAgIHJldHVybiBpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIG51bGw7XG59O1xuXG4vKipcbiAqIFRoaXMgbWV0aG9kIHRyYW5zZm9ybXMgYSBVbmlmaWVkIFBsYW4gU0RQIHRvIGFuIGVxdWl2YWxlbnQgUGxhbiBCIFNEUC4gQVxuICogUGVlckNvbm5lY3Rpb24gd3JhcHBlciB0cmFuc2Zvcm1zIHRoZSBTRFAgdG8gUGxhbiBCIGJlZm9yZSBwYXNzaW5nIGl0IHRvIHRoZVxuICogYXBwbGljYXRpb24uXG4gKlxuICogQHBhcmFtIGRlc2NcbiAqIEByZXR1cm5zIHsqfVxuICovXG5JbnRlcm9wLnByb3RvdHlwZS50b1BsYW5CID0gZnVuY3Rpb24oZGVzYykge1xuICAgIHZhciBzZWxmID0gdGhpcztcbiAgICAvLyNyZWdpb24gUHJlbGltaW5hcnkgaW5wdXQgdmFsaWRhdGlvbi5cblxuICAgIGlmICh0eXBlb2YgZGVzYyAhPT0gJ29iamVjdCcgfHwgZGVzYyA9PT0gbnVsbCB8fFxuICAgICAgICB0eXBlb2YgZGVzYy5zZHAgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgIGNvbnNvbGUud2FybignQW4gZW1wdHkgZGVzY3JpcHRpb24gd2FzIHBhc3NlZCBhcyBhbiBhcmd1bWVudC4nKTtcbiAgICAgICAgcmV0dXJuIGRlc2M7XG4gICAgfVxuXG4gICAgLy8gT2JqZWN0aWZ5IHRoZSBTRFAgZm9yIGVhc2llciBtYW5pcHVsYXRpb24uXG4gICAgdmFyIHNlc3Npb24gPSB0cmFuc2Zvcm0ucGFyc2UoZGVzYy5zZHApO1xuXG4gICAgLy8gSWYgdGhlIFNEUCBjb250YWlucyBubyBtZWRpYSwgdGhlcmUncyBub3RoaW5nIHRvIHRyYW5zZm9ybS5cbiAgICBpZiAodHlwZW9mIHNlc3Npb24ubWVkaWEgPT09ICd1bmRlZmluZWQnIHx8XG4gICAgICAgICFBcnJheS5pc0FycmF5KHNlc3Npb24ubWVkaWEpIHx8IHNlc3Npb24ubWVkaWEubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIGNvbnNvbGUud2FybignVGhlIGRlc2NyaXB0aW9uIGhhcyBubyBtZWRpYS4nKTtcbiAgICAgICAgcmV0dXJuIGRlc2M7XG4gICAgfVxuXG4gICAgLy8gVHJ5IHNvbWUgaGV1cmlzdGljcyB0byBcIm1ha2Ugc3VyZVwiIHRoaXMgaXMgYSBVbmlmaWVkIFBsYW4gU0RQLiBQbGFuIEJcbiAgICAvLyBTRFAgaGFzIGEgdmlkZW8sIGFuIGF1ZGlvIGFuZCBhIGRhdGEgXCJjaGFubmVsXCIgYXQgbW9zdC5cbiAgICBpZiAoc2Vzc2lvbi5tZWRpYS5sZW5ndGggPD0gMyAmJiBzZXNzaW9uLm1lZGlhLmV2ZXJ5KGZ1bmN0aW9uKG0pIHtcbiAgICAgICAgICAgIHJldHVybiBbJ3ZpZGVvJywgJ2F1ZGlvJywgJ2RhdGEnXS5pbmRleE9mKG0ubWlkKSAhPT0gLTE7XG4gICAgICAgIH0pKSB7XG4gICAgICAgIGNvbnNvbGUud2FybignVGhpcyBkZXNjcmlwdGlvbiBkb2VzIG5vdCBsb29rIGxpa2UgVW5pZmllZCBQbGFuLicpO1xuICAgICAgICByZXR1cm4gZGVzYztcbiAgICB9XG5cbiAgICAvLyNlbmRyZWdpb25cblxuICAgIC8vIEhBQ0sgaHR0cHM6Ly9idWd6aWxsYS5tb3ppbGxhLm9yZy9zaG93X2J1Zy5jZ2k/aWQ9MTExMzQ0M1xuICAgIHZhciBzZHAgPSBkZXNjLnNkcDtcbiAgICB2YXIgcmV3cml0ZSA9IGZhbHNlO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc2Vzc2lvbi5tZWRpYS5sZW5ndGg7IGkrKykge1xuICAgICAgICB2YXIgdUxpbmUgPSBzZXNzaW9uLm1lZGlhW2ldO1xuICAgICAgICB1TGluZS5ydHAuZm9yRWFjaChmdW5jdGlvbihydHApIHtcbiAgICAgICAgICAgIGlmIChydHAuY29kZWMgPT09ICdOVUxMJylcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICByZXdyaXRlID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICB2YXIgb2ZmZXIgPSB0cmFuc2Zvcm0ucGFyc2Uoc2VsZi5jYWNoZS5vZmZlcik7XG4gICAgICAgICAgICAgICAgcnRwLmNvZGVjID0gb2ZmZXIubWVkaWFbaV0ucnRwWzBdLmNvZGVjO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgaWYgKHJld3JpdGUpIHtcbiAgICAgICAgc2RwID0gdHJhbnNmb3JtLndyaXRlKHNlc3Npb24pO1xuICAgIH1cblxuICAgIC8vIFVuaWZpZWQgUGxhbiBTRFAgaXMgb3VyIFwicHJlY2lvdXNcIi4gQ2FjaGUgaXQgZm9yIGxhdGVyIHVzZSBpbiB0aGUgUGxhbiBCXG4gICAgLy8gLT4gVW5pZmllZCBQbGFuIHRyYW5zZm9ybWF0aW9uLlxuICAgIHRoaXMuY2FjaGVbZGVzYy50eXBlXSA9IHNkcDtcblxuICAgIC8vI3JlZ2lvbiBDb252ZXJ0IGZyb20gVW5pZmllZCBQbGFuIHRvIFBsYW4gQi5cblxuICAgIC8vIFdlIHJlYnVpbGQgdGhlIHNlc3Npb24ubWVkaWEgYXJyYXkuXG4gICAgdmFyIG1lZGlhID0gc2Vzc2lvbi5tZWRpYTtcbiAgICBzZXNzaW9uLm1lZGlhID0gW107XG5cbiAgICAvLyBBc3NvY2lhdGl2ZSBhcnJheSB0aGF0IG1hcHMgY2hhbm5lbCB0eXBlcyB0byBjaGFubmVsIG9iamVjdHMgZm9yIGZhc3RcbiAgICAvLyBhY2Nlc3MgdG8gY2hhbm5lbCBvYmplY3RzIGJ5IHRoZWlyIHR5cGUsIGUuZy4gdHlwZTJibFsnYXVkaW8nXS0+Y2hhbm5lbFxuICAgIC8vIG9iai5cbiAgICB2YXIgdHlwZTJibCA9IHt9O1xuXG4gICAgLy8gVXNlZCB0byBidWlsZCB0aGUgZ3JvdXA6QlVORExFIHZhbHVlIGFmdGVyIHRoZSBjaGFubmVscyBjb25zdHJ1Y3Rpb25cbiAgICAvLyBsb29wLlxuICAgIHZhciB0eXBlcyA9IFtdO1xuXG4gICAgbWVkaWEuZm9yRWFjaChmdW5jdGlvbih1TGluZSkge1xuICAgICAgICAvLyBydGNwLW11eCBpcyByZXF1aXJlZCBpbiB0aGUgUGxhbiBCIFNEUC5cbiAgICAgICAgaWYgKCh0eXBlb2YgdUxpbmUucnRjcE11eCAhPT0gJ3N0cmluZycgfHxcbiAgICAgICAgICAgIHVMaW5lLnJ0Y3BNdXggIT09ICdydGNwLW11eCcpICYmXG4gICAgICAgICAgICB1TGluZS5kaXJlY3Rpb24gIT09ICdpbmFjdGl2ZScpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignQ2Fubm90IGNvbnZlcnQgdG8gUGxhbiBCIGJlY2F1c2UgbS1saW5lcyAnICtcbiAgICAgICAgICAgICAgICAnd2l0aG91dCB0aGUgcnRjcC1tdXggYXR0cmlidXRlIHdlcmUgZm91bmQuJyk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBJZiB3ZSBkb24ndCBoYXZlIGEgY2hhbm5lbCBmb3IgdGhpcyB1TGluZS50eXBlIE9SIHRoZSBzZWxlY3RlZCBpc1xuICAgICAgICAvLyBpbmFjdGl2ZSwgdGhlbiBzZWxlY3QgdGhpcyB1TGluZSBhcyB0aGUgY2hhbm5lbCBiYXNpcy5cbiAgICAgICAgaWYgKHR5cGVvZiB0eXBlMmJsW3VMaW5lLnR5cGVdID09PSAndW5kZWZpbmVkJyB8fFxuICAgICAgICAgICAgdHlwZTJibFt1TGluZS50eXBlXS5kaXJlY3Rpb24gPT09ICdpbmFjdGl2ZScpIHtcbiAgICAgICAgICAgIHR5cGUyYmxbdUxpbmUudHlwZV0gPSB1TGluZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh1TGluZS5wcm90b2NvbCAhPSB0eXBlMmJsW3VMaW5lLnR5cGVdLnByb3RvY29sKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdDYW5ub3QgY29udmVydCB0byBQbGFuIEIgYmVjYXVzZSBtLWxpbmVzICcgK1xuICAgICAgICAgICAgICAnaGF2ZSBkaWZmZXJlbnQgcHJvdG9jb2xzIGFuZCB0aGlzIGxpYnJhcnkgZG9lcyBub3QgaGF2ZSAnICtcbiAgICAgICAgICAgICAgJ3N1cHBvcnQgZm9yIHRoYXQnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh1TGluZS5wYXlsb2FkcyAhPSB0eXBlMmJsW3VMaW5lLnR5cGVdLnBheWxvYWRzKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdDYW5ub3QgY29udmVydCB0byBQbGFuIEIgYmVjYXVzZSBtLWxpbmVzICcgK1xuICAgICAgICAgICAgICAnaGF2ZSBkaWZmZXJlbnQgcGF5bG9hZHMgYW5kIHRoaXMgbGlicmFyeSBkb2VzIG5vdCBoYXZlICcgK1xuICAgICAgICAgICAgICAnc3VwcG9ydCBmb3IgdGhhdCcpO1xuICAgICAgICB9XG5cbiAgICB9KTtcblxuICAgIC8vIEltcGxvZGUgdGhlIFVuaWZpZWQgUGxhbiBtLWxpbmVzL3RyYWNrcyBpbnRvIFBsYW4gQiBjaGFubmVscy5cbiAgICBtZWRpYS5mb3JFYWNoKGZ1bmN0aW9uKHVMaW5lKSB7XG4gICAgICAgIGlmICh1TGluZS50eXBlID09PSAnYXBwbGljYXRpb24nKSB7XG4gICAgICAgICAgICBzZXNzaW9uLm1lZGlhLnB1c2godUxpbmUpO1xuICAgICAgICAgICAgdHlwZXMucHVzaCh1TGluZS5taWQpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gQWRkIHNvdXJjZXMgdG8gdGhlIGNoYW5uZWwgYW5kIGhhbmRsZSBhPW1zaWQuXG4gICAgICAgIGlmICh0eXBlb2YgdUxpbmUuc291cmNlcyA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgIE9iamVjdC5rZXlzKHVMaW5lLnNvdXJjZXMpLmZvckVhY2goZnVuY3Rpb24oc3NyYykge1xuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgdHlwZTJibFt1TGluZS50eXBlXS5zb3VyY2VzICE9PSAnb2JqZWN0JylcbiAgICAgICAgICAgICAgICAgICAgdHlwZTJibFt1TGluZS50eXBlXS5zb3VyY2VzID0ge307XG5cbiAgICAgICAgICAgICAgICAvLyBBc3NpZ24gdGhlIHNvdXJjZXMgdG8gdGhlIGNoYW5uZWwuXG4gICAgICAgICAgICAgICAgdHlwZTJibFt1TGluZS50eXBlXS5zb3VyY2VzW3NzcmNdID1cbiAgICAgICAgICAgICAgICAgICAgdUxpbmUuc291cmNlc1tzc3JjXTtcblxuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgdUxpbmUubXNpZCAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gSW4gUGxhbiBCIHRoZSBtc2lkIGlzIGFuIFNTUkMgYXR0cmlidXRlLiBBbHNvLCB3ZSBkb24ndFxuICAgICAgICAgICAgICAgICAgICAvLyBjYXJlIGFib3V0IHRoZSBvYnNvbGV0ZSBsYWJlbCBhbmQgbXNsYWJlbCBhdHRyaWJ1dGVzLlxuICAgICAgICAgICAgICAgICAgICAvL1xuICAgICAgICAgICAgICAgICAgICAvLyBOb3RlIHRoYXQgaXQgaXMgbm90IGd1YXJhbnRlZWQgdGhhdCB0aGUgdUxpbmUgd2lsbFxuICAgICAgICAgICAgICAgICAgICAvLyBoYXZlIGFuIG1zaWQuIHJlY3Zvbmx5IGNoYW5uZWxzIGluIHBhcnRpY3VsYXIgZG9uJ3QgaGF2ZVxuICAgICAgICAgICAgICAgICAgICAvLyBvbmUuXG4gICAgICAgICAgICAgICAgICAgIHR5cGUyYmxbdUxpbmUudHlwZV0uc291cmNlc1tzc3JjXS5tc2lkID1cbiAgICAgICAgICAgICAgICAgICAgICAgIHVMaW5lLm1zaWQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIC8vIE5PVEUgc3NyY3MgaW4gc3NyYyBncm91cHMgd2lsbCBzaGFyZSBtc2lkcywgYXNcbiAgICAgICAgICAgICAgICAvLyBkcmFmdC11YmVydGktcnRjd2ViLXBsYW4tMDAgbWFuZGF0ZXMuXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEFkZCBzc3JjIGdyb3VwcyB0byB0aGUgY2hhbm5lbC5cbiAgICAgICAgaWYgKHR5cGVvZiB1TGluZS5zc3JjR3JvdXBzICE9PSAndW5kZWZpbmVkJyAmJlxuICAgICAgICAgICAgICAgIEFycmF5LmlzQXJyYXkodUxpbmUuc3NyY0dyb3VwcykpIHtcblxuICAgICAgICAgICAgLy8gQ3JlYXRlIHRoZSBzc3JjR3JvdXBzIGFycmF5LCBpZiBpdCdzIG5vdCBkZWZpbmVkLlxuICAgICAgICAgICAgaWYgKHR5cGVvZiB0eXBlMmJsW3VMaW5lLnR5cGVdLnNzcmNHcm91cHMgPT09ICd1bmRlZmluZWQnIHx8XG4gICAgICAgICAgICAgICAgICAgICFBcnJheS5pc0FycmF5KHR5cGUyYmxbdUxpbmUudHlwZV0uc3NyY0dyb3VwcykpIHtcbiAgICAgICAgICAgICAgICB0eXBlMmJsW3VMaW5lLnR5cGVdLnNzcmNHcm91cHMgPSBbXTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdHlwZTJibFt1TGluZS50eXBlXS5zc3JjR3JvdXBzID1cbiAgICAgICAgICAgICAgICB0eXBlMmJsW3VMaW5lLnR5cGVdLnNzcmNHcm91cHMuY29uY2F0KFxuICAgICAgICAgICAgICAgICAgICB1TGluZS5zc3JjR3JvdXBzKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0eXBlMmJsW3VMaW5lLnR5cGVdID09PSB1TGluZSkge1xuICAgICAgICAgICAgLy8gUGxhbiBCIG1pZHMgYXJlIGluIFsnYXVkaW8nLCAndmlkZW8nLCAnZGF0YSddXG4gICAgICAgICAgICB1TGluZS5taWQgPSB1TGluZS50eXBlO1xuXG4gICAgICAgICAgICAvLyBQbGFuIEIgZG9lc24ndCBzdXBwb3J0L25lZWQgdGhlIGJ1bmRsZS1vbmx5IGF0dHJpYnV0ZS5cbiAgICAgICAgICAgIGRlbGV0ZSB1TGluZS5idW5kbGVPbmx5O1xuXG4gICAgICAgICAgICAvLyBJbiBQbGFuIEIgdGhlIG1zaWQgaXMgYW4gU1NSQyBhdHRyaWJ1dGUuXG4gICAgICAgICAgICBkZWxldGUgdUxpbmUubXNpZDtcblxuXHQgICAgaWYgKHVMaW5lLnR5cGUgPT0gbWVkaWFbMF0udHlwZSkge1xuXHQgICAgICB0eXBlcy51bnNoaWZ0KHVMaW5lLnR5cGUpO1xuXHQgICAgICAvLyBBZGQgdGhlIGNoYW5uZWwgdG8gdGhlIG5ldyBtZWRpYSBhcnJheS5cblx0ICAgICAgc2Vzc2lvbi5tZWRpYS51bnNoaWZ0KHVMaW5lKTtcblx0ICAgIH0gZWxzZSB7XG5cdCAgICAgIHR5cGVzLnB1c2godUxpbmUudHlwZSk7XG5cdCAgICAgIC8vIEFkZCB0aGUgY2hhbm5lbCB0byB0aGUgbmV3IG1lZGlhIGFycmF5LlxuXHQgICAgICBzZXNzaW9uLm1lZGlhLnB1c2godUxpbmUpO1xuXHQgICAgfVxuICAgICAgICB9XG4gICAgfSk7XG5cbiAgICBpZiAodHlwZW9mIHNlc3Npb24uZ3JvdXBzICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgLy8gV2UgcmVnZW5lcmF0ZSB0aGUgQlVORExFIGdyb3VwIHdpdGggdGhlIG5ldyBtaWRzLlxuICAgICAgc2Vzc2lvbi5ncm91cHMuc29tZShmdW5jdGlvbihncm91cCkge1xuXHQgIGlmIChncm91cC50eXBlID09PSAnQlVORExFJykge1xuXHQgICAgICBncm91cC5taWRzID0gdHlwZXMuam9pbignICcpO1xuXHQgICAgICByZXR1cm4gdHJ1ZTtcblx0ICB9XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvLyBtc2lkIHNlbWFudGljXG4gICAgc2Vzc2lvbi5tc2lkU2VtYW50aWMgPSB7XG4gICAgICAgIHNlbWFudGljOiAnV01TJyxcbiAgICAgICAgdG9rZW46ICcqJ1xuICAgIH07XG5cbiAgICB2YXIgcmVzU3RyID0gdHJhbnNmb3JtLndyaXRlKHNlc3Npb24pO1xuXG4gICAgcmV0dXJuIG5ldyBSVENTZXNzaW9uRGVzY3JpcHRpb24oe1xuICAgICAgICB0eXBlOiBkZXNjLnR5cGUsXG4gICAgICAgIHNkcDogcmVzU3RyXG4gICAgfSk7XG5cbiAgICAvLyNlbmRyZWdpb25cbn07XG5cbi8qIGZvbGxvdyBydWxlcyBkZWZpbmVkIGluIFJGQzQxNDUgKi9cbmZ1bmN0aW9uIGFkZFNldHVwQXR0cih1TGluZSkge1xuICAgIGlmICh0eXBlb2YgdUxpbmUuc2V0dXAgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAodUxpbmUuc2V0dXAgPT09IFwiYWN0aXZlXCIpIHtcbiAgICAgICAgICAgIHVMaW5lLnNldHVwID0gXCJwYXNzaXZlXCI7XG4gICAgfSBlbHNlIGlmICh1TGluZS5zZXR1cCA9PT0gXCJwYXNzaXZlXCIpIHtcbiAgICAgICAgdUxpbmUuc2V0dXAgPSBcImFjdGl2ZVwiO1xuICAgIH1cbn1cblxuLyoqXG4gKiBUaGlzIG1ldGhvZCB0cmFuc2Zvcm1zIGEgUGxhbiBCIFNEUCB0byBhbiBlcXVpdmFsZW50IFVuaWZpZWQgUGxhbiBTRFAuIEFcbiAqIFBlZXJDb25uZWN0aW9uIHdyYXBwZXIgdHJhbnNmb3JtcyB0aGUgU0RQIHRvIFVuaWZpZWQgUGxhbiBiZWZvcmUgcGFzc2luZyBpdFxuICogdG8gRkYuXG4gKlxuICogQHBhcmFtIGRlc2NcbiAqIEByZXR1cm5zIHsqfVxuICovXG5JbnRlcm9wLnByb3RvdHlwZS50b1VuaWZpZWRQbGFuID0gZnVuY3Rpb24oZGVzYykge1xuICAgIHZhciBzZWxmID0gdGhpcztcbiAgICAvLyNyZWdpb24gUHJlbGltaW5hcnkgaW5wdXQgdmFsaWRhdGlvbi5cblxuICAgIGlmICh0eXBlb2YgZGVzYyAhPT0gJ29iamVjdCcgfHwgZGVzYyA9PT0gbnVsbCB8fFxuICAgICAgICB0eXBlb2YgZGVzYy5zZHAgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgIGNvbnNvbGUud2FybignQW4gZW1wdHkgZGVzY3JpcHRpb24gd2FzIHBhc3NlZCBhcyBhbiBhcmd1bWVudC4nKTtcbiAgICAgICAgcmV0dXJuIGRlc2M7XG4gICAgfVxuXG4gICAgdmFyIHNlc3Npb24gPSB0cmFuc2Zvcm0ucGFyc2UoZGVzYy5zZHApO1xuXG4gICAgLy8gSWYgdGhlIFNEUCBjb250YWlucyBubyBtZWRpYSwgdGhlcmUncyBub3RoaW5nIHRvIHRyYW5zZm9ybS5cbiAgICBpZiAodHlwZW9mIHNlc3Npb24ubWVkaWEgPT09ICd1bmRlZmluZWQnIHx8XG4gICAgICAgICFBcnJheS5pc0FycmF5KHNlc3Npb24ubWVkaWEpIHx8IHNlc3Npb24ubWVkaWEubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIGNvbnNvbGUud2FybignVGhlIGRlc2NyaXB0aW9uIGhhcyBubyBtZWRpYS4nKTtcbiAgICAgICAgcmV0dXJuIGRlc2M7XG4gICAgfVxuXG4gICAgLy8gVHJ5IHNvbWUgaGV1cmlzdGljcyB0byBcIm1ha2Ugc3VyZVwiIHRoaXMgaXMgYSBQbGFuIEIgU0RQLiBQbGFuIEIgU0RQIGhhc1xuICAgIC8vIGEgdmlkZW8sIGFuIGF1ZGlvIGFuZCBhIGRhdGEgXCJjaGFubmVsXCIgYXQgbW9zdC5cbiAgICBpZiAoc2Vzc2lvbi5tZWRpYS5sZW5ndGggPiAzIHx8ICFzZXNzaW9uLm1lZGlhLmV2ZXJ5KGZ1bmN0aW9uKG0pIHtcbiAgICAgICAgICAgIHJldHVybiBbJ3ZpZGVvJywgJ2F1ZGlvJywgJ2RhdGEnXS5pbmRleE9mKG0ubWlkKSAhPT0gLTE7XG4gICAgICAgIH0pKSB7XG4gICAgICAgIGNvbnNvbGUud2FybignVGhpcyBkZXNjcmlwdGlvbiBkb2VzIG5vdCBsb29rIGxpa2UgUGxhbiBCLicpO1xuICAgICAgICByZXR1cm4gZGVzYztcbiAgICB9XG5cbiAgICAvLyBNYWtlIHN1cmUgdGhpcyBQbGFuIEIgU0RQIGNhbiBiZSBjb252ZXJ0ZWQgdG8gYSBVbmlmaWVkIFBsYW4gU0RQLlxuICAgIHZhciBtaWRzID0gW107XG4gICAgc2Vzc2lvbi5tZWRpYS5mb3JFYWNoKGZ1bmN0aW9uKG0pIHtcbiAgICAgICAgbWlkcy5wdXNoKG0ubWlkKTtcbiAgICB9KTtcblxuICAgIHZhciBoYXNCdW5kbGUgPSBmYWxzZTtcbiAgICBpZiAodHlwZW9mIHNlc3Npb24uZ3JvdXBzICE9PSAndW5kZWZpbmVkJyAmJlxuICAgICAgICBBcnJheS5pc0FycmF5KHNlc3Npb24uZ3JvdXBzKSkge1xuICAgICAgICBoYXNCdW5kbGUgPSBzZXNzaW9uLmdyb3Vwcy5ldmVyeShmdW5jdGlvbihnKSB7XG4gICAgICAgICAgICByZXR1cm4gZy50eXBlICE9PSAnQlVORExFJyB8fFxuICAgICAgICAgICAgICAgIGFycmF5RXF1YWxzLmFwcGx5KGcubWlkcy5zb3J0KCksIFttaWRzLnNvcnQoKV0pO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBpZiAoIWhhc0J1bmRsZSkge1xuICAgICAgICB2YXIgbXVzdEJlQnVuZGxlID0gZmFsc2U7XG5cbiAgICAgICAgc2Vzc2lvbi5tZWRpYS5mb3JFYWNoKGZ1bmN0aW9uKG0pIHtcbiAgICAgICAgICAgIGlmIChtLmRpcmVjdGlvbiAhPT0gJ2luYWN0aXZlJykge1xuICAgICAgICAgICAgICAgIG11c3RCZUJ1bmRsZSA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGlmIChtdXN0QmVCdW5kbGUpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkNhbm5vdCBjb252ZXJ0IHRvIFVuaWZpZWQgUGxhbiBiZWNhdXNlIG0tbGluZXMgdGhhdFwiICtcbiAgICAgICAgICAgICAgXCIgYXJlIG5vdCBidW5kbGVkIHdlcmUgZm91bmQuXCIpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8jZW5kcmVnaW9uXG5cblxuICAgIC8vI3JlZ2lvbiBDb252ZXJ0IGZyb20gUGxhbiBCIHRvIFVuaWZpZWQgUGxhbi5cblxuICAgIC8vIFVuZm9ydHVuYXRlbHksIGEgUGxhbiBCIG9mZmVyL2Fuc3dlciBkb2Vzbid0IGhhdmUgZW5vdWdoIGluZm9ybWF0aW9uIHRvXG4gICAgLy8gcmVidWlsZCBhbiBlcXVpdmFsZW50IFVuaWZpZWQgUGxhbiBvZmZlci9hbnN3ZXIuXG4gICAgLy9cbiAgICAvLyBGb3IgZXhhbXBsZSwgaWYgdGhpcyBpcyBhIGxvY2FsIGFuc3dlciAoaW4gVW5pZmllZCBQbGFuIHN0eWxlKSB0aGF0IHdlXG4gICAgLy8gY29udmVydCB0byBQbGFuIEIgcHJpb3IgdG8gaGFuZGluZyBpdCBvdmVyIHRvIHRoZSBhcHBsaWNhdGlvbiAodGhlXG4gICAgLy8gUGVlckNvbm5lY3Rpb24gd3JhcHBlciBjYWxsZWQgdXMsIGZvciBpbnN0YW5jZSwgYWZ0ZXIgYSBzdWNjZXNzZnVsXG4gICAgLy8gY3JlYXRlQW5zd2VyKSwgd2Ugd2FudCB0byByZW1lbWJlciB0aGUgbS1saW5lIGF0IHdoaWNoIHdlJ3ZlIHNlZW4gdGhlXG4gICAgLy8gKGxvY2FsKSBTU1JDLiBUaGF0J3MgYmVjYXVzZSB3aGVuIHRoZSBhcHBsaWNhdGlvbiB3YW50cyB0byBkbyBjYWxsIHRoZVxuICAgIC8vIFNMRCBtZXRob2QsIGZvcmNpbmcgdXMgdG8gZG8gdGhlIGludmVyc2UgdHJhbnNmb3JtYXRpb24gKGZyb20gUGxhbiBCIHRvXG4gICAgLy8gVW5pZmllZCBQbGFuKSwgd2UgbmVlZCB0byBrbm93IHRvIHdoaWNoIG0tbGluZSB0byBhc3NpZ24gdGhlIChsb2NhbClcbiAgICAvLyBTU1JDLiBXZSBhbHNvIG5lZWQgdG8ga25vdyBhbGwgdGhlIG90aGVyIG0tbGluZXMgdGhhdCB0aGUgb3JpZ2luYWxcbiAgICAvLyBhbnN3ZXIgaGFkIGFuZCBpbmNsdWRlIHRoZW0gaW4gdGhlIHRyYW5zZm9ybWVkIGFuc3dlciBhcyB3ZWxsLlxuICAgIC8vXG4gICAgLy8gQW5vdGhlciBleGFtcGxlIGlzIGlmIHRoaXMgaXMgYSByZW1vdGUgb2ZmZXIgdGhhdCB3ZSBjb252ZXJ0IHRvIFBsYW4gQlxuICAgIC8vIHByaW9yIHRvIGdpdmluZyBpdCB0byB0aGUgYXBwbGljYXRpb24sIHdlIHdhbnQgdG8gcmVtZW1iZXIgdGhlIG1pZCBhdFxuICAgIC8vIHdoaWNoIHdlJ3ZlIHNlZW4gdGhlIChyZW1vdGUpIFNTUkMuXG4gICAgLy9cbiAgICAvLyBJbiB0aGUgaXRlcmF0aW9uIHRoYXQgZm9sbG93cywgd2UgdXNlIHRoZSBjYWNoZWQgVW5pZmllZCBQbGFuIChpZiBpdFxuICAgIC8vIGV4aXN0cykgdG8gYXNzaWduIG1pZHMgdG8gc3NyY3MuXG5cbiAgICB2YXIgdHlwZTtcbiAgICBpZiAoZGVzYy50eXBlID09PSAnYW5zd2VyJykge1xuICAgICAgICB0eXBlID0gJ29mZmVyJztcbiAgICB9IGVsc2UgaWYgKGRlc2MudHlwZSA9PT0gJ29mZmVyJykge1xuICAgICAgICB0eXBlID0gJ2Fuc3dlcic7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVHlwZSAnXCIgKyBkZXNjLnR5cGUgKyBcIicgbm90IHN1cHBvcnRlZC5cIik7XG4gICAgfVxuXG4gICAgdmFyIGNhY2hlZDtcbiAgICBpZiAodHlwZW9mIHRoaXMuY2FjaGVbdHlwZV0gIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIGNhY2hlZCA9IHRyYW5zZm9ybS5wYXJzZSh0aGlzLmNhY2hlW3R5cGVdKTtcbiAgICB9XG5cbiAgICB2YXIgcmVjdm9ubHlTc3JjcyA9IHtcbiAgICAgICAgYXVkaW86IHt9LFxuICAgICAgICB2aWRlbzoge31cbiAgICB9O1xuXG4gICAgLy8gQSBoZWxwZXIgbWFwIHRoYXQgc2VuZHMgbWlkcyB0byBtLWxpbmUgb2JqZWN0cy4gV2UgdXNlIGl0IGxhdGVyIHRvXG4gICAgLy8gcmVidWlsZCB0aGUgVW5pZmllZCBQbGFuIHN0eWxlIHNlc3Npb24ubWVkaWEgYXJyYXkuXG4gICAgdmFyIG1pZDJ1bCA9IHt9O1xuICAgIHZhciBiSWR4ID0gMDtcbiAgICB2YXIgdUlkeCA9IDA7XG5cbiAgICB2YXIgc291cmNlczJ1bCA9IHt9O1xuXG4gICAgdmFyIGNhbmRpZGF0ZXM7XG4gICAgdmFyIGljZVVmcmFnO1xuICAgIHZhciBpY2VQd2Q7XG4gICAgdmFyIGZpbmdlcnByaW50O1xuICAgIHZhciBwYXlsb2FkcyA9IHt9O1xuICAgIHZhciBydGNwRmIgPSB7fTtcbiAgICB2YXIgcnRwID0ge307XG5cbiAgICBzZXNzaW9uLm1lZGlhLmZvckVhY2goZnVuY3Rpb24oYkxpbmUpIHtcbiAgICAgICAgaWYgKCh0eXBlb2YgYkxpbmUucnRjcE11eCAhPT0gJ3N0cmluZycgfHxcbiAgICAgICAgICAgIGJMaW5lLnJ0Y3BNdXggIT09ICdydGNwLW11eCcpICYmXG4gICAgICAgICAgICBiTGluZS5kaXJlY3Rpb24gIT09ICdpbmFjdGl2ZScpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkNhbm5vdCBjb252ZXJ0IHRvIFVuaWZpZWQgUGxhbiBiZWNhdXNlIG0tbGluZXMgXCIgK1xuICAgICAgICAgICAgICAgIFwid2l0aG91dCB0aGUgcnRjcC1tdXggYXR0cmlidXRlIHdlcmUgZm91bmQuXCIpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGJMaW5lLnR5cGUgPT09ICdhcHBsaWNhdGlvbicpIHtcbiAgICAgICAgICAgIG1pZDJ1bFtiTGluZS5taWRdID0gYkxpbmU7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICAvLyBXaXRoIHJ0Y3AtbXV4IGFuZCBidW5kbGUgYWxsIHRoZSBjaGFubmVscyBzaG91bGQgaGF2ZSB0aGUgc2FtZSBJQ0VcbiAgICAgICAgLy8gc3R1ZmYuXG4gICAgICAgIHZhciBzb3VyY2VzID0gYkxpbmUuc291cmNlcztcbiAgICAgICAgdmFyIHNzcmNHcm91cHMgPSBiTGluZS5zc3JjR3JvdXBzO1xuICAgICAgICB2YXIgcG9ydCA9IGJMaW5lLnBvcnQ7XG5cbiAgICAgICAgLyogQ2hyb21lIGFkZHMgZGlmZmVyZW50IGNhbmRpZGF0ZXMgZXZlbiB1c2luZyBidW5kbGUsIHNvIHdlIGNvbmNhdCB0aGUgY2FuZGlkYXRlcyBsaXN0ICovXG4gICAgICAgIGlmICh0eXBlb2YgYkxpbmUuY2FuZGlkYXRlcyAhPSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBjYW5kaWRhdGVzICE9ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICAgICAgY2FuZGlkYXRlcyA9IGNhbmRpZGF0ZXMuY29uY2F0KGJMaW5lLmNhbmRpZGF0ZXMpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjYW5kaWRhdGVzID0gYkxpbmUuY2FuZGlkYXRlcztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmICgodHlwZW9mIGljZVVmcmFnICE9ICd1bmRlZmluZWQnKSAmJiAodHlwZW9mIGJMaW5lLmljZVVmcmFnICE9ICd1bmRlZmluZWQnKSAmJiAoaWNlVWZyYWcgIT0gYkxpbmUuaWNlVWZyYWcpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJPbmx5IEJVTkRMRSBzdXBwb3J0ZWQsIGljZVVmcmFnIG11c3QgYmUgdGhlIHNhbWUgZm9yIGFsbCBtLWxpbmVzLlxcblwiICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBcIlxcdExhc3QgaWNlVWZyYWc6IFwiICsgaWNlVWZyYWcgKyBcIlxcblwiICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBcIlxcdE5ldyBpY2VVZnJhZzogXCIgKyBiTGluZS5pY2VVZnJhZ1xuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0eXBlb2YgYkxpbmUuaWNlVWZyYWcgIT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgICAgICBpY2VVZnJhZyA9IGJMaW5lLmljZVVmcmFnO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCh0eXBlb2YgaWNlUHdkICE9ICd1bmRlZmluZWQnKSAmJiAodHlwZW9mIGJMaW5lLmljZVB3ZCAhPSAndW5kZWZpbmVkJykgJiYgKGljZVB3ZCAhPSBiTGluZS5pY2VQd2QpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJPbmx5IEJVTkRMRSBzdXBwb3J0ZWQsIGljZVB3ZCBtdXN0IGJlIHRoZSBzYW1lIGZvciBhbGwgbS1saW5lcy5cXG5cIiArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJcXHRMYXN0IGljZVB3ZDogXCIgKyBpY2VQd2QgKyBcIlxcblwiICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBcIlxcdE5ldyBpY2VQd2Q6IFwiICsgYkxpbmUuaWNlUHdkXG4gICAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHR5cGVvZiBiTGluZS5pY2VQd2QgIT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgICAgICBpY2VQd2QgPSBiTGluZS5pY2VQd2Q7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoKHR5cGVvZiBmaW5nZXJwcmludCAhPSAndW5kZWZpbmVkJykgJiYgKHR5cGVvZiBiTGluZS5maW5nZXJwcmludCAhPSAndW5kZWZpbmVkJykgJiZcbiAgICAgICAgICAgIChmaW5nZXJwcmludC50eXBlICE9IGJMaW5lLmZpbmdlcnByaW50LnR5cGUgfHwgZmluZ2VycHJpbnQuaGFzaCAhPSBiTGluZS5maW5nZXJwcmludC5oYXNoKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiT25seSBCVU5ETEUgc3VwcG9ydGVkLCBmaW5nZXJwcmludCBtdXN0IGJlIHRoZSBzYW1lIGZvciBhbGwgbS1saW5lcy5cXG5cIiArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJcXHRMYXN0IGZpbmdlcnByaW50OiBcIiArIEpTT04uc3RyaW5naWZ5KGZpbmdlcnByaW50KSArIFwiXFxuXCIgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiXFx0TmV3IGZpbmdlcnByaW50OiBcIiArIEpTT04uc3RyaW5naWZ5KGJMaW5lLmZpbmdlcnByaW50KVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0eXBlb2YgYkxpbmUuZmluZ2VycHJpbnQgIT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgICAgICBmaW5nZXJwcmludCA9IGJMaW5lLmZpbmdlcnByaW50O1xuICAgICAgICB9XG5cbiAgICAgICAgcGF5bG9hZHNbYkxpbmUudHlwZV0gPSBiTGluZS5wYXlsb2FkcztcbiAgICAgICAgcnRjcEZiW2JMaW5lLnR5cGVdID0gYkxpbmUucnRjcEZiO1xuICAgICAgICBydHBbYkxpbmUudHlwZV0gPSBiTGluZS5ydHA7XG5cbiAgICAgICAgLy8gaW52ZXJ0ZWQgc3NyYyBncm91cCBtYXBcbiAgICAgICAgdmFyIHNzcmMyZ3JvdXAgPSB7fTtcbiAgICAgICAgaWYgKHR5cGVvZiBzc3JjR3JvdXBzICE9PSAndW5kZWZpbmVkJyAmJiBBcnJheS5pc0FycmF5KHNzcmNHcm91cHMpKSB7XG4gICAgICAgICAgICBzc3JjR3JvdXBzLmZvckVhY2goZnVuY3Rpb24gKHNzcmNHcm91cCkge1xuICAgICAgICAgICAgICAgIC8vIFhYWCBUaGlzIG1pZ2h0IGJyYWtlIGlmIGFuIFNTUkMgaXMgaW4gbW9yZSB0aGFuIG9uZSBncm91cFxuICAgICAgICAgICAgICAgIC8vIGZvciBzb21lIHJlYXNvbi5cbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHNzcmNHcm91cC5zc3JjcyAhPT0gJ3VuZGVmaW5lZCcgJiZcbiAgICAgICAgICAgICAgICAgICAgQXJyYXkuaXNBcnJheShzc3JjR3JvdXAuc3NyY3MpKSB7XG4gICAgICAgICAgICAgICAgICAgIHNzcmNHcm91cC5zc3Jjcy5mb3JFYWNoKGZ1bmN0aW9uIChzc3JjKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHNzcmMyZ3JvdXBbc3NyY10gPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3NyYzJncm91cFtzc3JjXSA9IFtdO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICBzc3JjMmdyb3VwW3NzcmNdLnB1c2goc3NyY0dyb3VwKTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBzc3JjIHRvIG0tbGluZSBpbmRleC5cbiAgICAgICAgdmFyIHNzcmMybWwgPSB7fTtcblxuICAgICAgICBpZiAodHlwZW9mIHNvdXJjZXMgPT09ICdvYmplY3QnKSB7XG5cbiAgICAgICAgICAgIC8vIFdlJ2xsIHVzZSB0aGUgXCJiTGluZVwiIG9iamVjdCBhcyBhIHByb3RvdHlwZSBmb3IgZWFjaCBuZXcgXCJtTGluZVwiXG4gICAgICAgICAgICAvLyB0aGF0IHdlIGNyZWF0ZSwgYnV0IGZpcnN0IHdlIG5lZWQgdG8gY2xlYW4gaXQgdXAgYSBiaXQuXG4gICAgICAgICAgICBkZWxldGUgYkxpbmUuc291cmNlcztcbiAgICAgICAgICAgIGRlbGV0ZSBiTGluZS5zc3JjR3JvdXBzO1xuICAgICAgICAgICAgZGVsZXRlIGJMaW5lLmNhbmRpZGF0ZXM7XG4gICAgICAgICAgICBkZWxldGUgYkxpbmUuaWNlVWZyYWc7XG4gICAgICAgICAgICBkZWxldGUgYkxpbmUuaWNlUHdkO1xuICAgICAgICAgICAgZGVsZXRlIGJMaW5lLmZpbmdlcnByaW50O1xuICAgICAgICAgICAgZGVsZXRlIGJMaW5lLnBvcnQ7XG4gICAgICAgICAgICBkZWxldGUgYkxpbmUubWlkO1xuXG4gICAgICAgICAgICAvLyBFeHBsb2RlIHRoZSBQbGFuIEIgY2hhbm5lbCBzb3VyY2VzIHdpdGggb25lIG0tbGluZSBwZXIgc291cmNlLlxuICAgICAgICAgICAgT2JqZWN0LmtleXMoc291cmNlcykuZm9yRWFjaChmdW5jdGlvbihzc3JjKSB7XG5cbiAgICAgICAgICAgICAgICAvLyBUaGUgKHVuaWZpZWQpIG0tbGluZSBmb3IgdGhpcyBTU1JDLiBXZSBlaXRoZXIgY3JlYXRlIGl0IGZyb21cbiAgICAgICAgICAgICAgICAvLyBzY3JhdGNoIG9yLCBpZiBpdCdzIGEgZ3JvdXBlZCBTU1JDLCB3ZSByZS11c2UgYSByZWxhdGVkXG4gICAgICAgICAgICAgICAgLy8gbWxpbmUuIEluIG90aGVyIHdvcmRzLCBpZiB0aGUgc291cmNlIGlzIGdyb3VwZWQgd2l0aCBhbm90aGVyXG4gICAgICAgICAgICAgICAgLy8gc291cmNlLCBwdXQgdGhlIHR3byB0b2dldGhlciBpbiB0aGUgc2FtZSBtLWxpbmUuXG4gICAgICAgICAgICAgICAgdmFyIHVMaW5lO1xuXG4gICAgICAgICAgICAgICAgLy8gV2UgYXNzdW1lIGhlcmUgdGhhdCB3ZSBhcmUgdGhlIGFuc3dlcmVyIGluIHRoZSBPL0EsIHNvIGFueVxuICAgICAgICAgICAgICAgIC8vIG9mZmVycyB3aGljaCB3ZSB0cmFuc2xhdGUgY29tZSBmcm9tIHRoZSByZW1vdGUgc2lkZSwgd2hpbGVcbiAgICAgICAgICAgICAgICAvLyBhbnN3ZXJzIGFyZSBsb2NhbC4gU28gdGhlIGNoZWNrIGJlbG93IGlzIHRvIG1ha2UgdGhhdCB3ZVxuICAgICAgICAgICAgICAgIC8vIGhhbmRsZSByZWNlaXZlLW9ubHkgU1NSQ3MgaW4gYSBzcGVjaWFsIHdheSBvbmx5IGlmIHRoZXkgY29tZVxuICAgICAgICAgICAgICAgIC8vIGZyb20gdGhlIHJlbW90ZSBzaWRlLlxuICAgICAgICAgICAgICAgIGlmIChkZXNjLnR5cGU9PT0nb2ZmZXInKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIFdlIHdhbnQgdG8gZGV0ZWN0IFNTUkNzIHdoaWNoIGFyZSB1c2VkIGJ5IGEgcmVtb3RlIHBlZXJcbiAgICAgICAgICAgICAgICAgICAgLy8gaW4gYW4gbS1saW5lIHdpdGggZGlyZWN0aW9uPXJlY3Zvbmx5IChpLmUuIHRoZXkgYXJlXG4gICAgICAgICAgICAgICAgICAgIC8vIGJlaW5nIHVzZWQgZm9yIFJUQ1Agb25seSkuXG4gICAgICAgICAgICAgICAgICAgIC8vIFRoaXMgaW5mb3JtYXRpb24gd291bGQgaGF2ZSBnb3R0ZW4gbG9zdCBpZiB0aGUgcmVtb3RlXG4gICAgICAgICAgICAgICAgICAgIC8vIHBlZXIgdXNlZCBVbmlmaWVkIFBsYW4gYW5kIHRoZWlyIGxvY2FsIGRlc2NyaXB0aW9uIHdhc1xuICAgICAgICAgICAgICAgICAgICAvLyB0cmFuc2xhdGVkIHRvIFBsYW4gQi4gU28gd2UgdXNlIHRoZSBsYWNrIG9mIGFuIE1TSURcbiAgICAgICAgICAgICAgICAgICAgLy8gYXR0cmlidXRlIHRvIGRlZHVjZSBhIFwicmVjZWl2ZSBvbmx5XCIgU1NSQy5cbiAgICAgICAgICAgICAgICAgICAgaWYgKCFzb3VyY2VzW3NzcmNdLm1zaWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlY3Zvbmx5U3NyY3NbYkxpbmUudHlwZV1bc3NyY10gPSBzb3VyY2VzW3NzcmNdO1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gUmVjZWl2ZS1vbmx5IFNTUkNzIG11c3Qgbm90IGNyZWF0ZSBuZXcgbS1saW5lcy4gV2VcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIHdpbGwgYXNzaWduIHRoZW0gdG8gYW4gZXhpc3RpbmcgbS1saW5lIGxhdGVyLlxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBzc3JjMmdyb3VwW3NzcmNdICE9PSAndW5kZWZpbmVkJyAmJlxuICAgICAgICAgICAgICAgICAgICBBcnJheS5pc0FycmF5KHNzcmMyZ3JvdXBbc3NyY10pKSB7XG4gICAgICAgICAgICAgICAgICAgIHNzcmMyZ3JvdXBbc3NyY10uc29tZShmdW5jdGlvbiAoc3NyY0dyb3VwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBzc3JjR3JvdXAuc3NyY3MgKmlzKiBhbiBBcnJheSwgbm8gbmVlZCB0byBjaGVja1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gYWdhaW4gaGVyZS5cbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBzc3JjR3JvdXAuc3NyY3Muc29tZShmdW5jdGlvbiAocmVsYXRlZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2Ygc3NyYzJtbFtyZWxhdGVkXSA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdUxpbmUgPSBzc3JjMm1sW3JlbGF0ZWRdO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiB1TGluZSA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gdGhlIG0tbGluZSBhbHJlYWR5IGV4aXN0cy4gSnVzdCBhZGQgdGhlIHNvdXJjZS5cbiAgICAgICAgICAgICAgICAgICAgdUxpbmUuc291cmNlc1tzc3JjXSA9IHNvdXJjZXNbc3NyY107XG4gICAgICAgICAgICAgICAgICAgIGRlbGV0ZSBzb3VyY2VzW3NzcmNdLm1zaWQ7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gVXNlIHRoZSBcImJMaW5lXCIgYXMgYSBwcm90b3R5cGUgZm9yIHRoZSBcInVMaW5lXCIuXG4gICAgICAgICAgICAgICAgICAgIHVMaW5lID0gT2JqZWN0LmNyZWF0ZShiTGluZSk7XG4gICAgICAgICAgICAgICAgICAgIHNzcmMybWxbc3NyY10gPSB1TGluZTtcblxuICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHNvdXJjZXNbc3NyY10ubXNpZCAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIEFzc2lnbiB0aGUgbXNpZCBvZiB0aGUgc291cmNlIHRvIHRoZSBtLWxpbmUuIE5vdGVcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRoYXQgaXQgaXMgbm90IGd1YXJhbnRlZWQgdGhhdCB0aGUgc291cmNlIHdpbGwgaGF2ZVxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gbXNpZC4gSW4gcGFydGljdWxhciBcInJlY3Zvbmx5XCIgc291cmNlcyBkb24ndCBoYXZlIGFuXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBtc2lkLiBOb3RlIHRoYXQgXCJyZWN2b25seVwiIGlzIGEgdGVybSBvbmx5IGRlZmluZWRcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGZvciBtLWxpbmVzLlxuICAgICAgICAgICAgICAgICAgICAgICAgdUxpbmUubXNpZCA9IHNvdXJjZXNbc3NyY10ubXNpZDtcbiAgICAgICAgICAgICAgICAgICAgICAgIGRlbGV0ZSBzb3VyY2VzW3NzcmNdLm1zaWQ7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAvLyBXZSBhc3NpZ24gb25lIFNTUkMgcGVyIG1lZGlhIGxpbmUuXG4gICAgICAgICAgICAgICAgICAgIHVMaW5lLnNvdXJjZXMgPSB7fTtcbiAgICAgICAgICAgICAgICAgICAgdUxpbmUuc291cmNlc1tzc3JjXSA9IHNvdXJjZXNbc3NyY107XG4gICAgICAgICAgICAgICAgICAgIHVMaW5lLnNzcmNHcm91cHMgPSBzc3JjMmdyb3VwW3NzcmNdO1xuXG4gICAgICAgICAgICAgICAgICAgIC8vIFVzZSB0aGUgY2FjaGVkIFVuaWZpZWQgUGxhbiBTRFAgKGlmIGl0IGV4aXN0cykgdG8gYXNzaWduXG4gICAgICAgICAgICAgICAgICAgIC8vIFNTUkNzIHRvIG1pZHMuXG4gICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgY2FjaGVkICE9PSAndW5kZWZpbmVkJyAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgdHlwZW9mIGNhY2hlZC5tZWRpYSAhPT0gJ3VuZGVmaW5lZCcgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgIEFycmF5LmlzQXJyYXkoY2FjaGVkLm1lZGlhKSkge1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBjYWNoZWQubWVkaWEuZm9yRWFjaChmdW5jdGlvbiAobSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgbS5zb3VyY2VzID09PSAnb2JqZWN0Jykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPYmplY3Qua2V5cyhtLnNvdXJjZXMpLmZvckVhY2goZnVuY3Rpb24gKHMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzID09PSBzc3JjKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdUxpbmUubWlkID0gbS5taWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiB1TGluZS5taWQgPT09ICd1bmRlZmluZWQnKSB7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIElmIHRoaXMgaXMgYW4gU1NSQyB0aGF0IHdlIHNlZSBmb3IgdGhlIGZpcnN0IHRpbWVcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGFzc2lnbiBpdCBhIG5ldyBtaWQuIFRoaXMgaXMgdHlwaWNhbGx5IHRoZSBjYXNlIHdoZW5cbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRoaXMgbWV0aG9kIGlzIGNhbGxlZCB0byB0cmFuc2Zvcm0gYSByZW1vdGVcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGRlc2NyaXB0aW9uIGZvciB0aGUgZmlyc3QgdGltZSBvciB3aGVuIHRoZXJlIGlzIGFcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIG5ldyBTU1JDIGluIHRoZSByZW1vdGUgZGVzY3JpcHRpb24gYmVjYXVzZSBhIG5ld1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gcGVlciBoYXMgam9pbmVkIHRoZSBjb25mZXJlbmNlLiBMb2NhbCBTU1JDcyBzaG91bGRcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGhhdmUgYWxyZWFkeSBiZWVuIGFkZGVkIHRvIHRoZSBtYXAgaW4gdGhlIHRvUGxhbkJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIG1ldGhvZC5cbiAgICAgICAgICAgICAgICAgICAgICAgIC8vXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBCZWNhdXNlIEZGIGdlbmVyYXRlcyBhbnN3ZXJzIGluIFVuaWZpZWQgUGxhbiBzdHlsZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIHdlIE1VU1QgYWxyZWFkeSBoYXZlIGEgY2FjaGVkIGFuc3dlciB3aXRoIGFsbCB0aGVcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGxvY2FsIFNTUkNzIG1hcHBlZCB0byBzb21lIG0tbGluZS9taWQuXG5cbiAgICAgICAgICAgICAgICAgICAgICAgIHVMaW5lLm1pZCA9IFtiTGluZS50eXBlLCAnLScsIHNzcmNdLmpvaW4oJycpO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgLy8gSW5jbHVkZSB0aGUgY2FuZGlkYXRlcyBpbiB0aGUgMXN0IG1lZGlhIGxpbmUuXG4gICAgICAgICAgICAgICAgICAgIHVMaW5lLmNhbmRpZGF0ZXMgPSBjYW5kaWRhdGVzO1xuICAgICAgICAgICAgICAgICAgICB1TGluZS5pY2VVZnJhZyA9IGljZVVmcmFnO1xuICAgICAgICAgICAgICAgICAgICB1TGluZS5pY2VQd2QgPSBpY2VQd2Q7XG4gICAgICAgICAgICAgICAgICAgIHVMaW5lLmZpbmdlcnByaW50ID0gZmluZ2VycHJpbnQ7XG4gICAgICAgICAgICAgICAgICAgIHVMaW5lLnBvcnQgPSBwb3J0O1xuXG4gICAgICAgICAgICAgICAgICAgIG1pZDJ1bFt1TGluZS5taWRdID0gdUxpbmU7XG4gICAgICAgICAgICAgICAgICAgIHNvdXJjZXMydWxbdUlkeF0gPSB1TGluZS5zb3VyY2VzO1xuXG4gICAgICAgICAgICAgICAgICAgIHNlbGYuY2FjaGUubWxVMkJNYXBbdUlkeF0gPSBiSWR4O1xuICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHNlbGYuY2FjaGUubWxCMlVNYXBbYklkeF0gPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgc2VsZi5jYWNoZS5tbEIyVU1hcFtiSWR4XSA9IHVJZHg7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgdUlkeCsrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHZhciB1TGluZSA9IGJMaW5lO1xuXG4gICAgICAgICAgdUxpbmUuY2FuZGlkYXRlcyA9IGNhbmRpZGF0ZXM7XG4gICAgICAgICAgdUxpbmUuaWNlVWZyYWcgPSBpY2VVZnJhZztcbiAgICAgICAgICB1TGluZS5pY2VQd2QgPSBpY2VQd2Q7XG4gICAgICAgICAgdUxpbmUuZmluZ2VycHJpbnQgPSBmaW5nZXJwcmludDtcbiAgICAgICAgICB1TGluZS5wb3J0ID0gcG9ydDtcblxuICAgICAgICAgIG1pZDJ1bFt1TGluZS5taWRdID0gdUxpbmU7XG5cbiAgICAgICAgICBzZWxmLmNhY2hlLm1sVTJCTWFwW3VJZHhdID0gYklkeDtcbiAgICAgICAgICBpZiAodHlwZW9mIHNlbGYuY2FjaGUubWxCMlVNYXBbYklkeF0gPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICBzZWxmLmNhY2hlLm1sQjJVTWFwW2JJZHhdID0gdUlkeDtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBiSWR4Kys7XG4gICAgfSk7XG5cbiAgICAvLyBSZWJ1aWxkIHRoZSBtZWRpYSBhcnJheSBpbiB0aGUgcmlnaHQgb3JkZXIgYW5kIGFkZCB0aGUgbWlzc2luZyBtTGluZXNcbiAgICAvLyAobWlzc2luZyBmcm9tIHRoZSBQbGFuIEIgU0RQKS5cbiAgICBzZXNzaW9uLm1lZGlhID0gW107XG4gICAgbWlkcyA9IFtdOyAvLyByZXVzZVxuXG4gICAgaWYgKGRlc2MudHlwZSA9PT0gJ2Fuc3dlcicpIHtcblxuICAgICAgICAvLyBUaGUgbWVkaWEgbGluZXMgaW4gdGhlIGFuc3dlciBtdXN0IG1hdGNoIHRoZSBtZWRpYSBsaW5lcyBpbiB0aGVcbiAgICAgICAgLy8gb2ZmZXIuIFRoZSBvcmRlciBpcyBpbXBvcnRhbnQgdG9vLiBIZXJlIHdlIGFzc3VtZSB0aGF0IEZpcmVmb3ggaXNcbiAgICAgICAgLy8gdGhlIGFuc3dlcmVyLCBzbyB3ZSBtZXJlbHkgaGF2ZSB0byB1c2UgdGhlIHJlY29uc3RydWN0ZWQgKHVuaWZpZWQpXG4gICAgICAgIC8vIGFuc3dlciB0byB1cGRhdGUgdGhlIGNhY2hlZCAodW5pZmllZCkgYW5zd2VyIGFjY29yZGluZ2x5LlxuICAgICAgICAvL1xuICAgICAgICAvLyBJbiB0aGUgZ2VuZXJhbCBjYXNlLCBvbmUgd291bGQgaGF2ZSB0byB1c2UgdGhlIGNhY2hlZCAodW5pZmllZClcbiAgICAgICAgLy8gb2ZmZXIgdG8gZmluZCB0aGUgbS1saW5lcyB0aGF0IGFyZSBtaXNzaW5nIGZyb20gdGhlIHJlY29uc3RydWN0ZWRcbiAgICAgICAgLy8gYW5zd2VyLCBwb3RlbnRpYWxseSBncmFiYmluZyB0aGVtIGZyb20gdGhlIGNhY2hlZCAodW5pZmllZCkgYW5zd2VyLlxuICAgICAgICAvLyBPbmUgaGFzIHRvIGJlIGNhcmVmdWwgd2l0aCB0aGlzIGFwcHJvYWNoIGJlY2F1c2UgaW5hY3RpdmUgbS1saW5lcyBkb1xuICAgICAgICAvLyBub3QgYWx3YXlzIGhhdmUgYW4gbWlkLCBtYWtpbmcgaXQgdHJpY2t5IChpbXBvc3NpYmxlPykgdG8gZmluZCB3aGVyZVxuICAgICAgICAvLyBleGFjdGx5IGFuZCB3aGljaCBtLWxpbmVzIGFyZSBtaXNzaW5nIGZyb20gdGhlIHJlY29uc3RydWN0ZWQgYW5zd2VyLlxuXG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgY2FjaGVkLm1lZGlhLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICB2YXIgdUxpbmUgPSBjYWNoZWQubWVkaWFbaV07XG5cbiAgICAgICAgICAgIGRlbGV0ZSB1TGluZS5tc2lkO1xuICAgICAgICAgICAgZGVsZXRlIHVMaW5lLnNvdXJjZXM7XG4gICAgICAgICAgICBkZWxldGUgdUxpbmUuc3NyY0dyb3VwcztcblxuICAgICAgICAgICAgaWYgKHR5cGVvZiBzb3VyY2VzMnVsW2ldID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgICBpZiAoIXVMaW5lLmRpcmVjdGlvblxuICAgICAgICAgICAgICAgICAgfHwgdUxpbmUuZGlyZWN0aW9uID09PSAnc2VuZHJlY3YnKVxuICAgICAgICAgICAgICAgICAgdUxpbmUuZGlyZWN0aW9uID0gJ3JlY3Zvbmx5JztcbiAgICAgICAgICAgICAgZWxzZSBpZiAodUxpbmUuZGlyZWN0aW9uID09PSAnc2VuZG9ubHknKVxuICAgICAgICAgICAgICAgICAgdUxpbmUuZGlyZWN0aW9uID0gJ2luYWN0aXZlJztcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIGlmICghdUxpbmUuZGlyZWN0aW9uXG4gICAgICAgICAgICAgICAgICB8fCB1TGluZS5kaXJlY3Rpb24gPT09ICdzZW5kcmVjdicpXG4gICAgICAgICAgICAgICAgICB1TGluZS5kaXJlY3Rpb24gPSAnc2VuZHJlY3YnO1xuICAgICAgICAgICAgICBlbHNlIGlmICh1TGluZS5kaXJlY3Rpb24gPT09ICdyZWN2b25seScpXG4gICAgICAgICAgICAgICAgICB1TGluZS5kaXJlY3Rpb24gPSAnc2VuZG9ubHknO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB1TGluZS5zb3VyY2VzID0gc291cmNlczJ1bFtpXTtcbiAgICAgICAgICAgIHVMaW5lLmNhbmRpZGF0ZXMgPSBjYW5kaWRhdGVzO1xuICAgICAgICAgICAgdUxpbmUuaWNlVWZyYWcgPSBpY2VVZnJhZztcbiAgICAgICAgICAgIHVMaW5lLmljZVB3ZCA9IGljZVB3ZDtcbiAgICAgICAgICAgIHVMaW5lLmZpbmdlcnByaW50ID0gZmluZ2VycHJpbnQ7XG5cbiAgICAgICAgICAgIHVMaW5lLnJ0cCA9IHJ0cFt1TGluZS50eXBlXTtcbiAgICAgICAgICAgIHVMaW5lLnBheWxvYWRzID0gcGF5bG9hZHNbdUxpbmUudHlwZV07XG4gICAgICAgICAgICB1TGluZS5ydGNwRmIgPSBydGNwRmJbdUxpbmUudHlwZV07XG5cbiAgICAgICAgICAgIHNlc3Npb24ubWVkaWEucHVzaCh1TGluZSk7XG5cbiAgICAgICAgICAgIGlmICh0eXBlb2YgdUxpbmUubWlkID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgICAgIC8vIGluYWN0aXZlIGxpbmVzIGRvbid0L21heSBub3QgaGF2ZSBhbiBtaWQuXG4gICAgICAgICAgICAgICAgbWlkcy5wdXNoKHVMaW5lLm1pZCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9IGVsc2Uge1xuXG4gICAgICAgIC8vIFNEUCBvZmZlci9hbnN3ZXIgKGFuZCB0aGUgSlNFUCBzcGVjKSBmb3JiaWRzIHJlbW92aW5nIGFuIG0tc2VjdGlvblxuICAgICAgICAvLyB1bmRlciBhbnkgY2lyY3Vtc3RhbmNlcy4gSWYgd2UgYXJlIG5vIGxvbmdlciBpbnRlcmVzdGVkIGluIHNlbmRpbmcgYVxuICAgICAgICAvLyB0cmFjaywgd2UganVzdCByZW1vdmUgdGhlIG1zaWQgYW5kIHNzcmMgYXR0cmlidXRlcyBhbmQgc2V0IGl0IHRvXG4gICAgICAgIC8vIGVpdGhlciBhPXJlY3Zvbmx5IChhcyB0aGUgcmVvZmZlcmVyLCB3ZSBtdXN0IHVzZSByZWN2b25seSBpZiB0aGVcbiAgICAgICAgLy8gb3RoZXIgc2lkZSB3YXMgcHJldmlvdXNseSBzZW5kaW5nIG9uIHRoZSBtLXNlY3Rpb24sIGJ1dCB3ZSBjYW4gYWxzb1xuICAgICAgICAvLyBsZWF2ZSB0aGUgcG9zc2liaWxpdHkgb3BlbiBpZiBpdCB3YXNuJ3QgcHJldmlvdXNseSBpbiB1c2UpLCBvclxuICAgICAgICAvLyBhPWluYWN0aXZlLlxuXG4gICAgICAgIGlmICh0eXBlb2YgY2FjaGVkICE9PSAndW5kZWZpbmVkJyAmJlxuICAgICAgICAgICAgdHlwZW9mIGNhY2hlZC5tZWRpYSAhPT0gJ3VuZGVmaW5lZCcgJiZcbiAgICAgICAgICAgIEFycmF5LmlzQXJyYXkoY2FjaGVkLm1lZGlhKSkge1xuICAgICAgICAgICAgY2FjaGVkLm1lZGlhLmZvckVhY2goZnVuY3Rpb24odUxpbmUpIHtcbiAgICAgICAgICAgICAgICBtaWRzLnB1c2godUxpbmUubWlkKTtcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIG1pZDJ1bFt1TGluZS5taWRdICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgICAgICAgICBzZXNzaW9uLm1lZGlhLnB1c2gobWlkMnVsW3VMaW5lLm1pZF0pO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGRlbGV0ZSB1TGluZS5tc2lkO1xuICAgICAgICAgICAgICAgICAgICBkZWxldGUgdUxpbmUuc291cmNlcztcbiAgICAgICAgICAgICAgICAgICAgZGVsZXRlIHVMaW5lLnNzcmNHcm91cHM7XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKCF1TGluZS5kaXJlY3Rpb25cbiAgICAgICAgICAgICAgICAgICAgICAgIHx8IHVMaW5lLmRpcmVjdGlvbiA9PT0gJ3NlbmRyZWN2Jykge1xuICAgICAgICAgICAgICAgICAgICAgICAgdUxpbmUuZGlyZWN0aW9uID0gJ3NlbmRvbmx5JztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoIXVMaW5lLmRpcmVjdGlvblxuICAgICAgICAgICAgICAgICAgICAgICAgfHwgdUxpbmUuZGlyZWN0aW9uID09PSAncmVjdm9ubHknKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB1TGluZS5kaXJlY3Rpb24gPSAnaW5hY3RpdmUnO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgYWRkU2V0dXBBdHRyICh1TGluZSk7XG4gICAgICAgICAgICAgICAgICAgIHNlc3Npb24ubWVkaWEucHVzaCh1TGluZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBBZGQgYWxsIHRoZSByZW1haW5pbmcgKG5ldykgbS1saW5lcyBvZiB0aGUgdHJhbnNmb3JtZWQgU0RQLlxuICAgICAgICBPYmplY3Qua2V5cyhtaWQydWwpLmZvckVhY2goZnVuY3Rpb24obWlkKSB7XG4gICAgICAgICAgICBpZiAobWlkcy5pbmRleE9mKG1pZCkgPT09IC0xKSB7XG4gICAgICAgICAgICAgICAgbWlkcy5wdXNoKG1pZCk7XG4gICAgICAgICAgICAgICAgaWYgKG1pZDJ1bFttaWRdLmRpcmVjdGlvbiA9PT0gJ3JlY3Zvbmx5Jykge1xuICAgICAgICAgICAgICAgICAgICAvLyBUaGlzIGlzIGEgcmVtb3RlIHJlY3Zvbmx5IGNoYW5uZWwuIEFkZCBpdHMgU1NSQyB0byB0aGVcbiAgICAgICAgICAgICAgICAgICAgLy8gYXBwcm9wcmlhdGUgc2VuZHJlY3Ygb3Igc2VuZG9ubHkgY2hhbm5lbC5cbiAgICAgICAgICAgICAgICAgICAgLy8gVE9ETyhncCkgd2hhdCBpZiB3ZSBkb24ndCBoYXZlIHNlbmRyZWN2L3NlbmRvbmx5XG4gICAgICAgICAgICAgICAgICAgIC8vIGNoYW5uZWw/XG5cbiAgICAgICAgICAgICAgICAgICAgdmFyIGRvbmUgPSBmYWxzZTtcblxuICAgICAgICAgICAgICAgICAgICBzZXNzaW9uLm1lZGlhLnNvbWUoZnVuY3Rpb24gKHVMaW5lKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoKHVMaW5lLmRpcmVjdGlvbiA9PT0gJ3NlbmRyZWN2JyB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVMaW5lLmRpcmVjdGlvbiA9PT0gJ3NlbmRvbmx5JykgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1TGluZS50eXBlID09PSBtaWQydWxbbWlkXS50eXBlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gbWlkMnVsW21pZF0gc2hvdWxkbid0IGhhdmUgYW55IHNzcmMtZ3JvdXBzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgT2JqZWN0LmtleXMobWlkMnVsW21pZF0uc291cmNlcykuZm9yRWFjaChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24gKHNzcmMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdUxpbmUuc291cmNlc1tzc3JjXSA9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtaWQydWxbbWlkXS5zb3VyY2VzW3NzcmNdO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgICAgIGlmICghZG9uZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbi5tZWRpYS5wdXNoKG1pZDJ1bFttaWRdKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHNlc3Npb24ubWVkaWEucHVzaChtaWQydWxbbWlkXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvLyBBZnRlciB3ZSBoYXZlIGNvbnN0cnVjdGVkIHRoZSBQbGFuIFVuaWZpZWQgbS1saW5lcyB3ZSBjYW4gZmlndXJlIG91dFxuICAgIC8vIHdoZXJlIChpbiB3aGljaCBtLWxpbmUpIHRvIHBsYWNlIHRoZSAncmVjdm9ubHkgU1NSQ3MnLlxuICAgIC8vIE5vdGU6IHdlIGFzc3VtZSBoZXJlIHRoYXQgd2UgYXJlIHRoZSBhbnN3ZXJlciBpbiB0aGUgTy9BLCBzbyBhbnkgb2ZmZXJzXG4gICAgLy8gd2hpY2ggd2UgdHJhbnNsYXRlIGNvbWUgZnJvbSB0aGUgcmVtb3RlIHNpZGUsIHdoaWxlIGFuc3dlcnMgYXJlIGxvY2FsXG4gICAgLy8gKGFuZCBzbyBvdXIgbGFzdCBsb2NhbCBkZXNjcmlwdGlvbiBpcyBjYWNoZWQgYXMgYW4gJ2Fuc3dlcicpLlxuICAgIFtcImF1ZGlvXCIsIFwidmlkZW9cIl0uZm9yRWFjaChmdW5jdGlvbiAodHlwZSkge1xuICAgICAgICBpZiAoIXNlc3Npb24gfHwgIXNlc3Npb24ubWVkaWEgfHwgIUFycmF5LmlzQXJyYXkoc2Vzc2lvbi5tZWRpYSkpXG4gICAgICAgICAgICByZXR1cm47XG5cbiAgICAgICAgdmFyIGlkeCA9IG51bGw7XG4gICAgICAgIGlmIChPYmplY3Qua2V5cyhyZWN2b25seVNzcmNzW3R5cGVdKS5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICBpZHggPSBzZWxmLmdldEZpcnN0U2VuZGluZ0luZGV4RnJvbUFuc3dlcih0eXBlKTtcbiAgICAgICAgICAgIGlmIChpZHggPT09IG51bGwpe1xuICAgICAgICAgICAgICAgIC8vIElmIHRoaXMgaXMgdGhlIGZpcnN0IG9mZmVyIHdlIHJlY2VpdmUsIHdlIGRvbid0IGhhdmUgYVxuICAgICAgICAgICAgICAgIC8vIGNhY2hlZCBhbnN3ZXIuIEFzc3VtZSB0aGF0IHdlIHdpbGwgYmUgc2VuZGluZyBtZWRpYSB1c2luZ1xuICAgICAgICAgICAgICAgIC8vIHRoZSBmaXJzdCBtLWxpbmUgZm9yIGVhY2ggbWVkaWEgdHlwZS5cblxuICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc2Vzc2lvbi5tZWRpYS5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgICAgICBpZiAoc2Vzc2lvbi5tZWRpYVtpXS50eXBlID09PSB0eXBlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZHggPSBpO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoaWR4ICYmIHNlc3Npb24ubWVkaWEubGVuZ3RoID4gaWR4KSB7XG4gICAgICAgICAgICB2YXIgbUxpbmUgPSBzZXNzaW9uLm1lZGlhW2lkeF07XG4gICAgICAgICAgICBPYmplY3Qua2V5cyhyZWN2b25seVNzcmNzW3R5cGVdKS5mb3JFYWNoKGZ1bmN0aW9uKHNzcmMpIHtcbiAgICAgICAgICAgICAgICBpZiAobUxpbmUuc291cmNlcyAmJiBtTGluZS5zb3VyY2VzW3NzcmNdKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybihcIlJlcGxhY2luZyBhbiBleGlzdGluZyBTU1JDLlwiKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKCFtTGluZS5zb3VyY2VzKSB7XG4gICAgICAgICAgICAgICAgICAgIG1MaW5lLnNvdXJjZXMgPSB7fTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBtTGluZS5zb3VyY2VzW3NzcmNdID0gcmVjdm9ubHlTc3Jjc1t0eXBlXVtzc3JjXTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfSk7XG5cbiAgICBpZiAodHlwZW9mIHNlc3Npb24uZ3JvdXBzICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgLy8gV2UgcmVnZW5lcmF0ZSB0aGUgQlVORExFIGdyb3VwIChzaW5jZSB3ZSByZWdlbmVyYXRlZCB0aGUgbWlkcylcbiAgICAgIHNlc3Npb24uZ3JvdXBzLnNvbWUoZnVuY3Rpb24oZ3JvdXApIHtcblx0ICBpZiAoZ3JvdXAudHlwZSA9PT0gJ0JVTkRMRScpIHtcblx0ICAgICAgZ3JvdXAubWlkcyA9IG1pZHMuam9pbignICcpO1xuXHQgICAgICByZXR1cm4gdHJ1ZTtcblx0ICB9XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvLyBtc2lkIHNlbWFudGljXG4gICAgc2Vzc2lvbi5tc2lkU2VtYW50aWMgPSB7XG4gICAgICAgIHNlbWFudGljOiAnV01TJyxcbiAgICAgICAgdG9rZW46ICcqJ1xuICAgIH07XG5cbiAgICB2YXIgcmVzU3RyID0gdHJhbnNmb3JtLndyaXRlKHNlc3Npb24pO1xuXG4gICAgLy8gQ2FjaGUgdGhlIHRyYW5zZm9ybWVkIFNEUCAoVW5pZmllZCBQbGFuKSBmb3IgbGF0ZXIgcmUtdXNlIGluIHRoaXNcbiAgICAvLyBmdW5jdGlvbi5cbiAgICB0aGlzLmNhY2hlW2Rlc2MudHlwZV0gPSByZXNTdHI7XG5cbiAgICByZXR1cm4gbmV3IFJUQ1Nlc3Npb25EZXNjcmlwdGlvbih7XG4gICAgICAgIHR5cGU6IGRlc2MudHlwZSxcbiAgICAgICAgc2RwOiByZXNTdHJcbiAgICB9KTtcblxuICAgIC8vI2VuZHJlZ2lvblxufTtcbiIsIi8qIENvcHlyaWdodCBAIDIwMTUgQXRsYXNzaWFuIFB0eSBMdGRcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKi9cblxudmFyIHRyYW5zZm9ybSA9IHJlcXVpcmUoJ3NkcC10cmFuc2Zvcm0nKTtcblxuZXhwb3J0cy53cml0ZSA9IGZ1bmN0aW9uKHNlc3Npb24sIG9wdHMpIHtcblxuICBpZiAodHlwZW9mIHNlc3Npb24gIT09ICd1bmRlZmluZWQnICYmXG4gICAgICB0eXBlb2Ygc2Vzc2lvbi5tZWRpYSAhPT0gJ3VuZGVmaW5lZCcgJiZcbiAgICAgIEFycmF5LmlzQXJyYXkoc2Vzc2lvbi5tZWRpYSkpIHtcblxuICAgIHNlc3Npb24ubWVkaWEuZm9yRWFjaChmdW5jdGlvbiAobUxpbmUpIHtcbiAgICAgIC8vIGV4cGFuZCBzb3VyY2VzIHRvIHNzcmNzXG4gICAgICBpZiAodHlwZW9mIG1MaW5lLnNvdXJjZXMgIT09ICd1bmRlZmluZWQnICYmXG4gICAgICAgIE9iamVjdC5rZXlzKG1MaW5lLnNvdXJjZXMpLmxlbmd0aCAhPT0gMCkge1xuICAgICAgICAgIG1MaW5lLnNzcmNzID0gW107XG4gICAgICAgICAgT2JqZWN0LmtleXMobUxpbmUuc291cmNlcykuZm9yRWFjaChmdW5jdGlvbiAoc3NyYykge1xuICAgICAgICAgICAgdmFyIHNvdXJjZSA9IG1MaW5lLnNvdXJjZXNbc3NyY107XG4gICAgICAgICAgICBPYmplY3Qua2V5cyhzb3VyY2UpLmZvckVhY2goZnVuY3Rpb24gKGF0dHJpYnV0ZSkge1xuICAgICAgICAgICAgICBtTGluZS5zc3Jjcy5wdXNoKHtcbiAgICAgICAgICAgICAgICBpZDogc3NyYyxcbiAgICAgICAgICAgICAgICBhdHRyaWJ1dGU6IGF0dHJpYnV0ZSxcbiAgICAgICAgICAgICAgICB2YWx1ZTogc291cmNlW2F0dHJpYnV0ZV1cbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgICBkZWxldGUgbUxpbmUuc291cmNlcztcbiAgICAgICAgfVxuXG4gICAgICAvLyBqb2luIHNzcmNzIGluIHNzcmMgZ3JvdXBzXG4gICAgICBpZiAodHlwZW9mIG1MaW5lLnNzcmNHcm91cHMgIT09ICd1bmRlZmluZWQnICYmXG4gICAgICAgIEFycmF5LmlzQXJyYXkobUxpbmUuc3NyY0dyb3VwcykpIHtcbiAgICAgICAgICBtTGluZS5zc3JjR3JvdXBzLmZvckVhY2goZnVuY3Rpb24gKHNzcmNHcm91cCkge1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBzc3JjR3JvdXAuc3NyY3MgIT09ICd1bmRlZmluZWQnICYmXG4gICAgICAgICAgICAgICAgQXJyYXkuaXNBcnJheShzc3JjR3JvdXAuc3NyY3MpKSB7XG4gICAgICAgICAgICAgIHNzcmNHcm91cC5zc3JjcyA9IHNzcmNHcm91cC5zc3Jjcy5qb2luKCcgJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIC8vIGpvaW4gZ3JvdXAgbWlkc1xuICBpZiAodHlwZW9mIHNlc3Npb24gIT09ICd1bmRlZmluZWQnICYmXG4gICAgICB0eXBlb2Ygc2Vzc2lvbi5ncm91cHMgIT09ICd1bmRlZmluZWQnICYmIEFycmF5LmlzQXJyYXkoc2Vzc2lvbi5ncm91cHMpKSB7XG5cbiAgICBzZXNzaW9uLmdyb3Vwcy5mb3JFYWNoKGZ1bmN0aW9uIChnKSB7XG4gICAgICBpZiAodHlwZW9mIGcubWlkcyAhPT0gJ3VuZGVmaW5lZCcgJiYgQXJyYXkuaXNBcnJheShnLm1pZHMpKSB7XG4gICAgICAgIGcubWlkcyA9IGcubWlkcy5qb2luKCcgJyk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICByZXR1cm4gdHJhbnNmb3JtLndyaXRlKHNlc3Npb24sIG9wdHMpO1xufTtcblxuZXhwb3J0cy5wYXJzZSA9IGZ1bmN0aW9uKHNkcCkge1xuICB2YXIgc2Vzc2lvbiA9IHRyYW5zZm9ybS5wYXJzZShzZHApO1xuXG4gIGlmICh0eXBlb2Ygc2Vzc2lvbiAhPT0gJ3VuZGVmaW5lZCcgJiYgdHlwZW9mIHNlc3Npb24ubWVkaWEgIT09ICd1bmRlZmluZWQnICYmXG4gICAgICBBcnJheS5pc0FycmF5KHNlc3Npb24ubWVkaWEpKSB7XG5cbiAgICBzZXNzaW9uLm1lZGlhLmZvckVhY2goZnVuY3Rpb24gKG1MaW5lKSB7XG4gICAgICAvLyBncm91cCBzb3VyY2VzIGF0dHJpYnV0ZXMgYnkgc3NyY1xuICAgICAgaWYgKHR5cGVvZiBtTGluZS5zc3JjcyAhPT0gJ3VuZGVmaW5lZCcgJiYgQXJyYXkuaXNBcnJheShtTGluZS5zc3JjcykpIHtcbiAgICAgICAgbUxpbmUuc291cmNlcyA9IHt9O1xuICAgICAgICBtTGluZS5zc3Jjcy5mb3JFYWNoKGZ1bmN0aW9uIChzc3JjKSB7XG4gICAgICAgICAgaWYgKCFtTGluZS5zb3VyY2VzW3NzcmMuaWRdKVxuICAgICAgICAgIG1MaW5lLnNvdXJjZXNbc3NyYy5pZF0gPSB7fTtcbiAgICAgICAgbUxpbmUuc291cmNlc1tzc3JjLmlkXVtzc3JjLmF0dHJpYnV0ZV0gPSBzc3JjLnZhbHVlO1xuICAgICAgICB9KTtcblxuICAgICAgICBkZWxldGUgbUxpbmUuc3NyY3M7XG4gICAgICB9XG5cbiAgICAgIC8vIHNwbGl0IHNzcmNzIGluIHNzcmMgZ3JvdXBzXG4gICAgICBpZiAodHlwZW9mIG1MaW5lLnNzcmNHcm91cHMgIT09ICd1bmRlZmluZWQnICYmXG4gICAgICAgIEFycmF5LmlzQXJyYXkobUxpbmUuc3NyY0dyb3VwcykpIHtcbiAgICAgICAgICBtTGluZS5zc3JjR3JvdXBzLmZvckVhY2goZnVuY3Rpb24gKHNzcmNHcm91cCkge1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBzc3JjR3JvdXAuc3NyY3MgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICAgIHNzcmNHcm91cC5zc3JjcyA9IHNzcmNHcm91cC5zc3Jjcy5zcGxpdCgnICcpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfSk7XG4gIH1cbiAgLy8gc3BsaXQgZ3JvdXAgbWlkc1xuICBpZiAodHlwZW9mIHNlc3Npb24gIT09ICd1bmRlZmluZWQnICYmXG4gICAgICB0eXBlb2Ygc2Vzc2lvbi5ncm91cHMgIT09ICd1bmRlZmluZWQnICYmIEFycmF5LmlzQXJyYXkoc2Vzc2lvbi5ncm91cHMpKSB7XG5cbiAgICBzZXNzaW9uLmdyb3Vwcy5mb3JFYWNoKGZ1bmN0aW9uIChnKSB7XG4gICAgICBpZiAodHlwZW9mIGcubWlkcyA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgZy5taWRzID0gZy5taWRzLnNwbGl0KCcgJyk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICByZXR1cm4gc2Vzc2lvbjtcbn07XG5cbiIsIiAvKiBlc2xpbnQtZW52IG5vZGUgKi9cbid1c2Ugc3RyaWN0JztcblxuLy8gU0RQIGhlbHBlcnMuXG52YXIgU0RQVXRpbHMgPSB7fTtcblxuLy8gR2VuZXJhdGUgYW4gYWxwaGFudW1lcmljIGlkZW50aWZpZXIgZm9yIGNuYW1lIG9yIG1pZHMuXG4vLyBUT0RPOiB1c2UgVVVJRHMgaW5zdGVhZD8gaHR0cHM6Ly9naXN0LmdpdGh1Yi5jb20vamVkLzk4Mjg4M1xuU0RQVXRpbHMuZ2VuZXJhdGVJZGVudGlmaWVyID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiBNYXRoLnJhbmRvbSgpLnRvU3RyaW5nKDM2KS5zdWJzdHIoMiwgMTApO1xufTtcblxuLy8gVGhlIFJUQ1AgQ05BTUUgdXNlZCBieSBhbGwgcGVlcmNvbm5lY3Rpb25zIGZyb20gdGhlIHNhbWUgSlMuXG5TRFBVdGlscy5sb2NhbENOYW1lID0gU0RQVXRpbHMuZ2VuZXJhdGVJZGVudGlmaWVyKCk7XG5cbi8vIFNwbGl0cyBTRFAgaW50byBsaW5lcywgZGVhbGluZyB3aXRoIGJvdGggQ1JMRiBhbmQgTEYuXG5TRFBVdGlscy5zcGxpdExpbmVzID0gZnVuY3Rpb24oYmxvYikge1xuICByZXR1cm4gYmxvYi50cmltKCkuc3BsaXQoJ1xcbicpLm1hcChmdW5jdGlvbihsaW5lKSB7XG4gICAgcmV0dXJuIGxpbmUudHJpbSgpO1xuICB9KTtcbn07XG4vLyBTcGxpdHMgU0RQIGludG8gc2Vzc2lvbnBhcnQgYW5kIG1lZGlhc2VjdGlvbnMuIEVuc3VyZXMgQ1JMRi5cblNEUFV0aWxzLnNwbGl0U2VjdGlvbnMgPSBmdW5jdGlvbihibG9iKSB7XG4gIHZhciBwYXJ0cyA9IGJsb2Iuc3BsaXQoJ1xcbm09Jyk7XG4gIHJldHVybiBwYXJ0cy5tYXAoZnVuY3Rpb24ocGFydCwgaW5kZXgpIHtcbiAgICByZXR1cm4gKGluZGV4ID4gMCA/ICdtPScgKyBwYXJ0IDogcGFydCkudHJpbSgpICsgJ1xcclxcbic7XG4gIH0pO1xufTtcblxuLy8gUmV0dXJucyBsaW5lcyB0aGF0IHN0YXJ0IHdpdGggYSBjZXJ0YWluIHByZWZpeC5cblNEUFV0aWxzLm1hdGNoUHJlZml4ID0gZnVuY3Rpb24oYmxvYiwgcHJlZml4KSB7XG4gIHJldHVybiBTRFBVdGlscy5zcGxpdExpbmVzKGJsb2IpLmZpbHRlcihmdW5jdGlvbihsaW5lKSB7XG4gICAgcmV0dXJuIGxpbmUuaW5kZXhPZihwcmVmaXgpID09PSAwO1xuICB9KTtcbn07XG5cbi8vIFBhcnNlcyBhbiBJQ0UgY2FuZGlkYXRlIGxpbmUuIFNhbXBsZSBpbnB1dDpcbi8vIGNhbmRpZGF0ZTo3MDI3ODYzNTAgMiB1ZHAgNDE4MTk5MDIgOC44LjguOCA2MDc2OSB0eXAgcmVsYXkgcmFkZHIgOC44LjguOFxuLy8gcnBvcnQgNTU5OTZcIlxuU0RQVXRpbHMucGFyc2VDYW5kaWRhdGUgPSBmdW5jdGlvbihsaW5lKSB7XG4gIHZhciBwYXJ0cztcbiAgLy8gUGFyc2UgYm90aCB2YXJpYW50cy5cbiAgaWYgKGxpbmUuaW5kZXhPZignYT1jYW5kaWRhdGU6JykgPT09IDApIHtcbiAgICBwYXJ0cyA9IGxpbmUuc3Vic3RyaW5nKDEyKS5zcGxpdCgnICcpO1xuICB9IGVsc2Uge1xuICAgIHBhcnRzID0gbGluZS5zdWJzdHJpbmcoMTApLnNwbGl0KCcgJyk7XG4gIH1cblxuICB2YXIgY2FuZGlkYXRlID0ge1xuICAgIGZvdW5kYXRpb246IHBhcnRzWzBdLFxuICAgIGNvbXBvbmVudDogcGFyc2VJbnQocGFydHNbMV0sIDEwKSxcbiAgICBwcm90b2NvbDogcGFydHNbMl0udG9Mb3dlckNhc2UoKSxcbiAgICBwcmlvcml0eTogcGFyc2VJbnQocGFydHNbM10sIDEwKSxcbiAgICBpcDogcGFydHNbNF0sXG4gICAgcG9ydDogcGFyc2VJbnQocGFydHNbNV0sIDEwKSxcbiAgICAvLyBza2lwIHBhcnRzWzZdID09ICd0eXAnXG4gICAgdHlwZTogcGFydHNbN11cbiAgfTtcblxuICBmb3IgKHZhciBpID0gODsgaSA8IHBhcnRzLmxlbmd0aDsgaSArPSAyKSB7XG4gICAgc3dpdGNoIChwYXJ0c1tpXSkge1xuICAgICAgY2FzZSAncmFkZHInOlxuICAgICAgICBjYW5kaWRhdGUucmVsYXRlZEFkZHJlc3MgPSBwYXJ0c1tpICsgMV07XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAncnBvcnQnOlxuICAgICAgICBjYW5kaWRhdGUucmVsYXRlZFBvcnQgPSBwYXJzZUludChwYXJ0c1tpICsgMV0sIDEwKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICd0Y3B0eXBlJzpcbiAgICAgICAgY2FuZGlkYXRlLnRjcFR5cGUgPSBwYXJ0c1tpICsgMV07XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAndWZyYWcnOlxuICAgICAgICBjYW5kaWRhdGUudWZyYWcgPSBwYXJ0c1tpICsgMV07IC8vIGZvciBiYWNrd2FyZCBjb21wYWJpbGl0eS5cbiAgICAgICAgY2FuZGlkYXRlLnVzZXJuYW1lRnJhZ21lbnQgPSBwYXJ0c1tpICsgMV07XG4gICAgICAgIGJyZWFrO1xuICAgICAgZGVmYXVsdDogLy8gZXh0ZW5zaW9uIGhhbmRsaW5nLCBpbiBwYXJ0aWN1bGFyIHVmcmFnXG4gICAgICAgIGNhbmRpZGF0ZVtwYXJ0c1tpXV0gPSBwYXJ0c1tpICsgMV07XG4gICAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuICByZXR1cm4gY2FuZGlkYXRlO1xufTtcblxuLy8gVHJhbnNsYXRlcyBhIGNhbmRpZGF0ZSBvYmplY3QgaW50byBTRFAgY2FuZGlkYXRlIGF0dHJpYnV0ZS5cblNEUFV0aWxzLndyaXRlQ2FuZGlkYXRlID0gZnVuY3Rpb24oY2FuZGlkYXRlKSB7XG4gIHZhciBzZHAgPSBbXTtcbiAgc2RwLnB1c2goY2FuZGlkYXRlLmZvdW5kYXRpb24pO1xuICBzZHAucHVzaChjYW5kaWRhdGUuY29tcG9uZW50KTtcbiAgc2RwLnB1c2goY2FuZGlkYXRlLnByb3RvY29sLnRvVXBwZXJDYXNlKCkpO1xuICBzZHAucHVzaChjYW5kaWRhdGUucHJpb3JpdHkpO1xuICBzZHAucHVzaChjYW5kaWRhdGUuaXApO1xuICBzZHAucHVzaChjYW5kaWRhdGUucG9ydCk7XG5cbiAgdmFyIHR5cGUgPSBjYW5kaWRhdGUudHlwZTtcbiAgc2RwLnB1c2goJ3R5cCcpO1xuICBzZHAucHVzaCh0eXBlKTtcbiAgaWYgKHR5cGUgIT09ICdob3N0JyAmJiBjYW5kaWRhdGUucmVsYXRlZEFkZHJlc3MgJiZcbiAgICAgIGNhbmRpZGF0ZS5yZWxhdGVkUG9ydCkge1xuICAgIHNkcC5wdXNoKCdyYWRkcicpO1xuICAgIHNkcC5wdXNoKGNhbmRpZGF0ZS5yZWxhdGVkQWRkcmVzcyk7IC8vIHdhczogcmVsQWRkclxuICAgIHNkcC5wdXNoKCdycG9ydCcpO1xuICAgIHNkcC5wdXNoKGNhbmRpZGF0ZS5yZWxhdGVkUG9ydCk7IC8vIHdhczogcmVsUG9ydFxuICB9XG4gIGlmIChjYW5kaWRhdGUudGNwVHlwZSAmJiBjYW5kaWRhdGUucHJvdG9jb2wudG9Mb3dlckNhc2UoKSA9PT0gJ3RjcCcpIHtcbiAgICBzZHAucHVzaCgndGNwdHlwZScpO1xuICAgIHNkcC5wdXNoKGNhbmRpZGF0ZS50Y3BUeXBlKTtcbiAgfVxuICBpZiAoY2FuZGlkYXRlLnVmcmFnKSB7XG4gICAgc2RwLnB1c2goJ3VmcmFnJyk7XG4gICAgc2RwLnB1c2goY2FuZGlkYXRlLnVmcmFnKTtcbiAgfVxuICByZXR1cm4gJ2NhbmRpZGF0ZTonICsgc2RwLmpvaW4oJyAnKTtcbn07XG5cbi8vIFBhcnNlcyBhbiBpY2Utb3B0aW9ucyBsaW5lLCByZXR1cm5zIGFuIGFycmF5IG9mIG9wdGlvbiB0YWdzLlxuLy8gYT1pY2Utb3B0aW9uczpmb28gYmFyXG5TRFBVdGlscy5wYXJzZUljZU9wdGlvbnMgPSBmdW5jdGlvbihsaW5lKSB7XG4gIHJldHVybiBsaW5lLnN1YnN0cigxNCkuc3BsaXQoJyAnKTtcbn1cblxuLy8gUGFyc2VzIGFuIHJ0cG1hcCBsaW5lLCByZXR1cm5zIFJUQ1J0cENvZGRlY1BhcmFtZXRlcnMuIFNhbXBsZSBpbnB1dDpcbi8vIGE9cnRwbWFwOjExMSBvcHVzLzQ4MDAwLzJcblNEUFV0aWxzLnBhcnNlUnRwTWFwID0gZnVuY3Rpb24obGluZSkge1xuICB2YXIgcGFydHMgPSBsaW5lLnN1YnN0cig5KS5zcGxpdCgnICcpO1xuICB2YXIgcGFyc2VkID0ge1xuICAgIHBheWxvYWRUeXBlOiBwYXJzZUludChwYXJ0cy5zaGlmdCgpLCAxMCkgLy8gd2FzOiBpZFxuICB9O1xuXG4gIHBhcnRzID0gcGFydHNbMF0uc3BsaXQoJy8nKTtcblxuICBwYXJzZWQubmFtZSA9IHBhcnRzWzBdO1xuICBwYXJzZWQuY2xvY2tSYXRlID0gcGFyc2VJbnQocGFydHNbMV0sIDEwKTsgLy8gd2FzOiBjbG9ja3JhdGVcbiAgLy8gd2FzOiBjaGFubmVsc1xuICBwYXJzZWQubnVtQ2hhbm5lbHMgPSBwYXJ0cy5sZW5ndGggPT09IDMgPyBwYXJzZUludChwYXJ0c1syXSwgMTApIDogMTtcbiAgcmV0dXJuIHBhcnNlZDtcbn07XG5cbi8vIEdlbmVyYXRlIGFuIGE9cnRwbWFwIGxpbmUgZnJvbSBSVENSdHBDb2RlY0NhcGFiaWxpdHkgb3Jcbi8vIFJUQ1J0cENvZGVjUGFyYW1ldGVycy5cblNEUFV0aWxzLndyaXRlUnRwTWFwID0gZnVuY3Rpb24oY29kZWMpIHtcbiAgdmFyIHB0ID0gY29kZWMucGF5bG9hZFR5cGU7XG4gIGlmIChjb2RlYy5wcmVmZXJyZWRQYXlsb2FkVHlwZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgcHQgPSBjb2RlYy5wcmVmZXJyZWRQYXlsb2FkVHlwZTtcbiAgfVxuICByZXR1cm4gJ2E9cnRwbWFwOicgKyBwdCArICcgJyArIGNvZGVjLm5hbWUgKyAnLycgKyBjb2RlYy5jbG9ja1JhdGUgK1xuICAgICAgKGNvZGVjLm51bUNoYW5uZWxzICE9PSAxID8gJy8nICsgY29kZWMubnVtQ2hhbm5lbHMgOiAnJykgKyAnXFxyXFxuJztcbn07XG5cbi8vIFBhcnNlcyBhbiBhPWV4dG1hcCBsaW5lIChoZWFkZXJleHRlbnNpb24gZnJvbSBSRkMgNTI4NSkuIFNhbXBsZSBpbnB1dDpcbi8vIGE9ZXh0bWFwOjIgdXJuOmlldGY6cGFyYW1zOnJ0cC1oZHJleHQ6dG9mZnNldFxuLy8gYT1leHRtYXA6Mi9zZW5kb25seSB1cm46aWV0ZjpwYXJhbXM6cnRwLWhkcmV4dDp0b2Zmc2V0XG5TRFBVdGlscy5wYXJzZUV4dG1hcCA9IGZ1bmN0aW9uKGxpbmUpIHtcbiAgdmFyIHBhcnRzID0gbGluZS5zdWJzdHIoOSkuc3BsaXQoJyAnKTtcbiAgcmV0dXJuIHtcbiAgICBpZDogcGFyc2VJbnQocGFydHNbMF0sIDEwKSxcbiAgICBkaXJlY3Rpb246IHBhcnRzWzBdLmluZGV4T2YoJy8nKSA+IDAgPyBwYXJ0c1swXS5zcGxpdCgnLycpWzFdIDogJ3NlbmRyZWN2JyxcbiAgICB1cmk6IHBhcnRzWzFdXG4gIH07XG59O1xuXG4vLyBHZW5lcmF0ZXMgYT1leHRtYXAgbGluZSBmcm9tIFJUQ1J0cEhlYWRlckV4dGVuc2lvblBhcmFtZXRlcnMgb3Jcbi8vIFJUQ1J0cEhlYWRlckV4dGVuc2lvbi5cblNEUFV0aWxzLndyaXRlRXh0bWFwID0gZnVuY3Rpb24oaGVhZGVyRXh0ZW5zaW9uKSB7XG4gIHJldHVybiAnYT1leHRtYXA6JyArIChoZWFkZXJFeHRlbnNpb24uaWQgfHwgaGVhZGVyRXh0ZW5zaW9uLnByZWZlcnJlZElkKSArXG4gICAgICAoaGVhZGVyRXh0ZW5zaW9uLmRpcmVjdGlvbiAmJiBoZWFkZXJFeHRlbnNpb24uZGlyZWN0aW9uICE9PSAnc2VuZHJlY3YnXG4gICAgICAgICAgPyAnLycgKyBoZWFkZXJFeHRlbnNpb24uZGlyZWN0aW9uXG4gICAgICAgICAgOiAnJykgK1xuICAgICAgJyAnICsgaGVhZGVyRXh0ZW5zaW9uLnVyaSArICdcXHJcXG4nO1xufTtcblxuLy8gUGFyc2VzIGFuIGZ0bXAgbGluZSwgcmV0dXJucyBkaWN0aW9uYXJ5LiBTYW1wbGUgaW5wdXQ6XG4vLyBhPWZtdHA6OTYgdmJyPW9uO2NuZz1vblxuLy8gQWxzbyBkZWFscyB3aXRoIHZicj1vbjsgY25nPW9uXG5TRFBVdGlscy5wYXJzZUZtdHAgPSBmdW5jdGlvbihsaW5lKSB7XG4gIHZhciBwYXJzZWQgPSB7fTtcbiAgdmFyIGt2O1xuICB2YXIgcGFydHMgPSBsaW5lLnN1YnN0cihsaW5lLmluZGV4T2YoJyAnKSArIDEpLnNwbGl0KCc7Jyk7XG4gIGZvciAodmFyIGogPSAwOyBqIDwgcGFydHMubGVuZ3RoOyBqKyspIHtcbiAgICBrdiA9IHBhcnRzW2pdLnRyaW0oKS5zcGxpdCgnPScpO1xuICAgIHBhcnNlZFtrdlswXS50cmltKCldID0ga3ZbMV07XG4gIH1cbiAgcmV0dXJuIHBhcnNlZDtcbn07XG5cbi8vIEdlbmVyYXRlcyBhbiBhPWZ0bXAgbGluZSBmcm9tIFJUQ1J0cENvZGVjQ2FwYWJpbGl0eSBvciBSVENSdHBDb2RlY1BhcmFtZXRlcnMuXG5TRFBVdGlscy53cml0ZUZtdHAgPSBmdW5jdGlvbihjb2RlYykge1xuICB2YXIgbGluZSA9ICcnO1xuICB2YXIgcHQgPSBjb2RlYy5wYXlsb2FkVHlwZTtcbiAgaWYgKGNvZGVjLnByZWZlcnJlZFBheWxvYWRUeXBlICE9PSB1bmRlZmluZWQpIHtcbiAgICBwdCA9IGNvZGVjLnByZWZlcnJlZFBheWxvYWRUeXBlO1xuICB9XG4gIGlmIChjb2RlYy5wYXJhbWV0ZXJzICYmIE9iamVjdC5rZXlzKGNvZGVjLnBhcmFtZXRlcnMpLmxlbmd0aCkge1xuICAgIHZhciBwYXJhbXMgPSBbXTtcbiAgICBPYmplY3Qua2V5cyhjb2RlYy5wYXJhbWV0ZXJzKS5mb3JFYWNoKGZ1bmN0aW9uKHBhcmFtKSB7XG4gICAgICBwYXJhbXMucHVzaChwYXJhbSArICc9JyArIGNvZGVjLnBhcmFtZXRlcnNbcGFyYW1dKTtcbiAgICB9KTtcbiAgICBsaW5lICs9ICdhPWZtdHA6JyArIHB0ICsgJyAnICsgcGFyYW1zLmpvaW4oJzsnKSArICdcXHJcXG4nO1xuICB9XG4gIHJldHVybiBsaW5lO1xufTtcblxuLy8gUGFyc2VzIGFuIHJ0Y3AtZmIgbGluZSwgcmV0dXJucyBSVENQUnRjcEZlZWRiYWNrIG9iamVjdC4gU2FtcGxlIGlucHV0OlxuLy8gYT1ydGNwLWZiOjk4IG5hY2sgcnBzaVxuU0RQVXRpbHMucGFyc2VSdGNwRmIgPSBmdW5jdGlvbihsaW5lKSB7XG4gIHZhciBwYXJ0cyA9IGxpbmUuc3Vic3RyKGxpbmUuaW5kZXhPZignICcpICsgMSkuc3BsaXQoJyAnKTtcbiAgcmV0dXJuIHtcbiAgICB0eXBlOiBwYXJ0cy5zaGlmdCgpLFxuICAgIHBhcmFtZXRlcjogcGFydHMuam9pbignICcpXG4gIH07XG59O1xuLy8gR2VuZXJhdGUgYT1ydGNwLWZiIGxpbmVzIGZyb20gUlRDUnRwQ29kZWNDYXBhYmlsaXR5IG9yIFJUQ1J0cENvZGVjUGFyYW1ldGVycy5cblNEUFV0aWxzLndyaXRlUnRjcEZiID0gZnVuY3Rpb24oY29kZWMpIHtcbiAgdmFyIGxpbmVzID0gJyc7XG4gIHZhciBwdCA9IGNvZGVjLnBheWxvYWRUeXBlO1xuICBpZiAoY29kZWMucHJlZmVycmVkUGF5bG9hZFR5cGUgIT09IHVuZGVmaW5lZCkge1xuICAgIHB0ID0gY29kZWMucHJlZmVycmVkUGF5bG9hZFR5cGU7XG4gIH1cbiAgaWYgKGNvZGVjLnJ0Y3BGZWVkYmFjayAmJiBjb2RlYy5ydGNwRmVlZGJhY2subGVuZ3RoKSB7XG4gICAgLy8gRklYTUU6IHNwZWNpYWwgaGFuZGxpbmcgZm9yIHRyci1pbnQ/XG4gICAgY29kZWMucnRjcEZlZWRiYWNrLmZvckVhY2goZnVuY3Rpb24oZmIpIHtcbiAgICAgIGxpbmVzICs9ICdhPXJ0Y3AtZmI6JyArIHB0ICsgJyAnICsgZmIudHlwZSArXG4gICAgICAoZmIucGFyYW1ldGVyICYmIGZiLnBhcmFtZXRlci5sZW5ndGggPyAnICcgKyBmYi5wYXJhbWV0ZXIgOiAnJykgK1xuICAgICAgICAgICdcXHJcXG4nO1xuICAgIH0pO1xuICB9XG4gIHJldHVybiBsaW5lcztcbn07XG5cbi8vIFBhcnNlcyBhbiBSRkMgNTU3NiBzc3JjIG1lZGlhIGF0dHJpYnV0ZS4gU2FtcGxlIGlucHV0OlxuLy8gYT1zc3JjOjM3MzU5Mjg1NTkgY25hbWU6c29tZXRoaW5nXG5TRFBVdGlscy5wYXJzZVNzcmNNZWRpYSA9IGZ1bmN0aW9uKGxpbmUpIHtcbiAgdmFyIHNwID0gbGluZS5pbmRleE9mKCcgJyk7XG4gIHZhciBwYXJ0cyA9IHtcbiAgICBzc3JjOiBwYXJzZUludChsaW5lLnN1YnN0cig3LCBzcCAtIDcpLCAxMClcbiAgfTtcbiAgdmFyIGNvbG9uID0gbGluZS5pbmRleE9mKCc6Jywgc3ApO1xuICBpZiAoY29sb24gPiAtMSkge1xuICAgIHBhcnRzLmF0dHJpYnV0ZSA9IGxpbmUuc3Vic3RyKHNwICsgMSwgY29sb24gLSBzcCAtIDEpO1xuICAgIHBhcnRzLnZhbHVlID0gbGluZS5zdWJzdHIoY29sb24gKyAxKTtcbiAgfSBlbHNlIHtcbiAgICBwYXJ0cy5hdHRyaWJ1dGUgPSBsaW5lLnN1YnN0cihzcCArIDEpO1xuICB9XG4gIHJldHVybiBwYXJ0cztcbn07XG5cbi8vIEV4dHJhY3RzIHRoZSBNSUQgKFJGQyA1ODg4KSBmcm9tIGEgbWVkaWEgc2VjdGlvbi5cbi8vIHJldHVybnMgdGhlIE1JRCBvciB1bmRlZmluZWQgaWYgbm8gbWlkIGxpbmUgd2FzIGZvdW5kLlxuU0RQVXRpbHMuZ2V0TWlkID0gZnVuY3Rpb24obWVkaWFTZWN0aW9uKSB7XG4gIHZhciBtaWQgPSBTRFBVdGlscy5tYXRjaFByZWZpeChtZWRpYVNlY3Rpb24sICdhPW1pZDonKVswXTtcbiAgaWYgKG1pZCkge1xuICAgIHJldHVybiBtaWQuc3Vic3RyKDYpO1xuICB9XG59XG5cblNEUFV0aWxzLnBhcnNlRmluZ2VycHJpbnQgPSBmdW5jdGlvbihsaW5lKSB7XG4gIHZhciBwYXJ0cyA9IGxpbmUuc3Vic3RyKDE0KS5zcGxpdCgnICcpO1xuICByZXR1cm4ge1xuICAgIGFsZ29yaXRobTogcGFydHNbMF0udG9Mb3dlckNhc2UoKSwgLy8gYWxnb3JpdGhtIGlzIGNhc2Utc2Vuc2l0aXZlIGluIEVkZ2UuXG4gICAgdmFsdWU6IHBhcnRzWzFdXG4gIH07XG59O1xuXG4vLyBFeHRyYWN0cyBEVExTIHBhcmFtZXRlcnMgZnJvbSBTRFAgbWVkaWEgc2VjdGlvbiBvciBzZXNzaW9ucGFydC5cbi8vIEZJWE1FOiBmb3IgY29uc2lzdGVuY3kgd2l0aCBvdGhlciBmdW5jdGlvbnMgdGhpcyBzaG91bGQgb25seVxuLy8gICBnZXQgdGhlIGZpbmdlcnByaW50IGxpbmUgYXMgaW5wdXQuIFNlZSBhbHNvIGdldEljZVBhcmFtZXRlcnMuXG5TRFBVdGlscy5nZXREdGxzUGFyYW1ldGVycyA9IGZ1bmN0aW9uKG1lZGlhU2VjdGlvbiwgc2Vzc2lvbnBhcnQpIHtcbiAgdmFyIGxpbmVzID0gU0RQVXRpbHMubWF0Y2hQcmVmaXgobWVkaWFTZWN0aW9uICsgc2Vzc2lvbnBhcnQsXG4gICAgICAnYT1maW5nZXJwcmludDonKTtcbiAgLy8gTm90ZTogYT1zZXR1cCBsaW5lIGlzIGlnbm9yZWQgc2luY2Ugd2UgdXNlIHRoZSAnYXV0bycgcm9sZS5cbiAgLy8gTm90ZTI6ICdhbGdvcml0aG0nIGlzIG5vdCBjYXNlIHNlbnNpdGl2ZSBleGNlcHQgaW4gRWRnZS5cbiAgcmV0dXJuIHtcbiAgICByb2xlOiAnYXV0bycsXG4gICAgZmluZ2VycHJpbnRzOiBsaW5lcy5tYXAoU0RQVXRpbHMucGFyc2VGaW5nZXJwcmludClcbiAgfTtcbn07XG5cbi8vIFNlcmlhbGl6ZXMgRFRMUyBwYXJhbWV0ZXJzIHRvIFNEUC5cblNEUFV0aWxzLndyaXRlRHRsc1BhcmFtZXRlcnMgPSBmdW5jdGlvbihwYXJhbXMsIHNldHVwVHlwZSkge1xuICB2YXIgc2RwID0gJ2E9c2V0dXA6JyArIHNldHVwVHlwZSArICdcXHJcXG4nO1xuICBwYXJhbXMuZmluZ2VycHJpbnRzLmZvckVhY2goZnVuY3Rpb24oZnApIHtcbiAgICBzZHAgKz0gJ2E9ZmluZ2VycHJpbnQ6JyArIGZwLmFsZ29yaXRobSArICcgJyArIGZwLnZhbHVlICsgJ1xcclxcbic7XG4gIH0pO1xuICByZXR1cm4gc2RwO1xufTtcbi8vIFBhcnNlcyBJQ0UgaW5mb3JtYXRpb24gZnJvbSBTRFAgbWVkaWEgc2VjdGlvbiBvciBzZXNzaW9ucGFydC5cbi8vIEZJWE1FOiBmb3IgY29uc2lzdGVuY3kgd2l0aCBvdGhlciBmdW5jdGlvbnMgdGhpcyBzaG91bGQgb25seVxuLy8gICBnZXQgdGhlIGljZS11ZnJhZyBhbmQgaWNlLXB3ZCBsaW5lcyBhcyBpbnB1dC5cblNEUFV0aWxzLmdldEljZVBhcmFtZXRlcnMgPSBmdW5jdGlvbihtZWRpYVNlY3Rpb24sIHNlc3Npb25wYXJ0KSB7XG4gIHZhciBsaW5lcyA9IFNEUFV0aWxzLnNwbGl0TGluZXMobWVkaWFTZWN0aW9uKTtcbiAgLy8gU2VhcmNoIGluIHNlc3Npb24gcGFydCwgdG9vLlxuICBsaW5lcyA9IGxpbmVzLmNvbmNhdChTRFBVdGlscy5zcGxpdExpbmVzKHNlc3Npb25wYXJ0KSk7XG4gIHZhciBpY2VQYXJhbWV0ZXJzID0ge1xuICAgIHVzZXJuYW1lRnJhZ21lbnQ6IGxpbmVzLmZpbHRlcihmdW5jdGlvbihsaW5lKSB7XG4gICAgICByZXR1cm4gbGluZS5pbmRleE9mKCdhPWljZS11ZnJhZzonKSA9PT0gMDtcbiAgICB9KVswXS5zdWJzdHIoMTIpLFxuICAgIHBhc3N3b3JkOiBsaW5lcy5maWx0ZXIoZnVuY3Rpb24obGluZSkge1xuICAgICAgcmV0dXJuIGxpbmUuaW5kZXhPZignYT1pY2UtcHdkOicpID09PSAwO1xuICAgIH0pWzBdLnN1YnN0cigxMClcbiAgfTtcbiAgcmV0dXJuIGljZVBhcmFtZXRlcnM7XG59O1xuXG4vLyBTZXJpYWxpemVzIElDRSBwYXJhbWV0ZXJzIHRvIFNEUC5cblNEUFV0aWxzLndyaXRlSWNlUGFyYW1ldGVycyA9IGZ1bmN0aW9uKHBhcmFtcykge1xuICByZXR1cm4gJ2E9aWNlLXVmcmFnOicgKyBwYXJhbXMudXNlcm5hbWVGcmFnbWVudCArICdcXHJcXG4nICtcbiAgICAgICdhPWljZS1wd2Q6JyArIHBhcmFtcy5wYXNzd29yZCArICdcXHJcXG4nO1xufTtcblxuLy8gUGFyc2VzIHRoZSBTRFAgbWVkaWEgc2VjdGlvbiBhbmQgcmV0dXJucyBSVENSdHBQYXJhbWV0ZXJzLlxuU0RQVXRpbHMucGFyc2VSdHBQYXJhbWV0ZXJzID0gZnVuY3Rpb24obWVkaWFTZWN0aW9uKSB7XG4gIHZhciBkZXNjcmlwdGlvbiA9IHtcbiAgICBjb2RlY3M6IFtdLFxuICAgIGhlYWRlckV4dGVuc2lvbnM6IFtdLFxuICAgIGZlY01lY2hhbmlzbXM6IFtdLFxuICAgIHJ0Y3A6IFtdXG4gIH07XG4gIHZhciBsaW5lcyA9IFNEUFV0aWxzLnNwbGl0TGluZXMobWVkaWFTZWN0aW9uKTtcbiAgdmFyIG1saW5lID0gbGluZXNbMF0uc3BsaXQoJyAnKTtcbiAgZm9yICh2YXIgaSA9IDM7IGkgPCBtbGluZS5sZW5ndGg7IGkrKykgeyAvLyBmaW5kIGFsbCBjb2RlY3MgZnJvbSBtbGluZVszLi5dXG4gICAgdmFyIHB0ID0gbWxpbmVbaV07XG4gICAgdmFyIHJ0cG1hcGxpbmUgPSBTRFBVdGlscy5tYXRjaFByZWZpeChcbiAgICAgICAgbWVkaWFTZWN0aW9uLCAnYT1ydHBtYXA6JyArIHB0ICsgJyAnKVswXTtcbiAgICBpZiAocnRwbWFwbGluZSkge1xuICAgICAgdmFyIGNvZGVjID0gU0RQVXRpbHMucGFyc2VSdHBNYXAocnRwbWFwbGluZSk7XG4gICAgICB2YXIgZm10cHMgPSBTRFBVdGlscy5tYXRjaFByZWZpeChcbiAgICAgICAgICBtZWRpYVNlY3Rpb24sICdhPWZtdHA6JyArIHB0ICsgJyAnKTtcbiAgICAgIC8vIE9ubHkgdGhlIGZpcnN0IGE9Zm10cDo8cHQ+IGlzIGNvbnNpZGVyZWQuXG4gICAgICBjb2RlYy5wYXJhbWV0ZXJzID0gZm10cHMubGVuZ3RoID8gU0RQVXRpbHMucGFyc2VGbXRwKGZtdHBzWzBdKSA6IHt9O1xuICAgICAgY29kZWMucnRjcEZlZWRiYWNrID0gU0RQVXRpbHMubWF0Y2hQcmVmaXgoXG4gICAgICAgICAgbWVkaWFTZWN0aW9uLCAnYT1ydGNwLWZiOicgKyBwdCArICcgJylcbiAgICAgICAgLm1hcChTRFBVdGlscy5wYXJzZVJ0Y3BGYik7XG4gICAgICBkZXNjcmlwdGlvbi5jb2RlY3MucHVzaChjb2RlYyk7XG4gICAgICAvLyBwYXJzZSBGRUMgbWVjaGFuaXNtcyBmcm9tIHJ0cG1hcCBsaW5lcy5cbiAgICAgIHN3aXRjaCAoY29kZWMubmFtZS50b1VwcGVyQ2FzZSgpKSB7XG4gICAgICAgIGNhc2UgJ1JFRCc6XG4gICAgICAgIGNhc2UgJ1VMUEZFQyc6XG4gICAgICAgICAgZGVzY3JpcHRpb24uZmVjTWVjaGFuaXNtcy5wdXNoKGNvZGVjLm5hbWUudG9VcHBlckNhc2UoKSk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGRlZmF1bHQ6IC8vIG9ubHkgUkVEIGFuZCBVTFBGRUMgYXJlIHJlY29nbml6ZWQgYXMgRkVDIG1lY2hhbmlzbXMuXG4gICAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIFNEUFV0aWxzLm1hdGNoUHJlZml4KG1lZGlhU2VjdGlvbiwgJ2E9ZXh0bWFwOicpLmZvckVhY2goZnVuY3Rpb24obGluZSkge1xuICAgIGRlc2NyaXB0aW9uLmhlYWRlckV4dGVuc2lvbnMucHVzaChTRFBVdGlscy5wYXJzZUV4dG1hcChsaW5lKSk7XG4gIH0pO1xuICAvLyBGSVhNRTogcGFyc2UgcnRjcC5cbiAgcmV0dXJuIGRlc2NyaXB0aW9uO1xufTtcblxuLy8gR2VuZXJhdGVzIHBhcnRzIG9mIHRoZSBTRFAgbWVkaWEgc2VjdGlvbiBkZXNjcmliaW5nIHRoZSBjYXBhYmlsaXRpZXMgL1xuLy8gcGFyYW1ldGVycy5cblNEUFV0aWxzLndyaXRlUnRwRGVzY3JpcHRpb24gPSBmdW5jdGlvbihraW5kLCBjYXBzKSB7XG4gIHZhciBzZHAgPSAnJztcblxuICAvLyBCdWlsZCB0aGUgbWxpbmUuXG4gIHNkcCArPSAnbT0nICsga2luZCArICcgJztcbiAgc2RwICs9IGNhcHMuY29kZWNzLmxlbmd0aCA+IDAgPyAnOScgOiAnMCc7IC8vIHJlamVjdCBpZiBubyBjb2RlY3MuXG4gIHNkcCArPSAnIFVEUC9UTFMvUlRQL1NBVlBGICc7XG4gIHNkcCArPSBjYXBzLmNvZGVjcy5tYXAoZnVuY3Rpb24oY29kZWMpIHtcbiAgICBpZiAoY29kZWMucHJlZmVycmVkUGF5bG9hZFR5cGUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuIGNvZGVjLnByZWZlcnJlZFBheWxvYWRUeXBlO1xuICAgIH1cbiAgICByZXR1cm4gY29kZWMucGF5bG9hZFR5cGU7XG4gIH0pLmpvaW4oJyAnKSArICdcXHJcXG4nO1xuXG4gIHNkcCArPSAnYz1JTiBJUDQgMC4wLjAuMFxcclxcbic7XG4gIHNkcCArPSAnYT1ydGNwOjkgSU4gSVA0IDAuMC4wLjBcXHJcXG4nO1xuXG4gIC8vIEFkZCBhPXJ0cG1hcCBsaW5lcyBmb3IgZWFjaCBjb2RlYy4gQWxzbyBmbXRwIGFuZCBydGNwLWZiLlxuICBjYXBzLmNvZGVjcy5mb3JFYWNoKGZ1bmN0aW9uKGNvZGVjKSB7XG4gICAgc2RwICs9IFNEUFV0aWxzLndyaXRlUnRwTWFwKGNvZGVjKTtcbiAgICBzZHAgKz0gU0RQVXRpbHMud3JpdGVGbXRwKGNvZGVjKTtcbiAgICBzZHAgKz0gU0RQVXRpbHMud3JpdGVSdGNwRmIoY29kZWMpO1xuICB9KTtcbiAgdmFyIG1heHB0aW1lID0gMDtcbiAgY2Fwcy5jb2RlY3MuZm9yRWFjaChmdW5jdGlvbihjb2RlYykge1xuICAgIGlmIChjb2RlYy5tYXhwdGltZSA+IG1heHB0aW1lKSB7XG4gICAgICBtYXhwdGltZSA9IGNvZGVjLm1heHB0aW1lO1xuICAgIH1cbiAgfSk7XG4gIGlmIChtYXhwdGltZSA+IDApIHtcbiAgICBzZHAgKz0gJ2E9bWF4cHRpbWU6JyArIG1heHB0aW1lICsgJ1xcclxcbic7XG4gIH1cbiAgc2RwICs9ICdhPXJ0Y3AtbXV4XFxyXFxuJztcblxuICBjYXBzLmhlYWRlckV4dGVuc2lvbnMuZm9yRWFjaChmdW5jdGlvbihleHRlbnNpb24pIHtcbiAgICBzZHAgKz0gU0RQVXRpbHMud3JpdGVFeHRtYXAoZXh0ZW5zaW9uKTtcbiAgfSk7XG4gIC8vIEZJWE1FOiB3cml0ZSBmZWNNZWNoYW5pc21zLlxuICByZXR1cm4gc2RwO1xufTtcblxuLy8gUGFyc2VzIHRoZSBTRFAgbWVkaWEgc2VjdGlvbiBhbmQgcmV0dXJucyBhbiBhcnJheSBvZlxuLy8gUlRDUnRwRW5jb2RpbmdQYXJhbWV0ZXJzLlxuU0RQVXRpbHMucGFyc2VSdHBFbmNvZGluZ1BhcmFtZXRlcnMgPSBmdW5jdGlvbihtZWRpYVNlY3Rpb24pIHtcbiAgdmFyIGVuY29kaW5nUGFyYW1ldGVycyA9IFtdO1xuICB2YXIgZGVzY3JpcHRpb24gPSBTRFBVdGlscy5wYXJzZVJ0cFBhcmFtZXRlcnMobWVkaWFTZWN0aW9uKTtcbiAgdmFyIGhhc1JlZCA9IGRlc2NyaXB0aW9uLmZlY01lY2hhbmlzbXMuaW5kZXhPZignUkVEJykgIT09IC0xO1xuICB2YXIgaGFzVWxwZmVjID0gZGVzY3JpcHRpb24uZmVjTWVjaGFuaXNtcy5pbmRleE9mKCdVTFBGRUMnKSAhPT0gLTE7XG5cbiAgLy8gZmlsdGVyIGE9c3NyYzouLi4gY25hbWU6LCBpZ25vcmUgUGxhbkItbXNpZFxuICB2YXIgc3NyY3MgPSBTRFBVdGlscy5tYXRjaFByZWZpeChtZWRpYVNlY3Rpb24sICdhPXNzcmM6JylcbiAgLm1hcChmdW5jdGlvbihsaW5lKSB7XG4gICAgcmV0dXJuIFNEUFV0aWxzLnBhcnNlU3NyY01lZGlhKGxpbmUpO1xuICB9KVxuICAuZmlsdGVyKGZ1bmN0aW9uKHBhcnRzKSB7XG4gICAgcmV0dXJuIHBhcnRzLmF0dHJpYnV0ZSA9PT0gJ2NuYW1lJztcbiAgfSk7XG4gIHZhciBwcmltYXJ5U3NyYyA9IHNzcmNzLmxlbmd0aCA+IDAgJiYgc3NyY3NbMF0uc3NyYztcbiAgdmFyIHNlY29uZGFyeVNzcmM7XG5cbiAgdmFyIGZsb3dzID0gU0RQVXRpbHMubWF0Y2hQcmVmaXgobWVkaWFTZWN0aW9uLCAnYT1zc3JjLWdyb3VwOkZJRCcpXG4gIC5tYXAoZnVuY3Rpb24obGluZSkge1xuICAgIHZhciBwYXJ0cyA9IGxpbmUuc3BsaXQoJyAnKTtcbiAgICBwYXJ0cy5zaGlmdCgpO1xuICAgIHJldHVybiBwYXJ0cy5tYXAoZnVuY3Rpb24ocGFydCkge1xuICAgICAgcmV0dXJuIHBhcnNlSW50KHBhcnQsIDEwKTtcbiAgICB9KTtcbiAgfSk7XG4gIGlmIChmbG93cy5sZW5ndGggPiAwICYmIGZsb3dzWzBdLmxlbmd0aCA+IDEgJiYgZmxvd3NbMF1bMF0gPT09IHByaW1hcnlTc3JjKSB7XG4gICAgc2Vjb25kYXJ5U3NyYyA9IGZsb3dzWzBdWzFdO1xuICB9XG5cbiAgZGVzY3JpcHRpb24uY29kZWNzLmZvckVhY2goZnVuY3Rpb24oY29kZWMpIHtcbiAgICBpZiAoY29kZWMubmFtZS50b1VwcGVyQ2FzZSgpID09PSAnUlRYJyAmJiBjb2RlYy5wYXJhbWV0ZXJzLmFwdCkge1xuICAgICAgdmFyIGVuY1BhcmFtID0ge1xuICAgICAgICBzc3JjOiBwcmltYXJ5U3NyYyxcbiAgICAgICAgY29kZWNQYXlsb2FkVHlwZTogcGFyc2VJbnQoY29kZWMucGFyYW1ldGVycy5hcHQsIDEwKSxcbiAgICAgICAgcnR4OiB7XG4gICAgICAgICAgc3NyYzogc2Vjb25kYXJ5U3NyY1xuICAgICAgICB9XG4gICAgICB9O1xuICAgICAgZW5jb2RpbmdQYXJhbWV0ZXJzLnB1c2goZW5jUGFyYW0pO1xuICAgICAgaWYgKGhhc1JlZCkge1xuICAgICAgICBlbmNQYXJhbSA9IEpTT04ucGFyc2UoSlNPTi5zdHJpbmdpZnkoZW5jUGFyYW0pKTtcbiAgICAgICAgZW5jUGFyYW0uZmVjID0ge1xuICAgICAgICAgIHNzcmM6IHNlY29uZGFyeVNzcmMsXG4gICAgICAgICAgbWVjaGFuaXNtOiBoYXNVbHBmZWMgPyAncmVkK3VscGZlYycgOiAncmVkJ1xuICAgICAgICB9O1xuICAgICAgICBlbmNvZGluZ1BhcmFtZXRlcnMucHVzaChlbmNQYXJhbSk7XG4gICAgICB9XG4gICAgfVxuICB9KTtcbiAgaWYgKGVuY29kaW5nUGFyYW1ldGVycy5sZW5ndGggPT09IDAgJiYgcHJpbWFyeVNzcmMpIHtcbiAgICBlbmNvZGluZ1BhcmFtZXRlcnMucHVzaCh7XG4gICAgICBzc3JjOiBwcmltYXJ5U3NyY1xuICAgIH0pO1xuICB9XG5cbiAgLy8gd2Ugc3VwcG9ydCBib3RoIGI9QVMgYW5kIGI9VElBUyBidXQgaW50ZXJwcmV0IEFTIGFzIFRJQVMuXG4gIHZhciBiYW5kd2lkdGggPSBTRFBVdGlscy5tYXRjaFByZWZpeChtZWRpYVNlY3Rpb24sICdiPScpO1xuICBpZiAoYmFuZHdpZHRoLmxlbmd0aCkge1xuICAgIGlmIChiYW5kd2lkdGhbMF0uaW5kZXhPZignYj1USUFTOicpID09PSAwKSB7XG4gICAgICBiYW5kd2lkdGggPSBwYXJzZUludChiYW5kd2lkdGhbMF0uc3Vic3RyKDcpLCAxMCk7XG4gICAgfSBlbHNlIGlmIChiYW5kd2lkdGhbMF0uaW5kZXhPZignYj1BUzonKSA9PT0gMCkge1xuICAgICAgLy8gdXNlIGZvcm11bGEgZnJvbSBKU0VQIHRvIGNvbnZlcnQgYj1BUyB0byBUSUFTIHZhbHVlLlxuICAgICAgYmFuZHdpZHRoID0gcGFyc2VJbnQoYmFuZHdpZHRoWzBdLnN1YnN0cig1KSwgMTApICogMTAwMCAqIDAuOTVcbiAgICAgICAgICAtICg1MCAqIDQwICogOCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGJhbmR3aWR0aCA9IHVuZGVmaW5lZDtcbiAgICB9XG4gICAgZW5jb2RpbmdQYXJhbWV0ZXJzLmZvckVhY2goZnVuY3Rpb24ocGFyYW1zKSB7XG4gICAgICBwYXJhbXMubWF4Qml0cmF0ZSA9IGJhbmR3aWR0aDtcbiAgICB9KTtcbiAgfVxuICByZXR1cm4gZW5jb2RpbmdQYXJhbWV0ZXJzO1xufTtcblxuLy8gcGFyc2VzIGh0dHA6Ly9kcmFmdC5vcnRjLm9yZy8jcnRjcnRjcHBhcmFtZXRlcnMqXG5TRFBVdGlscy5wYXJzZVJ0Y3BQYXJhbWV0ZXJzID0gZnVuY3Rpb24obWVkaWFTZWN0aW9uKSB7XG4gIHZhciBydGNwUGFyYW1ldGVycyA9IHt9O1xuXG4gIHZhciBjbmFtZTtcbiAgLy8gR2V0cyB0aGUgZmlyc3QgU1NSQy4gTm90ZSB0aGF0IHdpdGggUlRYIHRoZXJlIG1pZ2h0IGJlIG11bHRpcGxlXG4gIC8vIFNTUkNzLlxuICB2YXIgcmVtb3RlU3NyYyA9IFNEUFV0aWxzLm1hdGNoUHJlZml4KG1lZGlhU2VjdGlvbiwgJ2E9c3NyYzonKVxuICAgICAgLm1hcChmdW5jdGlvbihsaW5lKSB7XG4gICAgICAgIHJldHVybiBTRFBVdGlscy5wYXJzZVNzcmNNZWRpYShsaW5lKTtcbiAgICAgIH0pXG4gICAgICAuZmlsdGVyKGZ1bmN0aW9uKG9iaikge1xuICAgICAgICByZXR1cm4gb2JqLmF0dHJpYnV0ZSA9PT0gJ2NuYW1lJztcbiAgICAgIH0pWzBdO1xuICBpZiAocmVtb3RlU3NyYykge1xuICAgIHJ0Y3BQYXJhbWV0ZXJzLmNuYW1lID0gcmVtb3RlU3NyYy52YWx1ZTtcbiAgICBydGNwUGFyYW1ldGVycy5zc3JjID0gcmVtb3RlU3NyYy5zc3JjO1xuICB9XG5cbiAgLy8gRWRnZSB1c2VzIHRoZSBjb21wb3VuZCBhdHRyaWJ1dGUgaW5zdGVhZCBvZiByZWR1Y2VkU2l6ZVxuICAvLyBjb21wb3VuZCBpcyAhcmVkdWNlZFNpemVcbiAgdmFyIHJzaXplID0gU0RQVXRpbHMubWF0Y2hQcmVmaXgobWVkaWFTZWN0aW9uLCAnYT1ydGNwLXJzaXplJyk7XG4gIHJ0Y3BQYXJhbWV0ZXJzLnJlZHVjZWRTaXplID0gcnNpemUubGVuZ3RoID4gMDtcbiAgcnRjcFBhcmFtZXRlcnMuY29tcG91bmQgPSByc2l6ZS5sZW5ndGggPT09IDA7XG5cbiAgLy8gcGFyc2VzIHRoZSBydGNwLW11eCBhdHRy0ZZidXRlLlxuICAvLyBOb3RlIHRoYXQgRWRnZSBkb2VzIG5vdCBzdXBwb3J0IHVubXV4ZWQgUlRDUC5cbiAgdmFyIG11eCA9IFNEUFV0aWxzLm1hdGNoUHJlZml4KG1lZGlhU2VjdGlvbiwgJ2E9cnRjcC1tdXgnKTtcbiAgcnRjcFBhcmFtZXRlcnMubXV4ID0gbXV4Lmxlbmd0aCA+IDA7XG5cbiAgcmV0dXJuIHJ0Y3BQYXJhbWV0ZXJzO1xufTtcblxuLy8gcGFyc2VzIGVpdGhlciBhPW1zaWQ6IG9yIGE9c3NyYzouLi4gbXNpZCBsaW5lcyBhbmQgcmV0dXJuc1xuLy8gdGhlIGlkIG9mIHRoZSBNZWRpYVN0cmVhbSBhbmQgTWVkaWFTdHJlYW1UcmFjay5cblNEUFV0aWxzLnBhcnNlTXNpZCA9IGZ1bmN0aW9uKG1lZGlhU2VjdGlvbikge1xuICB2YXIgcGFydHM7XG4gIHZhciBzcGVjID0gU0RQVXRpbHMubWF0Y2hQcmVmaXgobWVkaWFTZWN0aW9uLCAnYT1tc2lkOicpO1xuICBpZiAoc3BlYy5sZW5ndGggPT09IDEpIHtcbiAgICBwYXJ0cyA9IHNwZWNbMF0uc3Vic3RyKDcpLnNwbGl0KCcgJyk7XG4gICAgcmV0dXJuIHtzdHJlYW06IHBhcnRzWzBdLCB0cmFjazogcGFydHNbMV19O1xuICB9XG4gIHZhciBwbGFuQiA9IFNEUFV0aWxzLm1hdGNoUHJlZml4KG1lZGlhU2VjdGlvbiwgJ2E9c3NyYzonKVxuICAubWFwKGZ1bmN0aW9uKGxpbmUpIHtcbiAgICByZXR1cm4gU0RQVXRpbHMucGFyc2VTc3JjTWVkaWEobGluZSk7XG4gIH0pXG4gIC5maWx0ZXIoZnVuY3Rpb24ocGFydHMpIHtcbiAgICByZXR1cm4gcGFydHMuYXR0cmlidXRlID09PSAnbXNpZCc7XG4gIH0pO1xuICBpZiAocGxhbkIubGVuZ3RoID4gMCkge1xuICAgIHBhcnRzID0gcGxhbkJbMF0udmFsdWUuc3BsaXQoJyAnKTtcbiAgICByZXR1cm4ge3N0cmVhbTogcGFydHNbMF0sIHRyYWNrOiBwYXJ0c1sxXX07XG4gIH1cbn07XG5cbi8vIEdlbmVyYXRlIGEgc2Vzc2lvbiBJRCBmb3IgU0RQLlxuLy8gaHR0cHM6Ly90b29scy5pZXRmLm9yZy9odG1sL2RyYWZ0LWlldGYtcnRjd2ViLWpzZXAtMjAjc2VjdGlvbi01LjIuMVxuLy8gcmVjb21tZW5kcyB1c2luZyBhIGNyeXB0b2dyYXBoaWNhbGx5IHJhbmRvbSArdmUgNjQtYml0IHZhbHVlXG4vLyBidXQgcmlnaHQgbm93IHRoaXMgc2hvdWxkIGJlIGFjY2VwdGFibGUgYW5kIHdpdGhpbiB0aGUgcmlnaHQgcmFuZ2VcblNEUFV0aWxzLmdlbmVyYXRlU2Vzc2lvbklkID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiBNYXRoLnJhbmRvbSgpLnRvU3RyaW5nKCkuc3Vic3RyKDIsIDIxKTtcbn07XG5cbi8vIFdyaXRlIGJvaWxkZXIgcGxhdGUgZm9yIHN0YXJ0IG9mIFNEUFxuLy8gc2Vzc0lkIGFyZ3VtZW50IGlzIG9wdGlvbmFsIC0gaWYgbm90IHN1cHBsaWVkIGl0IHdpbGxcbi8vIGJlIGdlbmVyYXRlZCByYW5kb21seVxuLy8gc2Vzc1ZlcnNpb24gaXMgb3B0aW9uYWwgYW5kIGRlZmF1bHRzIHRvIDJcblNEUFV0aWxzLndyaXRlU2Vzc2lvbkJvaWxlcnBsYXRlID0gZnVuY3Rpb24oc2Vzc0lkLCBzZXNzVmVyKSB7XG4gIHZhciBzZXNzaW9uSWQ7XG4gIHZhciB2ZXJzaW9uID0gc2Vzc1ZlciAhPT0gdW5kZWZpbmVkID8gc2Vzc1ZlciA6IDI7XG4gIGlmIChzZXNzSWQpIHtcbiAgICBzZXNzaW9uSWQgPSBzZXNzSWQ7XG4gIH0gZWxzZSB7XG4gICAgc2Vzc2lvbklkID0gU0RQVXRpbHMuZ2VuZXJhdGVTZXNzaW9uSWQoKTtcbiAgfVxuICAvLyBGSVhNRTogc2Vzcy1pZCBzaG91bGQgYmUgYW4gTlRQIHRpbWVzdGFtcC5cbiAgcmV0dXJuICd2PTBcXHJcXG4nICtcbiAgICAgICdvPXRoaXNpc2FkYXB0ZXJvcnRjICcgKyBzZXNzaW9uSWQgKyAnICcgKyB2ZXJzaW9uICsgJyBJTiBJUDQgMTI3LjAuMC4xXFxyXFxuJyArXG4gICAgICAncz0tXFxyXFxuJyArXG4gICAgICAndD0wIDBcXHJcXG4nO1xufTtcblxuU0RQVXRpbHMud3JpdGVNZWRpYVNlY3Rpb24gPSBmdW5jdGlvbih0cmFuc2NlaXZlciwgY2FwcywgdHlwZSwgc3RyZWFtKSB7XG4gIHZhciBzZHAgPSBTRFBVdGlscy53cml0ZVJ0cERlc2NyaXB0aW9uKHRyYW5zY2VpdmVyLmtpbmQsIGNhcHMpO1xuXG4gIC8vIE1hcCBJQ0UgcGFyYW1ldGVycyAodWZyYWcsIHB3ZCkgdG8gU0RQLlxuICBzZHAgKz0gU0RQVXRpbHMud3JpdGVJY2VQYXJhbWV0ZXJzKFxuICAgICAgdHJhbnNjZWl2ZXIuaWNlR2F0aGVyZXIuZ2V0TG9jYWxQYXJhbWV0ZXJzKCkpO1xuXG4gIC8vIE1hcCBEVExTIHBhcmFtZXRlcnMgdG8gU0RQLlxuICBzZHAgKz0gU0RQVXRpbHMud3JpdGVEdGxzUGFyYW1ldGVycyhcbiAgICAgIHRyYW5zY2VpdmVyLmR0bHNUcmFuc3BvcnQuZ2V0TG9jYWxQYXJhbWV0ZXJzKCksXG4gICAgICB0eXBlID09PSAnb2ZmZXInID8gJ2FjdHBhc3MnIDogJ2FjdGl2ZScpO1xuXG4gIHNkcCArPSAnYT1taWQ6JyArIHRyYW5zY2VpdmVyLm1pZCArICdcXHJcXG4nO1xuXG4gIGlmICh0cmFuc2NlaXZlci5kaXJlY3Rpb24pIHtcbiAgICBzZHAgKz0gJ2E9JyArIHRyYW5zY2VpdmVyLmRpcmVjdGlvbiArICdcXHJcXG4nO1xuICB9IGVsc2UgaWYgKHRyYW5zY2VpdmVyLnJ0cFNlbmRlciAmJiB0cmFuc2NlaXZlci5ydHBSZWNlaXZlcikge1xuICAgIHNkcCArPSAnYT1zZW5kcmVjdlxcclxcbic7XG4gIH0gZWxzZSBpZiAodHJhbnNjZWl2ZXIucnRwU2VuZGVyKSB7XG4gICAgc2RwICs9ICdhPXNlbmRvbmx5XFxyXFxuJztcbiAgfSBlbHNlIGlmICh0cmFuc2NlaXZlci5ydHBSZWNlaXZlcikge1xuICAgIHNkcCArPSAnYT1yZWN2b25seVxcclxcbic7XG4gIH0gZWxzZSB7XG4gICAgc2RwICs9ICdhPWluYWN0aXZlXFxyXFxuJztcbiAgfVxuXG4gIGlmICh0cmFuc2NlaXZlci5ydHBTZW5kZXIpIHtcbiAgICAvLyBzcGVjLlxuICAgIHZhciBtc2lkID0gJ21zaWQ6JyArIHN0cmVhbS5pZCArICcgJyArXG4gICAgICAgIHRyYW5zY2VpdmVyLnJ0cFNlbmRlci50cmFjay5pZCArICdcXHJcXG4nO1xuICAgIHNkcCArPSAnYT0nICsgbXNpZDtcblxuICAgIC8vIGZvciBDaHJvbWUuXG4gICAgc2RwICs9ICdhPXNzcmM6JyArIHRyYW5zY2VpdmVyLnNlbmRFbmNvZGluZ1BhcmFtZXRlcnNbMF0uc3NyYyArXG4gICAgICAgICcgJyArIG1zaWQ7XG4gICAgaWYgKHRyYW5zY2VpdmVyLnNlbmRFbmNvZGluZ1BhcmFtZXRlcnNbMF0ucnR4KSB7XG4gICAgICBzZHAgKz0gJ2E9c3NyYzonICsgdHJhbnNjZWl2ZXIuc2VuZEVuY29kaW5nUGFyYW1ldGVyc1swXS5ydHguc3NyYyArXG4gICAgICAgICAgJyAnICsgbXNpZDtcbiAgICAgIHNkcCArPSAnYT1zc3JjLWdyb3VwOkZJRCAnICtcbiAgICAgICAgICB0cmFuc2NlaXZlci5zZW5kRW5jb2RpbmdQYXJhbWV0ZXJzWzBdLnNzcmMgKyAnICcgK1xuICAgICAgICAgIHRyYW5zY2VpdmVyLnNlbmRFbmNvZGluZ1BhcmFtZXRlcnNbMF0ucnR4LnNzcmMgK1xuICAgICAgICAgICdcXHJcXG4nO1xuICAgIH1cbiAgfVxuICAvLyBGSVhNRTogdGhpcyBzaG91bGQgYmUgd3JpdHRlbiBieSB3cml0ZVJ0cERlc2NyaXB0aW9uLlxuICBzZHAgKz0gJ2E9c3NyYzonICsgdHJhbnNjZWl2ZXIuc2VuZEVuY29kaW5nUGFyYW1ldGVyc1swXS5zc3JjICtcbiAgICAgICcgY25hbWU6JyArIFNEUFV0aWxzLmxvY2FsQ05hbWUgKyAnXFxyXFxuJztcbiAgaWYgKHRyYW5zY2VpdmVyLnJ0cFNlbmRlciAmJiB0cmFuc2NlaXZlci5zZW5kRW5jb2RpbmdQYXJhbWV0ZXJzWzBdLnJ0eCkge1xuICAgIHNkcCArPSAnYT1zc3JjOicgKyB0cmFuc2NlaXZlci5zZW5kRW5jb2RpbmdQYXJhbWV0ZXJzWzBdLnJ0eC5zc3JjICtcbiAgICAgICAgJyBjbmFtZTonICsgU0RQVXRpbHMubG9jYWxDTmFtZSArICdcXHJcXG4nO1xuICB9XG4gIHJldHVybiBzZHA7XG59O1xuXG4vLyBHZXRzIHRoZSBkaXJlY3Rpb24gZnJvbSB0aGUgbWVkaWFTZWN0aW9uIG9yIHRoZSBzZXNzaW9ucGFydC5cblNEUFV0aWxzLmdldERpcmVjdGlvbiA9IGZ1bmN0aW9uKG1lZGlhU2VjdGlvbiwgc2Vzc2lvbnBhcnQpIHtcbiAgLy8gTG9vayBmb3Igc2VuZHJlY3YsIHNlbmRvbmx5LCByZWN2b25seSwgaW5hY3RpdmUsIGRlZmF1bHQgdG8gc2VuZHJlY3YuXG4gIHZhciBsaW5lcyA9IFNEUFV0aWxzLnNwbGl0TGluZXMobWVkaWFTZWN0aW9uKTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsaW5lcy5sZW5ndGg7IGkrKykge1xuICAgIHN3aXRjaCAobGluZXNbaV0pIHtcbiAgICAgIGNhc2UgJ2E9c2VuZHJlY3YnOlxuICAgICAgY2FzZSAnYT1zZW5kb25seSc6XG4gICAgICBjYXNlICdhPXJlY3Zvbmx5JzpcbiAgICAgIGNhc2UgJ2E9aW5hY3RpdmUnOlxuICAgICAgICByZXR1cm4gbGluZXNbaV0uc3Vic3RyKDIpO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgLy8gRklYTUU6IFdoYXQgc2hvdWxkIGhhcHBlbiBoZXJlP1xuICAgIH1cbiAgfVxuICBpZiAoc2Vzc2lvbnBhcnQpIHtcbiAgICByZXR1cm4gU0RQVXRpbHMuZ2V0RGlyZWN0aW9uKHNlc3Npb25wYXJ0KTtcbiAgfVxuICByZXR1cm4gJ3NlbmRyZWN2Jztcbn07XG5cblNEUFV0aWxzLmdldEtpbmQgPSBmdW5jdGlvbihtZWRpYVNlY3Rpb24pIHtcbiAgdmFyIGxpbmVzID0gU0RQVXRpbHMuc3BsaXRMaW5lcyhtZWRpYVNlY3Rpb24pO1xuICB2YXIgbWxpbmUgPSBsaW5lc1swXS5zcGxpdCgnICcpO1xuICByZXR1cm4gbWxpbmVbMF0uc3Vic3RyKDIpO1xufTtcblxuU0RQVXRpbHMuaXNSZWplY3RlZCA9IGZ1bmN0aW9uKG1lZGlhU2VjdGlvbikge1xuICByZXR1cm4gbWVkaWFTZWN0aW9uLnNwbGl0KCcgJywgMilbMV0gPT09ICcwJztcbn07XG5cblNEUFV0aWxzLnBhcnNlTUxpbmUgPSBmdW5jdGlvbihtZWRpYVNlY3Rpb24pIHtcbiAgdmFyIGxpbmVzID0gU0RQVXRpbHMuc3BsaXRMaW5lcyhtZWRpYVNlY3Rpb24pO1xuICB2YXIgbWxpbmUgPSBsaW5lc1swXS5zcGxpdCgnICcpO1xuICByZXR1cm4ge1xuICAgIGtpbmQ6IG1saW5lWzBdLnN1YnN0cigyKSxcbiAgICBwb3J0OiBwYXJzZUludChtbGluZVsxXSwgMTApLFxuICAgIHByb3RvY29sOiBtbGluZVsyXSxcbiAgICBmbXQ6IG1saW5lLnNsaWNlKDMpLmpvaW4oJyAnKVxuICB9O1xufTtcblxuLy8gRXhwb3NlIHB1YmxpYyBtZXRob2RzLlxuaWYgKHR5cGVvZiBtb2R1bGUgPT09ICdvYmplY3QnKSB7XG4gIG1vZHVsZS5leHBvcnRzID0gU0RQVXRpbHM7XG59XG4iLCIvKipcbiAqIFVBUGFyc2VyLmpzIHYwLjcuMTRcbiAqIExpZ2h0d2VpZ2h0IEphdmFTY3JpcHQtYmFzZWQgVXNlci1BZ2VudCBzdHJpbmcgcGFyc2VyXG4gKiBodHRwczovL2dpdGh1Yi5jb20vZmFpc2FsbWFuL3VhLXBhcnNlci1qc1xuICpcbiAqIENvcHlyaWdodCDCqSAyMDEyLTIwMTYgRmFpc2FsIFNhbG1hbiA8Znl6bG1hbkBnbWFpbC5jb20+XG4gKiBEdWFsIGxpY2Vuc2VkIHVuZGVyIEdQTHYyICYgTUlUXG4gKi9cblxuKGZ1bmN0aW9uICh3aW5kb3csIHVuZGVmaW5lZCkge1xuXG4gICAgJ3VzZSBzdHJpY3QnO1xuXG4gICAgLy8vLy8vLy8vLy8vLy9cbiAgICAvLyBDb25zdGFudHNcbiAgICAvLy8vLy8vLy8vLy8vXG5cblxuICAgIHZhciBMSUJWRVJTSU9OICA9ICcwLjcuMTQnLFxuICAgICAgICBFTVBUWSAgICAgICA9ICcnLFxuICAgICAgICBVTktOT1dOICAgICA9ICc/JyxcbiAgICAgICAgRlVOQ19UWVBFICAgPSAnZnVuY3Rpb24nLFxuICAgICAgICBVTkRFRl9UWVBFICA9ICd1bmRlZmluZWQnLFxuICAgICAgICBPQkpfVFlQRSAgICA9ICdvYmplY3QnLFxuICAgICAgICBTVFJfVFlQRSAgICA9ICdzdHJpbmcnLFxuICAgICAgICBNQUpPUiAgICAgICA9ICdtYWpvcicsIC8vIGRlcHJlY2F0ZWRcbiAgICAgICAgTU9ERUwgICAgICAgPSAnbW9kZWwnLFxuICAgICAgICBOQU1FICAgICAgICA9ICduYW1lJyxcbiAgICAgICAgVFlQRSAgICAgICAgPSAndHlwZScsXG4gICAgICAgIFZFTkRPUiAgICAgID0gJ3ZlbmRvcicsXG4gICAgICAgIFZFUlNJT04gICAgID0gJ3ZlcnNpb24nLFxuICAgICAgICBBUkNISVRFQ1RVUkU9ICdhcmNoaXRlY3R1cmUnLFxuICAgICAgICBDT05TT0xFICAgICA9ICdjb25zb2xlJyxcbiAgICAgICAgTU9CSUxFICAgICAgPSAnbW9iaWxlJyxcbiAgICAgICAgVEFCTEVUICAgICAgPSAndGFibGV0JyxcbiAgICAgICAgU01BUlRUViAgICAgPSAnc21hcnR0dicsXG4gICAgICAgIFdFQVJBQkxFICAgID0gJ3dlYXJhYmxlJyxcbiAgICAgICAgRU1CRURERUQgICAgPSAnZW1iZWRkZWQnO1xuXG5cbiAgICAvLy8vLy8vLy8vL1xuICAgIC8vIEhlbHBlclxuICAgIC8vLy8vLy8vLy9cblxuXG4gICAgdmFyIHV0aWwgPSB7XG4gICAgICAgIGV4dGVuZCA6IGZ1bmN0aW9uIChyZWdleGVzLCBleHRlbnNpb25zKSB7XG4gICAgICAgICAgICB2YXIgbWFyZ2VkUmVnZXhlcyA9IHt9O1xuICAgICAgICAgICAgZm9yICh2YXIgaSBpbiByZWdleGVzKSB7XG4gICAgICAgICAgICAgICAgaWYgKGV4dGVuc2lvbnNbaV0gJiYgZXh0ZW5zaW9uc1tpXS5sZW5ndGggJSAyID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgIG1hcmdlZFJlZ2V4ZXNbaV0gPSBleHRlbnNpb25zW2ldLmNvbmNhdChyZWdleGVzW2ldKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBtYXJnZWRSZWdleGVzW2ldID0gcmVnZXhlc1tpXTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gbWFyZ2VkUmVnZXhlcztcbiAgICAgICAgfSxcbiAgICAgICAgaGFzIDogZnVuY3Rpb24gKHN0cjEsIHN0cjIpIHtcbiAgICAgICAgICBpZiAodHlwZW9mIHN0cjEgPT09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgICAgIHJldHVybiBzdHIyLnRvTG93ZXJDYXNlKCkuaW5kZXhPZihzdHIxLnRvTG93ZXJDYXNlKCkpICE9PSAtMTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgICAgbG93ZXJpemUgOiBmdW5jdGlvbiAoc3RyKSB7XG4gICAgICAgICAgICByZXR1cm4gc3RyLnRvTG93ZXJDYXNlKCk7XG4gICAgICAgIH0sXG4gICAgICAgIG1ham9yIDogZnVuY3Rpb24gKHZlcnNpb24pIHtcbiAgICAgICAgICAgIHJldHVybiB0eXBlb2YodmVyc2lvbikgPT09IFNUUl9UWVBFID8gdmVyc2lvbi5yZXBsYWNlKC9bXlxcZFxcLl0vZywnJykuc3BsaXQoXCIuXCIpWzBdIDogdW5kZWZpbmVkO1xuICAgICAgICB9LFxuICAgICAgICB0cmltIDogZnVuY3Rpb24gKHN0cikge1xuICAgICAgICAgIHJldHVybiBzdHIucmVwbGFjZSgvXltcXHNcXHVGRUZGXFx4QTBdK3xbXFxzXFx1RkVGRlxceEEwXSskL2csICcnKTtcbiAgICAgICAgfVxuICAgIH07XG5cblxuICAgIC8vLy8vLy8vLy8vLy8vL1xuICAgIC8vIE1hcCBoZWxwZXJcbiAgICAvLy8vLy8vLy8vLy8vL1xuXG5cbiAgICB2YXIgbWFwcGVyID0ge1xuXG4gICAgICAgIHJneCA6IGZ1bmN0aW9uICh1YSwgYXJyYXlzKSB7XG5cbiAgICAgICAgICAgIC8vdmFyIHJlc3VsdCA9IHt9LFxuICAgICAgICAgICAgdmFyIGkgPSAwLCBqLCBrLCBwLCBxLCBtYXRjaGVzLCBtYXRjaDsvLywgYXJncyA9IGFyZ3VtZW50cztcblxuICAgICAgICAgICAgLyovLyBjb25zdHJ1Y3Qgb2JqZWN0IGJhcmVib25lc1xuICAgICAgICAgICAgZm9yIChwID0gMDsgcCA8IGFyZ3NbMV0ubGVuZ3RoOyBwKyspIHtcbiAgICAgICAgICAgICAgICBxID0gYXJnc1sxXVtwXTtcbiAgICAgICAgICAgICAgICByZXN1bHRbdHlwZW9mIHEgPT09IE9CSl9UWVBFID8gcVswXSA6IHFdID0gdW5kZWZpbmVkO1xuICAgICAgICAgICAgfSovXG5cbiAgICAgICAgICAgIC8vIGxvb3AgdGhyb3VnaCBhbGwgcmVnZXhlcyBtYXBzXG4gICAgICAgICAgICB3aGlsZSAoaSA8IGFycmF5cy5sZW5ndGggJiYgIW1hdGNoZXMpIHtcblxuICAgICAgICAgICAgICAgIHZhciByZWdleCA9IGFycmF5c1tpXSwgICAgICAgLy8gZXZlbiBzZXF1ZW5jZSAoMCwyLDQsLi4pXG4gICAgICAgICAgICAgICAgICAgIHByb3BzID0gYXJyYXlzW2kgKyAxXTsgICAvLyBvZGQgc2VxdWVuY2UgKDEsMyw1LC4uKVxuICAgICAgICAgICAgICAgIGogPSBrID0gMDtcblxuICAgICAgICAgICAgICAgIC8vIHRyeSBtYXRjaGluZyB1YXN0cmluZyB3aXRoIHJlZ2V4ZXNcbiAgICAgICAgICAgICAgICB3aGlsZSAoaiA8IHJlZ2V4Lmxlbmd0aCAmJiAhbWF0Y2hlcykge1xuXG4gICAgICAgICAgICAgICAgICAgIG1hdGNoZXMgPSByZWdleFtqKytdLmV4ZWModWEpO1xuXG4gICAgICAgICAgICAgICAgICAgIGlmICghIW1hdGNoZXMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAocCA9IDA7IHAgPCBwcm9wcy5sZW5ndGg7IHArKykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hdGNoID0gbWF0Y2hlc1srK2tdO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHEgPSBwcm9wc1twXTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBjaGVjayBpZiBnaXZlbiBwcm9wZXJ0eSBpcyBhY3R1YWxseSBhcnJheVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgcSA9PT0gT0JKX1RZUEUgJiYgcS5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChxLmxlbmd0aCA9PSAyKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHFbMV0gPT0gRlVOQ19UWVBFKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gYXNzaWduIG1vZGlmaWVkIG1hdGNoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpc1txWzBdXSA9IHFbMV0uY2FsbCh0aGlzLCBtYXRjaCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGFzc2lnbiBnaXZlbiB2YWx1ZSwgaWdub3JlIHJlZ2V4IG1hdGNoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpc1txWzBdXSA9IHFbMV07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAocS5sZW5ndGggPT0gMykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gY2hlY2sgd2hldGhlciBmdW5jdGlvbiBvciByZWdleFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBxWzFdID09PSBGVU5DX1RZUEUgJiYgIShxWzFdLmV4ZWMgJiYgcVsxXS50ZXN0KSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNhbGwgZnVuY3Rpb24gKHVzdWFsbHkgc3RyaW5nIG1hcHBlcilcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzW3FbMF1dID0gbWF0Y2ggPyBxWzFdLmNhbGwodGhpcywgbWF0Y2gsIHFbMl0pIDogdW5kZWZpbmVkO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBzYW5pdGl6ZSBtYXRjaCB1c2luZyBnaXZlbiByZWdleFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXNbcVswXV0gPSBtYXRjaCA/IG1hdGNoLnJlcGxhY2UocVsxXSwgcVsyXSkgOiB1bmRlZmluZWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAocS5sZW5ndGggPT0gNCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXNbcVswXV0gPSBtYXRjaCA/IHFbM10uY2FsbCh0aGlzLCBtYXRjaC5yZXBsYWNlKHFbMV0sIHFbMl0pKSA6IHVuZGVmaW5lZDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXNbcV0gPSBtYXRjaCA/IG1hdGNoIDogdW5kZWZpbmVkO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpICs9IDI7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvL2NvbnNvbGUubG9nKHRoaXMpO1xuICAgICAgICAgICAgLy9yZXR1cm4gdGhpcztcbiAgICAgICAgfSxcblxuICAgICAgICBzdHIgOiBmdW5jdGlvbiAoc3RyLCBtYXApIHtcblxuICAgICAgICAgICAgZm9yICh2YXIgaSBpbiBtYXApIHtcbiAgICAgICAgICAgICAgICAvLyBjaGVjayBpZiBhcnJheVxuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgbWFwW2ldID09PSBPQkpfVFlQRSAmJiBtYXBbaV0ubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IG1hcFtpXS5sZW5ndGg7IGorKykge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHV0aWwuaGFzKG1hcFtpXVtqXSwgc3RyKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAoaSA9PT0gVU5LTk9XTikgPyB1bmRlZmluZWQgOiBpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmICh1dGlsLmhhcyhtYXBbaV0sIHN0cikpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIChpID09PSBVTktOT1dOKSA/IHVuZGVmaW5lZCA6IGk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHN0cjtcbiAgICAgICAgfVxuICAgIH07XG5cblxuICAgIC8vLy8vLy8vLy8vLy8vL1xuICAgIC8vIFN0cmluZyBtYXBcbiAgICAvLy8vLy8vLy8vLy8vL1xuXG5cbiAgICB2YXIgbWFwcyA9IHtcblxuICAgICAgICBicm93c2VyIDoge1xuICAgICAgICAgICAgb2xkc2FmYXJpIDoge1xuICAgICAgICAgICAgICAgIHZlcnNpb24gOiB7XG4gICAgICAgICAgICAgICAgICAgICcxLjAnICAgOiAnLzgnLFxuICAgICAgICAgICAgICAgICAgICAnMS4yJyAgIDogJy8xJyxcbiAgICAgICAgICAgICAgICAgICAgJzEuMycgICA6ICcvMycsXG4gICAgICAgICAgICAgICAgICAgICcyLjAnICAgOiAnLzQxMicsXG4gICAgICAgICAgICAgICAgICAgICcyLjAuMicgOiAnLzQxNicsXG4gICAgICAgICAgICAgICAgICAgICcyLjAuMycgOiAnLzQxNycsXG4gICAgICAgICAgICAgICAgICAgICcyLjAuNCcgOiAnLzQxOScsXG4gICAgICAgICAgICAgICAgICAgICc/JyAgICAgOiAnLydcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG5cbiAgICAgICAgZGV2aWNlIDoge1xuICAgICAgICAgICAgYW1hem9uIDoge1xuICAgICAgICAgICAgICAgIG1vZGVsIDoge1xuICAgICAgICAgICAgICAgICAgICAnRmlyZSBQaG9uZScgOiBbJ1NEJywgJ0tGJ11cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc3ByaW50IDoge1xuICAgICAgICAgICAgICAgIG1vZGVsIDoge1xuICAgICAgICAgICAgICAgICAgICAnRXZvIFNoaWZ0IDRHJyA6ICc3MzczS1QnXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB2ZW5kb3IgOiB7XG4gICAgICAgICAgICAgICAgICAgICdIVEMnICAgICAgIDogJ0FQQScsXG4gICAgICAgICAgICAgICAgICAgICdTcHJpbnQnICAgIDogJ1NwcmludCdcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG5cbiAgICAgICAgb3MgOiB7XG4gICAgICAgICAgICB3aW5kb3dzIDoge1xuICAgICAgICAgICAgICAgIHZlcnNpb24gOiB7XG4gICAgICAgICAgICAgICAgICAgICdNRScgICAgICAgIDogJzQuOTAnLFxuICAgICAgICAgICAgICAgICAgICAnTlQgMy4xMScgICA6ICdOVDMuNTEnLFxuICAgICAgICAgICAgICAgICAgICAnTlQgNC4wJyAgICA6ICdOVDQuMCcsXG4gICAgICAgICAgICAgICAgICAgICcyMDAwJyAgICAgIDogJ05UIDUuMCcsXG4gICAgICAgICAgICAgICAgICAgICdYUCcgICAgICAgIDogWydOVCA1LjEnLCAnTlQgNS4yJ10sXG4gICAgICAgICAgICAgICAgICAgICdWaXN0YScgICAgIDogJ05UIDYuMCcsXG4gICAgICAgICAgICAgICAgICAgICc3JyAgICAgICAgIDogJ05UIDYuMScsXG4gICAgICAgICAgICAgICAgICAgICc4JyAgICAgICAgIDogJ05UIDYuMicsXG4gICAgICAgICAgICAgICAgICAgICc4LjEnICAgICAgIDogJ05UIDYuMycsXG4gICAgICAgICAgICAgICAgICAgICcxMCcgICAgICAgIDogWydOVCA2LjQnLCAnTlQgMTAuMCddLFxuICAgICAgICAgICAgICAgICAgICAnUlQnICAgICAgICA6ICdBUk0nXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfTtcblxuXG4gICAgLy8vLy8vLy8vLy8vLy9cbiAgICAvLyBSZWdleCBtYXBcbiAgICAvLy8vLy8vLy8vLy8vXG5cblxuICAgIHZhciByZWdleGVzID0ge1xuXG4gICAgICAgIGJyb3dzZXIgOiBbW1xuXG4gICAgICAgICAgICAvLyBQcmVzdG8gYmFzZWRcbiAgICAgICAgICAgIC8ob3BlcmFcXHNtaW5pKVxcLyhbXFx3XFwuLV0rKS9pLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE9wZXJhIE1pbmlcbiAgICAgICAgICAgIC8ob3BlcmFcXHNbbW9iaWxldGFiXSspLit2ZXJzaW9uXFwvKFtcXHdcXC4tXSspL2ksICAgICAgICAgICAgICAgICAgICAgIC8vIE9wZXJhIE1vYmkvVGFibGV0XG4gICAgICAgICAgICAvKG9wZXJhKS4rdmVyc2lvblxcLyhbXFx3XFwuXSspL2ksICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE9wZXJhID4gOS44MFxuICAgICAgICAgICAgLyhvcGVyYSlbXFwvXFxzXSsoW1xcd1xcLl0rKS9pICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gT3BlcmEgPCA5LjgwXG4gICAgICAgICAgICBdLCBbTkFNRSwgVkVSU0lPTl0sIFtcblxuICAgICAgICAgICAgLyhvcGlvcylbXFwvXFxzXSsoW1xcd1xcLl0rKS9pICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gT3BlcmEgbWluaSBvbiBpcGhvbmUgPj0gOC4wXG4gICAgICAgICAgICBdLCBbW05BTUUsICdPcGVyYSBNaW5pJ10sIFZFUlNJT05dLCBbXG5cbiAgICAgICAgICAgIC9cXHMob3ByKVxcLyhbXFx3XFwuXSspL2kgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE9wZXJhIFdlYmtpdFxuICAgICAgICAgICAgXSwgW1tOQU1FLCAnT3BlcmEnXSwgVkVSU0lPTl0sIFtcblxuICAgICAgICAgICAgLy8gTWl4ZWRcbiAgICAgICAgICAgIC8oa2luZGxlKVxcLyhbXFx3XFwuXSspL2ksICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gS2luZGxlXG4gICAgICAgICAgICAvKGx1bmFzY2FwZXxtYXh0aG9ufG5ldGZyb250fGphc21pbmV8YmxhemVyKVtcXC9cXHNdPyhbXFx3XFwuXSspKi9pLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBMdW5hc2NhcGUvTWF4dGhvbi9OZXRmcm9udC9KYXNtaW5lL0JsYXplclxuXG4gICAgICAgICAgICAvLyBUcmlkZW50IGJhc2VkXG4gICAgICAgICAgICAvKGF2YW50XFxzfGllbW9iaWxlfHNsaW18YmFpZHUpKD86YnJvd3Nlcik/W1xcL1xcc10/KFtcXHdcXC5dKikvaSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQXZhbnQvSUVNb2JpbGUvU2xpbUJyb3dzZXIvQmFpZHVcbiAgICAgICAgICAgIC8oPzptc3xcXCgpKGllKVxccyhbXFx3XFwuXSspL2ksICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEludGVybmV0IEV4cGxvcmVyXG5cbiAgICAgICAgICAgIC8vIFdlYmtpdC9LSFRNTCBiYXNlZFxuICAgICAgICAgICAgLyhyZWtvbnEpXFwvKFtcXHdcXC5dKykqL2ksICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBSZWtvbnFcbiAgICAgICAgICAgIC8oY2hyb21pdW18ZmxvY2t8cm9ja21lbHR8bWlkb3JpfGVwaXBoYW55fHNpbGt8c2t5ZmlyZXxvdmlicm93c2VyfGJvbHR8aXJvbnx2aXZhbGRpfGlyaWRpdW18cGhhbnRvbWpzfGJvd3NlcilcXC8oW1xcd1xcLi1dKykvaVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBDaHJvbWl1bS9GbG9jay9Sb2NrTWVsdC9NaWRvcmkvRXBpcGhhbnkvU2lsay9Ta3lmaXJlL0JvbHQvSXJvbi9JcmlkaXVtL1BoYW50b21KUy9Cb3dzZXJcbiAgICAgICAgICAgIF0sIFtOQU1FLCBWRVJTSU9OXSwgW1xuXG4gICAgICAgICAgICAvKHRyaWRlbnQpLitydls6XFxzXShbXFx3XFwuXSspLitsaWtlXFxzZ2Vja28vaSAgICAgICAgICAgICAgICAgICAgICAgICAvLyBJRTExXG4gICAgICAgICAgICBdLCBbW05BTUUsICdJRSddLCBWRVJTSU9OXSwgW1xuXG4gICAgICAgICAgICAvKGVkZ2UpXFwvKChcXGQrKT9bXFx3XFwuXSspL2kgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBNaWNyb3NvZnQgRWRnZVxuICAgICAgICAgICAgXSwgW05BTUUsIFZFUlNJT05dLCBbXG5cbiAgICAgICAgICAgIC8oeWFicm93c2VyKVxcLyhbXFx3XFwuXSspL2kgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gWWFuZGV4XG4gICAgICAgICAgICBdLCBbW05BTUUsICdZYW5kZXgnXSwgVkVSU0lPTl0sIFtcblxuICAgICAgICAgICAgLyhwdWZmaW4pXFwvKFtcXHdcXC5dKykvaSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBQdWZmaW5cbiAgICAgICAgICAgIF0sIFtbTkFNRSwgJ1B1ZmZpbiddLCBWRVJTSU9OXSwgW1xuXG4gICAgICAgICAgICAvKCg/OltcXHNcXC9dKXVjP1xccz9icm93c2VyfCg/Omp1Yy4rKXVjd2ViKVtcXC9cXHNdPyhbXFx3XFwuXSspL2lcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gVUNCcm93c2VyXG4gICAgICAgICAgICBdLCBbW05BTUUsICdVQ0Jyb3dzZXInXSwgVkVSU0lPTl0sIFtcblxuICAgICAgICAgICAgLyhjb21vZG9fZHJhZ29uKVxcLyhbXFx3XFwuXSspL2kgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBDb21vZG8gRHJhZ29uXG4gICAgICAgICAgICBdLCBbW05BTUUsIC9fL2csICcgJ10sIFZFUlNJT05dLCBbXG5cbiAgICAgICAgICAgIC8obWljcm9tZXNzZW5nZXIpXFwvKFtcXHdcXC5dKykvaSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gV2VDaGF0XG4gICAgICAgICAgICBdLCBbW05BTUUsICdXZUNoYXQnXSwgVkVSU0lPTl0sIFtcblxuICAgICAgICAgICAgLyhRUSlcXC8oW1xcZFxcLl0rKS9pICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBRUSwgYWthIFNob3VRXG4gICAgICAgICAgICBdLCBbTkFNRSwgVkVSU0lPTl0sIFtcblxuICAgICAgICAgICAgL20/KHFxYnJvd3NlcilbXFwvXFxzXT8oW1xcd1xcLl0rKS9pICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gUVFCcm93c2VyXG4gICAgICAgICAgICBdLCBbTkFNRSwgVkVSU0lPTl0sIFtcblxuICAgICAgICAgICAgL3hpYW9taVxcL21pdWlicm93c2VyXFwvKFtcXHdcXC5dKykvaSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gTUlVSSBCcm93c2VyXG4gICAgICAgICAgICBdLCBbVkVSU0lPTiwgW05BTUUsICdNSVVJIEJyb3dzZXInXV0sIFtcblxuICAgICAgICAgICAgLztmYmF2XFwvKFtcXHdcXC5dKyk7L2kgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBGYWNlYm9vayBBcHAgZm9yIGlPUyAmIEFuZHJvaWRcbiAgICAgICAgICAgIF0sIFtWRVJTSU9OLCBbTkFNRSwgJ0ZhY2Vib29rJ11dLCBbXG5cbiAgICAgICAgICAgIC8oaGVhZGxlc3NjaHJvbWUpIChbXFx3XFwuXSspL2kgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBDaHJvbWUgSGVhZGxlc3NcbiAgICAgICAgICAgIF0sIFtWRVJTSU9OLCBbTkFNRSwgJ0Nocm9tZSBIZWFkbGVzcyddXSwgW1xuXG4gICAgICAgICAgICAvXFxzd3ZcXCkuKyhjaHJvbWUpXFwvKFtcXHdcXC5dKykvaSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQ2hyb21lIFdlYlZpZXdcbiAgICAgICAgICAgIF0sIFtbTkFNRSwgLyguKykvLCAnJDEgV2ViVmlldyddLCBWRVJTSU9OXSwgW1xuXG4gICAgICAgICAgICAvKCg/Om9jdWx1c3xzYW1zdW5nKWJyb3dzZXIpXFwvKFtcXHdcXC5dKykvaVxuICAgICAgICAgICAgXSwgW1tOQU1FLCAvKC4rKD86Z3x1cykpKC4rKS8sICckMSAkMiddLCBWRVJTSU9OXSwgWyAgICAgICAgICAgICAgICAvLyBPY3VsdXMgLyBTYW1zdW5nIEJyb3dzZXJcblxuICAgICAgICAgICAgL2FuZHJvaWQuK3ZlcnNpb25cXC8oW1xcd1xcLl0rKVxccysoPzptb2JpbGVcXHM/c2FmYXJpfHNhZmFyaSkqL2kgICAgICAgIC8vIEFuZHJvaWQgQnJvd3NlclxuICAgICAgICAgICAgXSwgW1ZFUlNJT04sIFtOQU1FLCAnQW5kcm9pZCBCcm93c2VyJ11dLCBbXG5cbiAgICAgICAgICAgIC8oY2hyb21lfG9tbml3ZWJ8YXJvcmF8W3RpemVub2thXXs1fVxccz9icm93c2VyKVxcL3Y/KFtcXHdcXC5dKykvaVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBDaHJvbWUvT21uaVdlYi9Bcm9yYS9UaXplbi9Ob2tpYVxuICAgICAgICAgICAgXSwgW05BTUUsIFZFUlNJT05dLCBbXG5cbiAgICAgICAgICAgIC8oZG9sZmluKVxcLyhbXFx3XFwuXSspL2kgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gRG9scGhpblxuICAgICAgICAgICAgXSwgW1tOQU1FLCAnRG9scGhpbiddLCBWRVJTSU9OXSwgW1xuXG4gICAgICAgICAgICAvKCg/OmFuZHJvaWQuKyljcm1vfGNyaW9zKVxcLyhbXFx3XFwuXSspL2kgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIENocm9tZSBmb3IgQW5kcm9pZC9pT1NcbiAgICAgICAgICAgIF0sIFtbTkFNRSwgJ0Nocm9tZSddLCBWRVJTSU9OXSwgW1xuXG4gICAgICAgICAgICAvKGNvYXN0KVxcLyhbXFx3XFwuXSspL2kgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE9wZXJhIENvYXN0XG4gICAgICAgICAgICBdLCBbW05BTUUsICdPcGVyYSBDb2FzdCddLCBWRVJTSU9OXSwgW1xuXG4gICAgICAgICAgICAvZnhpb3NcXC8oW1xcd1xcLi1dKykvaSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEZpcmVmb3ggZm9yIGlPU1xuICAgICAgICAgICAgXSwgW1ZFUlNJT04sIFtOQU1FLCAnRmlyZWZveCddXSwgW1xuXG4gICAgICAgICAgICAvdmVyc2lvblxcLyhbXFx3XFwuXSspLis/bW9iaWxlXFwvXFx3K1xccyhzYWZhcmkpL2kgICAgICAgICAgICAgICAgICAgICAgIC8vIE1vYmlsZSBTYWZhcmlcbiAgICAgICAgICAgIF0sIFtWRVJTSU9OLCBbTkFNRSwgJ01vYmlsZSBTYWZhcmknXV0sIFtcblxuICAgICAgICAgICAgL3ZlcnNpb25cXC8oW1xcd1xcLl0rKS4rPyhtb2JpbGVcXHM/c2FmYXJpfHNhZmFyaSkvaSAgICAgICAgICAgICAgICAgICAgLy8gU2FmYXJpICYgU2FmYXJpIE1vYmlsZVxuICAgICAgICAgICAgXSwgW1ZFUlNJT04sIE5BTUVdLCBbXG5cbiAgICAgICAgICAgIC93ZWJraXQuKz8obW9iaWxlXFxzP3NhZmFyaXxzYWZhcmkpKFxcL1tcXHdcXC5dKykvaSAgICAgICAgICAgICAgICAgICAgIC8vIFNhZmFyaSA8IDMuMFxuICAgICAgICAgICAgXSwgW05BTUUsIFtWRVJTSU9OLCBtYXBwZXIuc3RyLCBtYXBzLmJyb3dzZXIub2xkc2FmYXJpLnZlcnNpb25dXSwgW1xuXG4gICAgICAgICAgICAvKGtvbnF1ZXJvcilcXC8oW1xcd1xcLl0rKS9pLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEtvbnF1ZXJvclxuICAgICAgICAgICAgLyh3ZWJraXR8a2h0bWwpXFwvKFtcXHdcXC5dKykvaVxuICAgICAgICAgICAgXSwgW05BTUUsIFZFUlNJT05dLCBbXG5cbiAgICAgICAgICAgIC8vIEdlY2tvIGJhc2VkXG4gICAgICAgICAgICAvKG5hdmlnYXRvcnxuZXRzY2FwZSlcXC8oW1xcd1xcLi1dKykvaSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE5ldHNjYXBlXG4gICAgICAgICAgICBdLCBbW05BTUUsICdOZXRzY2FwZSddLCBWRVJTSU9OXSwgW1xuICAgICAgICAgICAgLyhzd2lmdGZveCkvaSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBTd2lmdGZveFxuICAgICAgICAgICAgLyhpY2VkcmFnb258aWNld2Vhc2VsfGNhbWlub3xjaGltZXJhfGZlbm5lY3xtYWVtb1xcc2Jyb3dzZXJ8bWluaW1vfGNvbmtlcm9yKVtcXC9cXHNdPyhbXFx3XFwuXFwrXSspL2ksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEljZURyYWdvbi9JY2V3ZWFzZWwvQ2FtaW5vL0NoaW1lcmEvRmVubmVjL01hZW1vL01pbmltby9Db25rZXJvclxuICAgICAgICAgICAgLyhmaXJlZm94fHNlYW1vbmtleXxrLW1lbGVvbnxpY2VjYXR8aWNlYXBlfGZpcmViaXJkfHBob2VuaXgpXFwvKFtcXHdcXC4tXSspL2ksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEZpcmVmb3gvU2VhTW9ua2V5L0stTWVsZW9uL0ljZUNhdC9JY2VBcGUvRmlyZWJpcmQvUGhvZW5peFxuICAgICAgICAgICAgLyhtb3ppbGxhKVxcLyhbXFx3XFwuXSspLitydlxcOi4rZ2Vja29cXC9cXGQrL2ksICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBNb3ppbGxhXG5cbiAgICAgICAgICAgIC8vIE90aGVyXG4gICAgICAgICAgICAvKHBvbGFyaXN8bHlueHxkaWxsb3xpY2FifGRvcmlzfGFtYXlhfHczbXxuZXRzdXJmfHNsZWlwbmlyKVtcXC9cXHNdPyhbXFx3XFwuXSspL2ksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFBvbGFyaXMvTHlueC9EaWxsby9pQ2FiL0RvcmlzL0FtYXlhL3czbS9OZXRTdXJmL1NsZWlwbmlyXG4gICAgICAgICAgICAvKGxpbmtzKVxcc1xcKChbXFx3XFwuXSspL2ksICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBMaW5rc1xuICAgICAgICAgICAgLyhnb2Jyb3dzZXIpXFwvPyhbXFx3XFwuXSspKi9pLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBHb0Jyb3dzZXJcbiAgICAgICAgICAgIC8oaWNlXFxzP2Jyb3dzZXIpXFwvdj8oW1xcd1xcLl9dKykvaSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIElDRSBCcm93c2VyXG4gICAgICAgICAgICAvKG1vc2FpYylbXFwvXFxzXShbXFx3XFwuXSspL2kgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBNb3NhaWNcbiAgICAgICAgICAgIF0sIFtOQU1FLCBWRVJTSU9OXVxuXG4gICAgICAgICAgICAvKiAvLy8vLy8vLy8vLy8vLy8vLy8vLy9cbiAgICAgICAgICAgIC8vIE1lZGlhIHBsYXllcnMgQkVHSU5cbiAgICAgICAgICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXG4gICAgICAgICAgICAsIFtcblxuICAgICAgICAgICAgLyhhcHBsZSg/OmNvcmVtZWRpYXwpKVxcLygoXFxkKylbXFx3XFwuX10rKS9pLCAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gR2VuZXJpYyBBcHBsZSBDb3JlTWVkaWFcbiAgICAgICAgICAgIC8oY29yZW1lZGlhKSB2KChcXGQrKVtcXHdcXC5fXSspL2lcbiAgICAgICAgICAgIF0sIFtOQU1FLCBWRVJTSU9OXSwgW1xuXG4gICAgICAgICAgICAvKGFxdWFsdW5nfGx5c3NuYXxic3BsYXllcilcXC8oKFxcZCspP1tcXHdcXC4tXSspL2kgICAgICAgICAgICAgICAgICAgICAvLyBBcXVhbHVuZy9MeXNzbmEvQlNQbGF5ZXJcbiAgICAgICAgICAgIF0sIFtOQU1FLCBWRVJTSU9OXSwgW1xuXG4gICAgICAgICAgICAvKGFyZXN8b3NzcHJveHkpXFxzKChcXGQrKVtcXHdcXC4tXSspL2kgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBBcmVzL09TU1Byb3h5XG4gICAgICAgICAgICBdLCBbTkFNRSwgVkVSU0lPTl0sIFtcblxuICAgICAgICAgICAgLyhhdWRhY2lvdXN8YXVkaW11c2ljc3RyZWFtfGFtYXJva3xiYXNzfGNvcmV8ZGFsdmlrfGdub21lbXBsYXllcnxtdXNpYyBvbiBjb25zb2xlfG5zcGxheWVyfHBzcC1pbnRlcm5ldHJhZGlvcGxheWVyfHZpZGVvcylcXC8oKFxcZCspW1xcd1xcLi1dKykvaSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQXVkYWNpb3VzL0F1ZGlNdXNpY1N0cmVhbS9BbWFyb2svQkFTUy9PcGVuQ09SRS9EYWx2aWsvR25vbWVNcGxheWVyL01vQ1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBOU1BsYXllci9QU1AtSW50ZXJuZXRSYWRpb1BsYXllci9WaWRlb3NcbiAgICAgICAgICAgIC8oY2xlbWVudGluZXxtdXNpYyBwbGF5ZXIgZGFlbW9uKVxccygoXFxkKylbXFx3XFwuLV0rKS9pLCAgICAgICAgICAgICAgIC8vIENsZW1lbnRpbmUvTVBEXG4gICAgICAgICAgICAvKGxnIHBsYXllcnxuZXhwbGF5ZXIpXFxzKChcXGQrKVtcXGRcXC5dKykvaSxcbiAgICAgICAgICAgIC9wbGF5ZXJcXC8obmV4cGxheWVyfGxnIHBsYXllcilcXHMoKFxcZCspW1xcd1xcLi1dKykvaSAgICAgICAgICAgICAgICAgICAvLyBOZXhQbGF5ZXIvTEcgUGxheWVyXG4gICAgICAgICAgICBdLCBbTkFNRSwgVkVSU0lPTl0sIFtcbiAgICAgICAgICAgIC8obmV4cGxheWVyKVxccygoXFxkKylbXFx3XFwuLV0rKS9pICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE5leHBsYXllclxuICAgICAgICAgICAgXSwgW05BTUUsIFZFUlNJT05dLCBbXG5cbiAgICAgICAgICAgIC8oZmxycClcXC8oKFxcZCspW1xcd1xcLi1dKykvaSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEZsaXAgUGxheWVyXG4gICAgICAgICAgICBdLCBbW05BTUUsICdGbGlwIFBsYXllciddLCBWRVJTSU9OXSwgW1xuXG4gICAgICAgICAgICAvKGZzdHJlYW18bmF0aXZlaG9zdHxxdWVyeXNlZWtzcGlkZXJ8aWEtYXJjaGl2ZXJ8ZmFjZWJvb2tleHRlcm5hbGhpdCkvaVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBGU3RyZWFtL05hdGl2ZUhvc3QvUXVlcnlTZWVrU3BpZGVyL0lBIEFyY2hpdmVyL2ZhY2Vib29rZXh0ZXJuYWxoaXRcbiAgICAgICAgICAgIF0sIFtOQU1FXSwgW1xuXG4gICAgICAgICAgICAvKGdzdHJlYW1lcikgc291cGh0dHBzcmMgKD86XFwoW15cXCldK1xcKSl7MCwxfSBsaWJzb3VwXFwvKChcXGQrKVtcXHdcXC4tXSspL2lcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gR3N0cmVhbWVyXG4gICAgICAgICAgICBdLCBbTkFNRSwgVkVSU0lPTl0sIFtcblxuICAgICAgICAgICAgLyhodGMgc3RyZWFtaW5nIHBsYXllcilcXHNbXFx3X10rXFxzXFwvXFxzKChcXGQrKVtcXGRcXC5dKykvaSwgICAgICAgICAgICAgIC8vIEhUQyBTdHJlYW1pbmcgUGxheWVyXG4gICAgICAgICAgICAvKGphdmF8cHl0aG9uLXVybGxpYnxweXRob24tcmVxdWVzdHN8d2dldHxsaWJjdXJsKVxcLygoXFxkKylbXFx3XFwuLV9dKykvaSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gSmF2YS91cmxsaWIvcmVxdWVzdHMvd2dldC9jVVJMXG4gICAgICAgICAgICAvKGxhdmYpKChcXGQrKVtcXGRcXC5dKykvaSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIExhdmYgKEZGTVBFRylcbiAgICAgICAgICAgIF0sIFtOQU1FLCBWRVJTSU9OXSwgW1xuXG4gICAgICAgICAgICAvKGh0Y19vbmVfcylcXC8oKFxcZCspW1xcZFxcLl0rKS9pICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBIVEMgT25lIFNcbiAgICAgICAgICAgIF0sIFtbTkFNRSwgL18vZywgJyAnXSwgVkVSU0lPTl0sIFtcblxuICAgICAgICAgICAgLyhtcGxheWVyKSg/Olxcc3xcXC8pKD86KD86c2hlcnB5YS0pezAsMX1zdm4pKD86LXxcXHMpKHJcXGQrKD86LVxcZCtbXFx3XFwuLV0rKXswLDF9KS9pXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE1QbGF5ZXIgU1ZOXG4gICAgICAgICAgICBdLCBbTkFNRSwgVkVSU0lPTl0sIFtcblxuICAgICAgICAgICAgLyhtcGxheWVyKSg/Olxcc3xcXC98W3Vua293LV0rKSgoXFxkKylbXFx3XFwuLV0rKS9pICAgICAgICAgICAgICAgICAgICAgIC8vIE1QbGF5ZXJcbiAgICAgICAgICAgIF0sIFtOQU1FLCBWRVJTSU9OXSwgW1xuXG4gICAgICAgICAgICAvKG1wbGF5ZXIpL2ksICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE1QbGF5ZXIgKG5vIG90aGVyIGluZm8pXG4gICAgICAgICAgICAvKHlvdXJtdXplKS9pLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFlvdXJNdXplXG4gICAgICAgICAgICAvKG1lZGlhIHBsYXllciBjbGFzc2ljfG5lcm8gc2hvd3RpbWUpL2kgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE1lZGlhIFBsYXllciBDbGFzc2ljL05lcm8gU2hvd1RpbWVcbiAgICAgICAgICAgIF0sIFtOQU1FXSwgW1xuXG4gICAgICAgICAgICAvKG5lcm8gKD86aG9tZXxzY291dCkpXFwvKChcXGQrKVtcXHdcXC4tXSspL2kgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBOZXJvIEhvbWUvTmVybyBTY291dFxuICAgICAgICAgICAgXSwgW05BTUUsIFZFUlNJT05dLCBbXG5cbiAgICAgICAgICAgIC8obm9raWFcXGQrKVxcLygoXFxkKylbXFx3XFwuLV0rKS9pICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBOb2tpYVxuICAgICAgICAgICAgXSwgW05BTUUsIFZFUlNJT05dLCBbXG5cbiAgICAgICAgICAgIC9cXHMoc29uZ2JpcmQpXFwvKChcXGQrKVtcXHdcXC4tXSspL2kgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBTb25nYmlyZC9QaGlsaXBzLVNvbmdiaXJkXG4gICAgICAgICAgICBdLCBbTkFNRSwgVkVSU0lPTl0sIFtcblxuICAgICAgICAgICAgLyh3aW5hbXApMyB2ZXJzaW9uICgoXFxkKylbXFx3XFwuLV0rKS9pLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBXaW5hbXBcbiAgICAgICAgICAgIC8od2luYW1wKVxccygoXFxkKylbXFx3XFwuLV0rKS9pLFxuICAgICAgICAgICAgLyh3aW5hbXApbXBlZ1xcLygoXFxkKylbXFx3XFwuLV0rKS9pXG4gICAgICAgICAgICBdLCBbTkFNRSwgVkVSU0lPTl0sIFtcblxuICAgICAgICAgICAgLyhvY21zLWJvdHx0YXBpbnJhZGlvfHR1bmVpbiByYWRpb3x1bmtub3dufHdpbmFtcHxpbmxpZ2h0IHJhZGlvKS9pICAvLyBPQ01TLWJvdC90YXAgaW4gcmFkaW8vdHVuZWluL3Vua25vd24vd2luYW1wIChubyBvdGhlciBpbmZvKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBpbmxpZ2h0IHJhZGlvXG4gICAgICAgICAgICBdLCBbTkFNRV0sIFtcblxuICAgICAgICAgICAgLyhxdWlja3RpbWV8cm1hfHJhZGlvYXBwfHJhZGlvY2xpZW50YXBwbGljYXRpb258c291bmR0YXB8dG90ZW18c3RhZ2VmcmlnaHR8c3RyZWFtaXVtKVxcLygoXFxkKylbXFx3XFwuLV0rKS9pXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFF1aWNrVGltZS9SZWFsTWVkaWEvUmFkaW9BcHAvUmFkaW9DbGllbnRBcHBsaWNhdGlvbi9cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gU291bmRUYXAvVG90ZW0vU3RhZ2VmcmlnaHQvU3RyZWFtaXVtXG4gICAgICAgICAgICBdLCBbTkFNRSwgVkVSU0lPTl0sIFtcblxuICAgICAgICAgICAgLyhzbXApKChcXGQrKVtcXGRcXC5dKykvaSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBTTVBcbiAgICAgICAgICAgIF0sIFtOQU1FLCBWRVJTSU9OXSwgW1xuXG4gICAgICAgICAgICAvKHZsYykgbWVkaWEgcGxheWVyIC0gdmVyc2lvbiAoKFxcZCspW1xcd1xcLl0rKS9pLCAgICAgICAgICAgICAgICAgICAgIC8vIFZMQyBWaWRlb2xhblxuICAgICAgICAgICAgLyh2bGMpXFwvKChcXGQrKVtcXHdcXC4tXSspL2ksXG4gICAgICAgICAgICAvKHhibWN8Z3Zmc3x4aW5lfHhtbXN8aXJhcHApXFwvKChcXGQrKVtcXHdcXC4tXSspL2ksICAgICAgICAgICAgICAgICAgICAvLyBYQk1DL2d2ZnMvWGluZS9YTU1TL2lyYXBwXG4gICAgICAgICAgICAvKGZvb2JhcjIwMDApXFwvKChcXGQrKVtcXGRcXC5dKykvaSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBGb29iYXIyMDAwXG4gICAgICAgICAgICAvKGl0dW5lcylcXC8oKFxcZCspW1xcZFxcLl0rKS9pICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBpVHVuZXNcbiAgICAgICAgICAgIF0sIFtOQU1FLCBWRVJTSU9OXSwgW1xuXG4gICAgICAgICAgICAvKHdtcGxheWVyKVxcLygoXFxkKylbXFx3XFwuLV0rKS9pLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBXaW5kb3dzIE1lZGlhIFBsYXllclxuICAgICAgICAgICAgLyh3aW5kb3dzLW1lZGlhLXBsYXllcilcXC8oKFxcZCspW1xcd1xcLi1dKykvaVxuICAgICAgICAgICAgXSwgW1tOQU1FLCAvLS9nLCAnICddLCBWRVJTSU9OXSwgW1xuXG4gICAgICAgICAgICAvd2luZG93c1xcLygoXFxkKylbXFx3XFwuLV0rKSB1cG5wXFwvW1xcZFxcLl0rIGRsbmFkb2NcXC9bXFxkXFwuXSsgKGhvbWUgbWVkaWEgc2VydmVyKS9pXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFdpbmRvd3MgTWVkaWEgU2VydmVyXG4gICAgICAgICAgICBdLCBbVkVSU0lPTiwgW05BTUUsICdXaW5kb3dzJ11dLCBbXG5cbiAgICAgICAgICAgIC8oY29tXFwucmlzZXVwcmFkaW9hbGFybSlcXC8oKFxcZCspW1xcZFxcLl0qKS9pICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBSaXNlVVAgUmFkaW8gQWxhcm1cbiAgICAgICAgICAgIF0sIFtOQU1FLCBWRVJTSU9OXSwgW1xuXG4gICAgICAgICAgICAvKHJhZC5pbylcXHMoKFxcZCspW1xcZFxcLl0rKS9pLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBSYWQuaW9cbiAgICAgICAgICAgIC8ocmFkaW8uKD86ZGV8YXR8ZnIpKVxccygoXFxkKylbXFxkXFwuXSspL2lcbiAgICAgICAgICAgIF0sIFtbTkFNRSwgJ3JhZC5pbyddLCBWRVJTSU9OXVxuXG4gICAgICAgICAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG4gICAgICAgICAgICAvLyBNZWRpYSBwbGF5ZXJzIEVORFxuICAgICAgICAgICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8qL1xuXG4gICAgICAgIF0sXG5cbiAgICAgICAgY3B1IDogW1tcblxuICAgICAgICAgICAgLyg/OihhbWR8eCg/Oig/Ojg2fDY0KVtfLV0pP3x3b3d8d2luKTY0KVs7XFwpXS9pICAgICAgICAgICAgICAgICAgICAgLy8gQU1ENjRcbiAgICAgICAgICAgIF0sIFtbQVJDSElURUNUVVJFLCAnYW1kNjQnXV0sIFtcblxuICAgICAgICAgICAgLyhpYTMyKD89OykpL2kgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBJQTMyIChxdWlja3RpbWUpXG4gICAgICAgICAgICBdLCBbW0FSQ0hJVEVDVFVSRSwgdXRpbC5sb3dlcml6ZV1dLCBbXG5cbiAgICAgICAgICAgIC8oKD86aVszNDZdfHgpODYpWztcXCldL2kgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIElBMzJcbiAgICAgICAgICAgIF0sIFtbQVJDSElURUNUVVJFLCAnaWEzMiddXSwgW1xuXG4gICAgICAgICAgICAvLyBQb2NrZXRQQyBtaXN0YWtlbmx5IGlkZW50aWZpZWQgYXMgUG93ZXJQQ1xuICAgICAgICAgICAgL3dpbmRvd3NcXHMoY2V8bW9iaWxlKTtcXHNwcGM7L2lcbiAgICAgICAgICAgIF0sIFtbQVJDSElURUNUVVJFLCAnYXJtJ11dLCBbXG5cbiAgICAgICAgICAgIC8oKD86cHBjfHBvd2VycGMpKD86NjQpPykoPzpcXHNtYWN8O3xcXCkpL2kgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBQb3dlclBDXG4gICAgICAgICAgICBdLCBbW0FSQ0hJVEVDVFVSRSwgL293ZXIvLCAnJywgdXRpbC5sb3dlcml6ZV1dLCBbXG5cbiAgICAgICAgICAgIC8oc3VuNFxcdylbO1xcKV0vaSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBTUEFSQ1xuICAgICAgICAgICAgXSwgW1tBUkNISVRFQ1RVUkUsICdzcGFyYyddXSwgW1xuXG4gICAgICAgICAgICAvKCg/OmF2cjMyfGlhNjQoPz07KSl8NjhrKD89XFwpKXxhcm0oPzo2NHwoPz12XFxkKzspKXwoPz1hdG1lbFxccylhdnJ8KD86aXJpeHxtaXBzfHNwYXJjKSg/OjY0KT8oPz07KXxwYS1yaXNjKS9pXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIElBNjQsIDY4SywgQVJNLzY0LCBBVlIvMzIsIElSSVgvNjQsIE1JUFMvNjQsIFNQQVJDLzY0LCBQQS1SSVNDXG4gICAgICAgICAgICBdLCBbW0FSQ0hJVEVDVFVSRSwgdXRpbC5sb3dlcml6ZV1dXG4gICAgICAgIF0sXG5cbiAgICAgICAgZGV2aWNlIDogW1tcblxuICAgICAgICAgICAgL1xcKChpcGFkfHBsYXlib29rKTtbXFx3XFxzXFwpOy1dKyhyaW18YXBwbGUpL2kgICAgICAgICAgICAgICAgICAgICAgICAgLy8gaVBhZC9QbGF5Qm9va1xuICAgICAgICAgICAgXSwgW01PREVMLCBWRU5ET1IsIFtUWVBFLCBUQUJMRVRdXSwgW1xuXG4gICAgICAgICAgICAvYXBwbGVjb3JlbWVkaWFcXC9bXFx3XFwuXSsgXFwoKGlwYWQpLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBpUGFkXG4gICAgICAgICAgICBdLCBbTU9ERUwsIFtWRU5ET1IsICdBcHBsZSddLCBbVFlQRSwgVEFCTEVUXV0sIFtcblxuICAgICAgICAgICAgLyhhcHBsZVxcc3swLDF9dHYpL2kgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQXBwbGUgVFZcbiAgICAgICAgICAgIF0sIFtbTU9ERUwsICdBcHBsZSBUViddLCBbVkVORE9SLCAnQXBwbGUnXV0sIFtcblxuICAgICAgICAgICAgLyhhcmNob3MpXFxzKGdhbWVwYWQyPykvaSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQXJjaG9zXG4gICAgICAgICAgICAvKGhwKS4rKHRvdWNocGFkKS9pLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEhQIFRvdWNoUGFkXG4gICAgICAgICAgICAvKGhwKS4rKHRhYmxldCkvaSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEhQIFRhYmxldFxuICAgICAgICAgICAgLyhraW5kbGUpXFwvKFtcXHdcXC5dKykvaSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBLaW5kbGVcbiAgICAgICAgICAgIC9cXHMobm9vaylbXFx3XFxzXStidWlsZFxcLyhcXHcrKS9pLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBOb29rXG4gICAgICAgICAgICAvKGRlbGwpXFxzKHN0cmVhW2twclxcc1xcZF0qW1xcZGtvXSkvaSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBEZWxsIFN0cmVha1xuICAgICAgICAgICAgXSwgW1ZFTkRPUiwgTU9ERUwsIFtUWVBFLCBUQUJMRVRdXSwgW1xuXG4gICAgICAgICAgICAvKGtmW0Etel0rKVxcc2J1aWxkXFwvW1xcd1xcLl0rLipzaWxrXFwvL2kgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gS2luZGxlIEZpcmUgSERcbiAgICAgICAgICAgIF0sIFtNT0RFTCwgW1ZFTkRPUiwgJ0FtYXpvbiddLCBbVFlQRSwgVEFCTEVUXV0sIFtcbiAgICAgICAgICAgIC8oc2R8a2YpWzAzNDloaWpvcnN0dXddK1xcc2J1aWxkXFwvW1xcd1xcLl0rLipzaWxrXFwvL2kgICAgICAgICAgICAgICAgICAvLyBGaXJlIFBob25lXG4gICAgICAgICAgICBdLCBbW01PREVMLCBtYXBwZXIuc3RyLCBtYXBzLmRldmljZS5hbWF6b24ubW9kZWxdLCBbVkVORE9SLCAnQW1hem9uJ10sIFtUWVBFLCBNT0JJTEVdXSwgW1xuXG4gICAgICAgICAgICAvXFwoKGlwW2hvbmVkfFxcc1xcdypdKyk7LisoYXBwbGUpL2kgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGlQb2QvaVBob25lXG4gICAgICAgICAgICBdLCBbTU9ERUwsIFZFTkRPUiwgW1RZUEUsIE1PQklMRV1dLCBbXG4gICAgICAgICAgICAvXFwoKGlwW2hvbmVkfFxcc1xcdypdKyk7L2kgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGlQb2QvaVBob25lXG4gICAgICAgICAgICBdLCBbTU9ERUwsIFtWRU5ET1IsICdBcHBsZSddLCBbVFlQRSwgTU9CSUxFXV0sIFtcblxuICAgICAgICAgICAgLyhibGFja2JlcnJ5KVtcXHMtXT8oXFx3KykvaSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEJsYWNrQmVycnlcbiAgICAgICAgICAgIC8oYmxhY2tiZXJyeXxiZW5xfHBhbG0oPz1cXC0pfHNvbnllcmljc3NvbnxhY2VyfGFzdXN8ZGVsbHxtZWl6dXxtb3Rvcm9sYXxwb2x5dHJvbilbXFxzXy1dPyhbXFx3LV0rKSovaSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQmVuUS9QYWxtL1NvbnktRXJpY3Nzb24vQWNlci9Bc3VzL0RlbGwvTWVpenUvTW90b3JvbGEvUG9seXRyb25cbiAgICAgICAgICAgIC8oaHApXFxzKFtcXHdcXHNdK1xcdykvaSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEhQIGlQQVFcbiAgICAgICAgICAgIC8oYXN1cyktPyhcXHcrKS9pICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEFzdXNcbiAgICAgICAgICAgIF0sIFtWRU5ET1IsIE1PREVMLCBbVFlQRSwgTU9CSUxFXV0sIFtcbiAgICAgICAgICAgIC9cXChiYjEwO1xccyhcXHcrKS9pICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQmxhY2tCZXJyeSAxMFxuICAgICAgICAgICAgXSwgW01PREVMLCBbVkVORE9SLCAnQmxhY2tCZXJyeSddLCBbVFlQRSwgTU9CSUxFXV0sIFtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQXN1cyBUYWJsZXRzXG4gICAgICAgICAgICAvYW5kcm9pZC4rKHRyYW5zZm9bcHJpbWVcXHNdezQsMTB9XFxzXFx3K3xlZWVwY3xzbGlkZXJcXHNcXHcrfG5leHVzIDd8cGFkZm9uZSkvaVxuICAgICAgICAgICAgXSwgW01PREVMLCBbVkVORE9SLCAnQXN1cyddLCBbVFlQRSwgVEFCTEVUXV0sIFtcblxuICAgICAgICAgICAgLyhzb255KVxccyh0YWJsZXRcXHNbcHNdKVxcc2J1aWxkXFwvL2ksICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFNvbnlcbiAgICAgICAgICAgIC8oc29ueSk/KD86c2dwLispXFxzYnVpbGRcXC8vaVxuICAgICAgICAgICAgXSwgW1tWRU5ET1IsICdTb255J10sIFtNT0RFTCwgJ1hwZXJpYSBUYWJsZXQnXSwgW1RZUEUsIFRBQkxFVF1dLCBbXG4gICAgICAgICAgICAvYW5kcm9pZC4rXFxzKFtjLWddXFxkezR9fHNvWy1sXVxcdyspXFxzYnVpbGRcXC8vaVxuICAgICAgICAgICAgXSwgW01PREVMLCBbVkVORE9SLCAnU29ueSddLCBbVFlQRSwgTU9CSUxFXV0sIFtcblxuICAgICAgICAgICAgL1xccyhvdXlhKVxccy9pLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE91eWFcbiAgICAgICAgICAgIC8obmludGVuZG8pXFxzKFt3aWRzM3VdKykvaSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE5pbnRlbmRvXG4gICAgICAgICAgICBdLCBbVkVORE9SLCBNT0RFTCwgW1RZUEUsIENPTlNPTEVdXSwgW1xuXG4gICAgICAgICAgICAvYW5kcm9pZC4rO1xccyhzaGllbGQpXFxzYnVpbGQvaSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gTnZpZGlhXG4gICAgICAgICAgICBdLCBbTU9ERUwsIFtWRU5ET1IsICdOdmlkaWEnXSwgW1RZUEUsIENPTlNPTEVdXSwgW1xuXG4gICAgICAgICAgICAvKHBsYXlzdGF0aW9uXFxzWzM0cG9ydGFibGV2aV0rKS9pICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBQbGF5c3RhdGlvblxuICAgICAgICAgICAgXSwgW01PREVMLCBbVkVORE9SLCAnU29ueSddLCBbVFlQRSwgQ09OU09MRV1dLCBbXG5cbiAgICAgICAgICAgIC8oc3ByaW50XFxzKFxcdyspKS9pICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBTcHJpbnQgUGhvbmVzXG4gICAgICAgICAgICBdLCBbW1ZFTkRPUiwgbWFwcGVyLnN0ciwgbWFwcy5kZXZpY2Uuc3ByaW50LnZlbmRvcl0sIFtNT0RFTCwgbWFwcGVyLnN0ciwgbWFwcy5kZXZpY2Uuc3ByaW50Lm1vZGVsXSwgW1RZUEUsIE1PQklMRV1dLCBbXG5cbiAgICAgICAgICAgIC8obGVub3ZvKVxccz8oUyg/OjUwMDB8NjAwMCkrKD86Wy1dW1xcdytdKSkvaSAgICAgICAgICAgICAgICAgICAgICAgICAvLyBMZW5vdm8gdGFibGV0c1xuICAgICAgICAgICAgXSwgW1ZFTkRPUiwgTU9ERUwsIFtUWVBFLCBUQUJMRVRdXSwgW1xuXG4gICAgICAgICAgICAvKGh0YylbO19cXHMtXSsoW1xcd1xcc10rKD89XFwpKXxcXHcrKSovaSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gSFRDXG4gICAgICAgICAgICAvKHp0ZSktKFxcdyspKi9pLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBaVEVcbiAgICAgICAgICAgIC8oYWxjYXRlbHxnZWVrc3Bob25lfGxlbm92b3xuZXhpYW58cGFuYXNvbmljfCg/PTtcXHMpc29ueSlbX1xccy1dPyhbXFx3LV0rKSovaVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBBbGNhdGVsL0dlZWtzUGhvbmUvTGVub3ZvL05leGlhbi9QYW5hc29uaWMvU29ueVxuICAgICAgICAgICAgXSwgW1ZFTkRPUiwgW01PREVMLCAvXy9nLCAnICddLCBbVFlQRSwgTU9CSUxFXV0sIFtcblxuICAgICAgICAgICAgLyhuZXh1c1xcczkpL2kgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gSFRDIE5leHVzIDlcbiAgICAgICAgICAgIF0sIFtNT0RFTCwgW1ZFTkRPUiwgJ0hUQyddLCBbVFlQRSwgVEFCTEVUXV0sIFtcblxuICAgICAgICAgICAgL2RcXC9odWF3ZWkoW1xcd1xccy1dKylbO1xcKV0vaSxcbiAgICAgICAgICAgIC8obmV4dXNcXHM2cCkvaSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEh1YXdlaVxuICAgICAgICAgICAgXSwgW01PREVMLCBbVkVORE9SLCAnSHVhd2VpJ10sIFtUWVBFLCBNT0JJTEVdXSwgW1xuXG4gICAgICAgICAgICAvKG1pY3Jvc29mdCk7XFxzKGx1bWlhW1xcc1xcd10rKS9pICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE1pY3Jvc29mdCBMdW1pYVxuICAgICAgICAgICAgXSwgW1ZFTkRPUiwgTU9ERUwsIFtUWVBFLCBNT0JJTEVdXSwgW1xuXG4gICAgICAgICAgICAvW1xcc1xcKDtdKHhib3goPzpcXHNvbmUpPylbXFxzXFwpO10vaSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gTWljcm9zb2Z0IFhib3hcbiAgICAgICAgICAgIF0sIFtNT0RFTCwgW1ZFTkRPUiwgJ01pY3Jvc29mdCddLCBbVFlQRSwgQ09OU09MRV1dLCBbXG4gICAgICAgICAgICAvKGtpblxcLltvbmV0d117M30pL2kgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBNaWNyb3NvZnQgS2luXG4gICAgICAgICAgICBdLCBbW01PREVMLCAvXFwuL2csICcgJ10sIFtWRU5ET1IsICdNaWNyb3NvZnQnXSwgW1RZUEUsIE1PQklMRV1dLCBbXG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gTW90b3JvbGFcbiAgICAgICAgICAgIC9cXHMobWlsZXN0b25lfGRyb2lkKD86WzItNHhdfFxccyg/OmJpb25pY3x4Mnxwcm98cmF6cikpPyg6P1xcczRnKT8pW1xcd1xcc10rYnVpbGRcXC8vaSxcbiAgICAgICAgICAgIC9tb3RbXFxzLV0/KFxcdyspKi9pLFxuICAgICAgICAgICAgLyhYVFxcZHszLDR9KSBidWlsZFxcLy9pLFxuICAgICAgICAgICAgLyhuZXh1c1xcczYpL2lcbiAgICAgICAgICAgIF0sIFtNT0RFTCwgW1ZFTkRPUiwgJ01vdG9yb2xhJ10sIFtUWVBFLCBNT0JJTEVdXSwgW1xuICAgICAgICAgICAgL2FuZHJvaWQuK1xccyhtejYwXFxkfHhvb21bXFxzMl17MCwyfSlcXHNidWlsZFxcLy9pXG4gICAgICAgICAgICBdLCBbTU9ERUwsIFtWRU5ET1IsICdNb3Rvcm9sYSddLCBbVFlQRSwgVEFCTEVUXV0sIFtcblxuICAgICAgICAgICAgL2hiYnR2XFwvXFxkK1xcLlxcZCtcXC5cXGQrXFxzK1xcKFtcXHdcXHNdKjtcXHMqKFxcd1teO10qKTsoW147XSopL2kgICAgICAgICAgICAvLyBIYmJUViBkZXZpY2VzXG4gICAgICAgICAgICBdLCBbW1ZFTkRPUiwgdXRpbC50cmltXSwgW01PREVMLCB1dGlsLnRyaW1dLCBbVFlQRSwgU01BUlRUVl1dLCBbXG5cbiAgICAgICAgICAgIC9oYmJ0di4rbWFwbGU7KFxcZCspL2lcbiAgICAgICAgICAgIF0sIFtbTU9ERUwsIC9eLywgJ1NtYXJ0VFYnXSwgW1ZFTkRPUiwgJ1NhbXN1bmcnXSwgW1RZUEUsIFNNQVJUVFZdXSwgW1xuXG4gICAgICAgICAgICAvXFwoZHR2W1xcKTtdLisoYXF1b3MpL2kgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gU2hhcnBcbiAgICAgICAgICAgIF0sIFtNT0RFTCwgW1ZFTkRPUiwgJ1NoYXJwJ10sIFtUWVBFLCBTTUFSVFRWXV0sIFtcblxuICAgICAgICAgICAgL2FuZHJvaWQuKygoc2NoLWlbODldMFxcZHxzaHctbTM4MHN8Z3QtcFxcZHs0fXxndC1uXFxkK3xzZ2gtdDhbNTZdOXxuZXh1cyAxMCkpL2ksXG4gICAgICAgICAgICAvKChTTS1UXFx3KykpL2lcbiAgICAgICAgICAgIF0sIFtbVkVORE9SLCAnU2Ftc3VuZyddLCBNT0RFTCwgW1RZUEUsIFRBQkxFVF1dLCBbICAgICAgICAgICAgICAgICAgLy8gU2Ftc3VuZ1xuICAgICAgICAgICAgL3NtYXJ0LXR2Lisoc2Ftc3VuZykvaVxuICAgICAgICAgICAgXSwgW1ZFTkRPUiwgW1RZUEUsIFNNQVJUVFZdLCBNT0RFTF0sIFtcbiAgICAgICAgICAgIC8oKHNbY2dwXWgtXFx3K3xndC1cXHcrfGdhbGF4eVxcc25leHVzfHNtLVxcd1tcXHdcXGRdKykpL2ksXG4gICAgICAgICAgICAvKHNhbVtzdW5nXSopW1xccy1dKihcXHcrLT9bXFx3LV0qKSovaSxcbiAgICAgICAgICAgIC9zZWMtKChzZ2hcXHcrKSkvaVxuICAgICAgICAgICAgXSwgW1tWRU5ET1IsICdTYW1zdW5nJ10sIE1PREVMLCBbVFlQRSwgTU9CSUxFXV0sIFtcblxuICAgICAgICAgICAgL3NpZS0oXFx3KykqL2kgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gU2llbWVuc1xuICAgICAgICAgICAgXSwgW01PREVMLCBbVkVORE9SLCAnU2llbWVucyddLCBbVFlQRSwgTU9CSUxFXV0sIFtcblxuICAgICAgICAgICAgLyhtYWVtb3xub2tpYSkuKihuOTAwfGx1bWlhXFxzXFxkKykvaSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE5va2lhXG4gICAgICAgICAgICAvKG5va2lhKVtcXHNfLV0/KFtcXHctXSspKi9pXG4gICAgICAgICAgICBdLCBbW1ZFTkRPUiwgJ05va2lhJ10sIE1PREVMLCBbVFlQRSwgTU9CSUxFXV0sIFtcblxuICAgICAgICAgICAgL2FuZHJvaWRcXHMzXFwuW1xcc1xcdzstXXsxMH0oYVxcZHszfSkvaSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEFjZXJcbiAgICAgICAgICAgIF0sIFtNT0RFTCwgW1ZFTkRPUiwgJ0FjZXInXSwgW1RZUEUsIFRBQkxFVF1dLCBbXG5cbiAgICAgICAgICAgIC9hbmRyb2lkLisoW3ZsXWtcXC0/XFxkezN9KVxccytidWlsZC9pICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gTEcgVGFibGV0XG4gICAgICAgICAgICBdLCBbTU9ERUwsIFtWRU5ET1IsICdMRyddLCBbVFlQRSwgVEFCTEVUXV0sIFtcbiAgICAgICAgICAgIC9hbmRyb2lkXFxzM1xcLltcXHNcXHc7LV17MTB9KGxnPyktKFswNmN2OV17Myw0fSkvaSAgICAgICAgICAgICAgICAgICAgIC8vIExHIFRhYmxldFxuICAgICAgICAgICAgXSwgW1tWRU5ET1IsICdMRyddLCBNT0RFTCwgW1RZUEUsIFRBQkxFVF1dLCBbXG4gICAgICAgICAgICAvKGxnKSBuZXRjYXN0XFwudHYvaSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBMRyBTbWFydFRWXG4gICAgICAgICAgICBdLCBbVkVORE9SLCBNT0RFTCwgW1RZUEUsIFNNQVJUVFZdXSwgW1xuICAgICAgICAgICAgLyhuZXh1c1xcc1s0NV0pL2ksICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gTEdcbiAgICAgICAgICAgIC9sZ1tlO1xcc1xcLy1dKyhcXHcrKSovaSxcbiAgICAgICAgICAgIC9hbmRyb2lkLitsZyhcXC0/W1xcZFxcd10rKVxccytidWlsZC9pXG4gICAgICAgICAgICBdLCBbTU9ERUwsIFtWRU5ET1IsICdMRyddLCBbVFlQRSwgTU9CSUxFXV0sIFtcblxuICAgICAgICAgICAgL2FuZHJvaWQuKyhpZGVhdGFiW2EtejAtOVxcLVxcc10rKS9pICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIExlbm92b1xuICAgICAgICAgICAgXSwgW01PREVMLCBbVkVORE9SLCAnTGVub3ZvJ10sIFtUWVBFLCBUQUJMRVRdXSwgW1xuXG4gICAgICAgICAgICAvbGludXg7LisoKGpvbGxhKSk7L2kgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEpvbGxhXG4gICAgICAgICAgICBdLCBbVkVORE9SLCBNT0RFTCwgW1RZUEUsIE1PQklMRV1dLCBbXG5cbiAgICAgICAgICAgIC8oKHBlYmJsZSkpYXBwXFwvW1xcZFxcLl0rXFxzL2kgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFBlYmJsZVxuICAgICAgICAgICAgXSwgW1ZFTkRPUiwgTU9ERUwsIFtUWVBFLCBXRUFSQUJMRV1dLCBbXG5cbiAgICAgICAgICAgIC9hbmRyb2lkLis7XFxzKG9wcG8pXFxzPyhbXFx3XFxzXSspXFxzYnVpbGQvaSAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBPUFBPXG4gICAgICAgICAgICBdLCBbVkVORE9SLCBNT0RFTCwgW1RZUEUsIE1PQklMRV1dLCBbXG5cbiAgICAgICAgICAgIC9jcmtleS9pICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gR29vZ2xlIENocm9tZWNhc3RcbiAgICAgICAgICAgIF0sIFtbTU9ERUwsICdDaHJvbWVjYXN0J10sIFtWRU5ET1IsICdHb29nbGUnXV0sIFtcblxuICAgICAgICAgICAgL2FuZHJvaWQuKztcXHMoZ2xhc3MpXFxzXFxkL2kgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBHb29nbGUgR2xhc3NcbiAgICAgICAgICAgIF0sIFtNT0RFTCwgW1ZFTkRPUiwgJ0dvb2dsZSddLCBbVFlQRSwgV0VBUkFCTEVdXSwgW1xuXG4gICAgICAgICAgICAvYW5kcm9pZC4rO1xccyhwaXhlbCBjKVxccy9pICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gR29vZ2xlIFBpeGVsIENcbiAgICAgICAgICAgIF0sIFtNT0RFTCwgW1ZFTkRPUiwgJ0dvb2dsZSddLCBbVFlQRSwgVEFCTEVUXV0sIFtcblxuICAgICAgICAgICAgL2FuZHJvaWQuKztcXHMocGl4ZWwgeGx8cGl4ZWwpXFxzL2kgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEdvb2dsZSBQaXhlbFxuICAgICAgICAgICAgXSwgW01PREVMLCBbVkVORE9SLCAnR29vZ2xlJ10sIFtUWVBFLCBNT0JJTEVdXSwgW1xuXG4gICAgICAgICAgICAvYW5kcm9pZC4rKFxcdyspXFxzK2J1aWxkXFwvaG1cXDEvaSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBYaWFvbWkgSG9uZ21pICdudW1lcmljJyBtb2RlbHNcbiAgICAgICAgICAgIC9hbmRyb2lkLisoaG1bXFxzXFwtX10qbm90ZT9bXFxzX10qKD86XFxkXFx3KT8pXFxzK2J1aWxkL2ksICAgICAgICAgICAgICAgLy8gWGlhb21pIEhvbmdtaVxuICAgICAgICAgICAgL2FuZHJvaWQuKyhtaVtcXHNcXC1fXSooPzpvbmV8b25lW1xcc19dcGx1c3xub3RlIGx0ZSk/W1xcc19dKig/OlxcZFxcdyk/KVxccytidWlsZC9pICAgIC8vIFhpYW9taSBNaVxuICAgICAgICAgICAgXSwgW1tNT0RFTCwgL18vZywgJyAnXSwgW1ZFTkRPUiwgJ1hpYW9taSddLCBbVFlQRSwgTU9CSUxFXV0sIFtcblxuICAgICAgICAgICAgL2FuZHJvaWQuKztcXHMobVsxLTVdXFxzbm90ZSlcXHNidWlsZC9pICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBNZWl6dSBUYWJsZXRcbiAgICAgICAgICAgIF0sIFtNT0RFTCwgW1ZFTkRPUiwgJ01laXp1J10sIFtUWVBFLCBUQUJMRVRdXSwgW1xuXG4gICAgICAgICAgICAvYW5kcm9pZC4rYTAwMCgxKVxccytidWlsZC9pICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBPbmVQbHVzXG4gICAgICAgICAgICBdLCBbTU9ERUwsIFtWRU5ET1IsICdPbmVQbHVzJ10sIFtUWVBFLCBNT0JJTEVdXSwgW1xuXG4gICAgICAgICAgICAvYW5kcm9pZC4rWztcXC9dXFxzKihSQ1RbXFxkXFx3XSspXFxzK2J1aWxkL2kgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gUkNBIFRhYmxldHNcbiAgICAgICAgICAgIF0sIFtNT0RFTCwgW1ZFTkRPUiwgJ1JDQSddLCBbVFlQRSwgVEFCTEVUXV0sIFtcblxuICAgICAgICAgICAgL2FuZHJvaWQuK1s7XFwvXVxccyooVmVudWVbXFxkXFxzXSopXFxzK2J1aWxkL2kgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIERlbGwgVmVudWUgVGFibGV0c1xuICAgICAgICAgICAgXSwgW01PREVMLCBbVkVORE9SLCAnRGVsbCddLCBbVFlQRSwgVEFCTEVUXV0sIFtcblxuICAgICAgICAgICAgL2FuZHJvaWQuK1s7XFwvXVxccyooUVtUfE1dW1xcZFxcd10rKVxccytidWlsZC9pICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFZlcml6b24gVGFibGV0XG4gICAgICAgICAgICBdLCBbTU9ERUwsIFtWRU5ET1IsICdWZXJpem9uJ10sIFtUWVBFLCBUQUJMRVRdXSwgW1xuXG4gICAgICAgICAgICAvYW5kcm9pZC4rWztcXC9dXFxzKyhCYXJuZXNbJlxcc10rTm9ibGVcXHMrfEJOW1JUXSkoVj8uKilcXHMrYnVpbGQvaSAgICAgLy8gQmFybmVzICYgTm9ibGUgVGFibGV0XG4gICAgICAgICAgICBdLCBbW1ZFTkRPUiwgJ0Jhcm5lcyAmIE5vYmxlJ10sIE1PREVMLCBbVFlQRSwgVEFCTEVUXV0sIFtcblxuICAgICAgICAgICAgL2FuZHJvaWQuK1s7XFwvXVxccysoVE1cXGR7M30uKlxcYilcXHMrYnVpbGQvaSAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEJhcm5lcyAmIE5vYmxlIFRhYmxldFxuICAgICAgICAgICAgXSwgW01PREVMLCBbVkVORE9SLCAnTnVWaXNpb24nXSwgW1RZUEUsIFRBQkxFVF1dLCBbXG5cbiAgICAgICAgICAgIC9hbmRyb2lkLitbO1xcL11cXHMqKHp0ZSk/Lisoa1xcZHsyfSlcXHMrYnVpbGQvaSAgICAgICAgICAgICAgICAgICAgICAgIC8vIFpURSBLIFNlcmllcyBUYWJsZXRcbiAgICAgICAgICAgIF0sIFtbVkVORE9SLCAnWlRFJ10sIE1PREVMLCBbVFlQRSwgVEFCTEVUXV0sIFtcblxuICAgICAgICAgICAgL2FuZHJvaWQuK1s7XFwvXVxccyooZ2VuXFxkezN9KVxccytidWlsZC4qNDloL2kgICAgICAgICAgICAgICAgICAgICAgICAgLy8gU3dpc3MgR0VOIE1vYmlsZVxuICAgICAgICAgICAgXSwgW01PREVMLCBbVkVORE9SLCAnU3dpc3MnXSwgW1RZUEUsIE1PQklMRV1dLCBbXG5cbiAgICAgICAgICAgIC9hbmRyb2lkLitbO1xcL11cXHMqKHp1clxcZHszfSlcXHMrYnVpbGQvaSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFN3aXNzIFpVUiBUYWJsZXRcbiAgICAgICAgICAgIF0sIFtNT0RFTCwgW1ZFTkRPUiwgJ1N3aXNzJ10sIFtUWVBFLCBUQUJMRVRdXSwgW1xuXG4gICAgICAgICAgICAvYW5kcm9pZC4rWztcXC9dXFxzKigoWmVraSk/VEIuKlxcYilcXHMrYnVpbGQvaSAgICAgICAgICAgICAgICAgICAgICAgICAvLyBaZWtpIFRhYmxldHNcbiAgICAgICAgICAgIF0sIFtNT0RFTCwgW1ZFTkRPUiwgJ1pla2knXSwgW1RZUEUsIFRBQkxFVF1dLCBbXG5cbiAgICAgICAgICAgIC8oYW5kcm9pZCkuK1s7XFwvXVxccysoW1lSXVxcZHsyfXg/LiopXFxzK2J1aWxkL2ksXG4gICAgICAgICAgICAvYW5kcm9pZC4rWztcXC9dXFxzKyhEcmFnb25bXFwtXFxzXStUb3VjaFxccyt8RFQpKC4rKVxccytidWlsZC9pICAgICAgICAgIC8vIERyYWdvbiBUb3VjaCBUYWJsZXRcbiAgICAgICAgICAgIF0sIFtbVkVORE9SLCAnRHJhZ29uIFRvdWNoJ10sIE1PREVMLCBbVFlQRSwgVEFCTEVUXV0sIFtcblxuICAgICAgICAgICAgL2FuZHJvaWQuK1s7XFwvXVxccyooTlMtPy4rKVxccytidWlsZC9pICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBJbnNpZ25pYSBUYWJsZXRzXG4gICAgICAgICAgICBdLCBbTU9ERUwsIFtWRU5ET1IsICdJbnNpZ25pYSddLCBbVFlQRSwgVEFCTEVUXV0sIFtcblxuICAgICAgICAgICAgL2FuZHJvaWQuK1s7XFwvXVxccyooKE5YfE5leHQpLT8uKylcXHMrYnVpbGQvaSAgICAgICAgICAgICAgICAgICAgICAgICAvLyBOZXh0Qm9vayBUYWJsZXRzXG4gICAgICAgICAgICBdLCBbTU9ERUwsIFtWRU5ET1IsICdOZXh0Qm9vayddLCBbVFlQRSwgVEFCTEVUXV0sIFtcblxuICAgICAgICAgICAgL2FuZHJvaWQuK1s7XFwvXVxccyooWHRyZW1lXFxfPyk/KFYoMVswNDVdfDJbMDE1XXwzMHw0MHw2MHw3WzA1XXw5MCkpXFxzK2J1aWxkL2lcbiAgICAgICAgICAgIF0sIFtbVkVORE9SLCAnVm9pY2UnXSwgTU9ERUwsIFtUWVBFLCBNT0JJTEVdXSwgWyAgICAgICAgICAgICAgICAgICAgLy8gVm9pY2UgWHRyZW1lIFBob25lc1xuXG4gICAgICAgICAgICAvYW5kcm9pZC4rWztcXC9dXFxzKihMVlRFTFxcLT8pPyhWMVsxMl0pXFxzK2J1aWxkL2kgICAgICAgICAgICAgICAgICAgICAvLyBMdlRlbCBQaG9uZXNcbiAgICAgICAgICAgIF0sIFtbVkVORE9SLCAnTHZUZWwnXSwgTU9ERUwsIFtUWVBFLCBNT0JJTEVdXSwgW1xuXG4gICAgICAgICAgICAvYW5kcm9pZC4rWztcXC9dXFxzKihWKDEwME1EfDcwME5BfDcwMTF8OTE3RykuKlxcYilcXHMrYnVpbGQvaSAgICAgICAgICAvLyBFbnZpemVuIFRhYmxldHNcbiAgICAgICAgICAgIF0sIFtNT0RFTCwgW1ZFTkRPUiwgJ0Vudml6ZW4nXSwgW1RZUEUsIFRBQkxFVF1dLCBbXG5cbiAgICAgICAgICAgIC9hbmRyb2lkLitbO1xcL11cXHMqKExlW1xcc1xcLV0rUGFuKVtcXHNcXC1dKyguKlxcYilcXHMrYnVpbGQvaSAgICAgICAgICAgICAvLyBMZSBQYW4gVGFibGV0c1xuICAgICAgICAgICAgXSwgW1ZFTkRPUiwgTU9ERUwsIFtUWVBFLCBUQUJMRVRdXSwgW1xuXG4gICAgICAgICAgICAvYW5kcm9pZC4rWztcXC9dXFxzKihUcmlvW1xcc1xcLV0qLiopXFxzK2J1aWxkL2kgICAgICAgICAgICAgICAgICAgICAgICAgLy8gTWFjaFNwZWVkIFRhYmxldHNcbiAgICAgICAgICAgIF0sIFtNT0RFTCwgW1ZFTkRPUiwgJ01hY2hTcGVlZCddLCBbVFlQRSwgVEFCTEVUXV0sIFtcblxuICAgICAgICAgICAgL2FuZHJvaWQuK1s7XFwvXVxccyooVHJpbml0eSlbXFwtXFxzXSooVFxcZHszfSlcXHMrYnVpbGQvaSAgICAgICAgICAgICAgICAvLyBUcmluaXR5IFRhYmxldHNcbiAgICAgICAgICAgIF0sIFtWRU5ET1IsIE1PREVMLCBbVFlQRSwgVEFCTEVUXV0sIFtcblxuICAgICAgICAgICAgL2FuZHJvaWQuK1s7XFwvXVxccypUVV8oMTQ5MSlcXHMrYnVpbGQvaSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBSb3RvciBUYWJsZXRzXG4gICAgICAgICAgICBdLCBbTU9ERUwsIFtWRU5ET1IsICdSb3RvciddLCBbVFlQRSwgVEFCTEVUXV0sIFtcblxuICAgICAgICAgICAgL2FuZHJvaWQuKyhLUyguKykpXFxzK2J1aWxkL2kgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQW1hem9uIEtpbmRsZSBUYWJsZXRzXG4gICAgICAgICAgICBdLCBbTU9ERUwsIFtWRU5ET1IsICdBbWF6b24nXSwgW1RZUEUsIFRBQkxFVF1dLCBbXG5cbiAgICAgICAgICAgIC9hbmRyb2lkLisoR2lnYXNldClbXFxzXFwtXSsoUS4rKVxccytidWlsZC9pICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gR2lnYXNldCBUYWJsZXRzXG4gICAgICAgICAgICBdLCBbVkVORE9SLCBNT0RFTCwgW1RZUEUsIFRBQkxFVF1dLCBbXG5cbiAgICAgICAgICAgIC9cXHModGFibGV0fHRhYilbO1xcL10vaSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBVbmlkZW50aWZpYWJsZSBUYWJsZXRcbiAgICAgICAgICAgIC9cXHMobW9iaWxlKSg/Ols7XFwvXXxcXHNzYWZhcmkpL2kgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gVW5pZGVudGlmaWFibGUgTW9iaWxlXG4gICAgICAgICAgICBdLCBbW1RZUEUsIHV0aWwubG93ZXJpemVdLCBWRU5ET1IsIE1PREVMXSwgW1xuXG4gICAgICAgICAgICAvKGFuZHJvaWQuKylbO1xcL10uK2J1aWxkL2kgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBHZW5lcmljIEFuZHJvaWQgRGV2aWNlXG4gICAgICAgICAgICBdLCBbTU9ERUwsIFtWRU5ET1IsICdHZW5lcmljJ11dXG5cblxuICAgICAgICAvKi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG4gICAgICAgICAgICAvLyBUT0RPOiBtb3ZlIHRvIHN0cmluZyBtYXBcbiAgICAgICAgICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblxuICAgICAgICAgICAgLyhDNjYwMykvaSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBTb255IFhwZXJpYSBaIEM2NjAzXG4gICAgICAgICAgICBdLCBbW01PREVMLCAnWHBlcmlhIFogQzY2MDMnXSwgW1ZFTkRPUiwgJ1NvbnknXSwgW1RZUEUsIE1PQklMRV1dLCBbXG4gICAgICAgICAgICAvKEM2OTAzKS9pICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFNvbnkgWHBlcmlhIFogMVxuICAgICAgICAgICAgXSwgW1tNT0RFTCwgJ1hwZXJpYSBaIDEnXSwgW1ZFTkRPUiwgJ1NvbnknXSwgW1RZUEUsIE1PQklMRV1dLCBbXG5cbiAgICAgICAgICAgIC8oU00tRzkwMFtGfEhdKS9pICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gU2Ftc3VuZyBHYWxheHkgUzVcbiAgICAgICAgICAgIF0sIFtbTU9ERUwsICdHYWxheHkgUzUnXSwgW1ZFTkRPUiwgJ1NhbXN1bmcnXSwgW1RZUEUsIE1PQklMRV1dLCBbXG4gICAgICAgICAgICAvKFNNLUc3MTAyKS9pICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFNhbXN1bmcgR2FsYXh5IEdyYW5kIDJcbiAgICAgICAgICAgIF0sIFtbTU9ERUwsICdHYWxheHkgR3JhbmQgMiddLCBbVkVORE9SLCAnU2Ftc3VuZyddLCBbVFlQRSwgTU9CSUxFXV0sIFtcbiAgICAgICAgICAgIC8oU00tRzUzMEgpL2kgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gU2Ftc3VuZyBHYWxheHkgR3JhbmQgUHJpbWVcbiAgICAgICAgICAgIF0sIFtbTU9ERUwsICdHYWxheHkgR3JhbmQgUHJpbWUnXSwgW1ZFTkRPUiwgJ1NhbXN1bmcnXSwgW1RZUEUsIE1PQklMRV1dLCBbXG4gICAgICAgICAgICAvKFNNLUczMTNIWikvaSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFNhbXN1bmcgR2FsYXh5IFZcbiAgICAgICAgICAgIF0sIFtbTU9ERUwsICdHYWxheHkgViddLCBbVkVORE9SLCAnU2Ftc3VuZyddLCBbVFlQRSwgTU9CSUxFXV0sIFtcbiAgICAgICAgICAgIC8oU00tVDgwNSkvaSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gU2Ftc3VuZyBHYWxheHkgVGFiIFMgMTAuNVxuICAgICAgICAgICAgXSwgW1tNT0RFTCwgJ0dhbGF4eSBUYWIgUyAxMC41J10sIFtWRU5ET1IsICdTYW1zdW5nJ10sIFtUWVBFLCBUQUJMRVRdXSwgW1xuICAgICAgICAgICAgLyhTTS1HODAwRikvaSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBTYW1zdW5nIEdhbGF4eSBTNSBNaW5pXG4gICAgICAgICAgICBdLCBbW01PREVMLCAnR2FsYXh5IFM1IE1pbmknXSwgW1ZFTkRPUiwgJ1NhbXN1bmcnXSwgW1RZUEUsIE1PQklMRV1dLCBbXG4gICAgICAgICAgICAvKFNNLVQzMTEpL2kgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFNhbXN1bmcgR2FsYXh5IFRhYiAzIDguMFxuICAgICAgICAgICAgXSwgW1tNT0RFTCwgJ0dhbGF4eSBUYWIgMyA4LjAnXSwgW1ZFTkRPUiwgJ1NhbXN1bmcnXSwgW1RZUEUsIFRBQkxFVF1dLCBbXG5cbiAgICAgICAgICAgIC8oVDNDKS9pICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQWR2YW4gVmFuZHJvaWQgVDNDXG4gICAgICAgICAgICBdLCBbTU9ERUwsIFtWRU5ET1IsICdBZHZhbiddLCBbVFlQRSwgVEFCTEVUXV0sIFtcbiAgICAgICAgICAgIC8oQURWQU4gVDFKXFwrKS9pICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEFkdmFuIFZhbmRyb2lkIFQxSitcbiAgICAgICAgICAgIF0sIFtbTU9ERUwsICdWYW5kcm9pZCBUMUorJ10sIFtWRU5ET1IsICdBZHZhbiddLCBbVFlQRSwgVEFCTEVUXV0sIFtcbiAgICAgICAgICAgIC8oQURWQU4gUzRBKS9pICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQWR2YW4gVmFuZHJvaWQgUzRBXG4gICAgICAgICAgICBdLCBbW01PREVMLCAnVmFuZHJvaWQgUzRBJ10sIFtWRU5ET1IsICdBZHZhbiddLCBbVFlQRSwgTU9CSUxFXV0sIFtcblxuICAgICAgICAgICAgLyhWOTcyTSkvaSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBaVEUgVjk3Mk1cbiAgICAgICAgICAgIF0sIFtNT0RFTCwgW1ZFTkRPUiwgJ1pURSddLCBbVFlQRSwgTU9CSUxFXV0sIFtcblxuICAgICAgICAgICAgLyhpLW1vYmlsZSlcXHMoSVFcXHNbXFxkXFwuXSspL2kgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gaS1tb2JpbGUgSVFcbiAgICAgICAgICAgIF0sIFtWRU5ET1IsIE1PREVMLCBbVFlQRSwgTU9CSUxFXV0sIFtcbiAgICAgICAgICAgIC8oSVE2LjMpL2kgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gaS1tb2JpbGUgSVEgSVEgNi4zXG4gICAgICAgICAgICBdLCBbW01PREVMLCAnSVEgNi4zJ10sIFtWRU5ET1IsICdpLW1vYmlsZSddLCBbVFlQRSwgTU9CSUxFXV0sIFtcbiAgICAgICAgICAgIC8oaS1tb2JpbGUpXFxzKGktc3R5bGVcXHNbXFxkXFwuXSspL2kgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGktbW9iaWxlIGktU1RZTEVcbiAgICAgICAgICAgIF0sIFtWRU5ET1IsIE1PREVMLCBbVFlQRSwgTU9CSUxFXV0sIFtcbiAgICAgICAgICAgIC8oaS1TVFlMRTIuMSkvaSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gaS1tb2JpbGUgaS1TVFlMRSAyLjFcbiAgICAgICAgICAgIF0sIFtbTU9ERUwsICdpLVNUWUxFIDIuMSddLCBbVkVORE9SLCAnaS1tb2JpbGUnXSwgW1RZUEUsIE1PQklMRV1dLCBbXG5cbiAgICAgICAgICAgIC8obW9iaWlzdGFyIHRvdWNoIExBSSA1MTIpL2kgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gbW9iaWlzdGFyIHRvdWNoIExBSSA1MTJcbiAgICAgICAgICAgIF0sIFtbTU9ERUwsICdUb3VjaCBMQUkgNTEyJ10sIFtWRU5ET1IsICdtb2JpaXN0YXInXSwgW1RZUEUsIE1PQklMRV1dLCBbXG5cbiAgICAgICAgICAgIC8vLy8vLy8vLy8vLy9cbiAgICAgICAgICAgIC8vIEVORCBUT0RPXG4gICAgICAgICAgICAvLy8vLy8vLy8vLyovXG5cbiAgICAgICAgXSxcblxuICAgICAgICBlbmdpbmUgOiBbW1xuXG4gICAgICAgICAgICAvd2luZG93cy4rXFxzZWRnZVxcLyhbXFx3XFwuXSspL2kgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBFZGdlSFRNTFxuICAgICAgICAgICAgXSwgW1ZFUlNJT04sIFtOQU1FLCAnRWRnZUhUTUwnXV0sIFtcblxuICAgICAgICAgICAgLyhwcmVzdG8pXFwvKFtcXHdcXC5dKykvaSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBQcmVzdG9cbiAgICAgICAgICAgIC8od2Via2l0fHRyaWRlbnR8bmV0ZnJvbnR8bmV0c3VyZnxhbWF5YXxseW54fHczbSlcXC8oW1xcd1xcLl0rKS9pLCAgICAgLy8gV2ViS2l0L1RyaWRlbnQvTmV0RnJvbnQvTmV0U3VyZi9BbWF5YS9MeW54L3czbVxuICAgICAgICAgICAgLyhraHRtbHx0YXNtYW58bGlua3MpW1xcL1xcc11cXCg/KFtcXHdcXC5dKykvaSwgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEtIVE1ML1Rhc21hbi9MaW5rc1xuICAgICAgICAgICAgLyhpY2FiKVtcXC9cXHNdKFsyM11cXC5bXFxkXFwuXSspL2kgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGlDYWJcbiAgICAgICAgICAgIF0sIFtOQU1FLCBWRVJTSU9OXSwgW1xuXG4gICAgICAgICAgICAvcnZcXDooW1xcd1xcLl0rKS4qKGdlY2tvKS9pICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEdlY2tvXG4gICAgICAgICAgICBdLCBbVkVSU0lPTiwgTkFNRV1cbiAgICAgICAgXSxcblxuICAgICAgICBvcyA6IFtbXG5cbiAgICAgICAgICAgIC8vIFdpbmRvd3MgYmFzZWRcbiAgICAgICAgICAgIC9taWNyb3NvZnRcXHMod2luZG93cylcXHModmlzdGF8eHApL2kgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBXaW5kb3dzIChpVHVuZXMpXG4gICAgICAgICAgICBdLCBbTkFNRSwgVkVSU0lPTl0sIFtcbiAgICAgICAgICAgIC8od2luZG93cylcXHNudFxcczZcXC4yO1xccyhhcm0pL2ksICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFdpbmRvd3MgUlRcbiAgICAgICAgICAgIC8od2luZG93c1xcc3Bob25lKD86XFxzb3MpKilbXFxzXFwvXT8oW1xcZFxcLlxcc10rXFx3KSovaSwgICAgICAgICAgICAgICAgICAvLyBXaW5kb3dzIFBob25lXG4gICAgICAgICAgICAvKHdpbmRvd3NcXHNtb2JpbGV8d2luZG93cylbXFxzXFwvXT8oW250Y2VcXGRcXC5cXHNdK1xcdykvaVxuICAgICAgICAgICAgXSwgW05BTUUsIFtWRVJTSU9OLCBtYXBwZXIuc3RyLCBtYXBzLm9zLndpbmRvd3MudmVyc2lvbl1dLCBbXG4gICAgICAgICAgICAvKHdpbig/PTN8OXxuKXx3aW5cXHM5eFxccykoW250XFxkXFwuXSspL2lcbiAgICAgICAgICAgIF0sIFtbTkFNRSwgJ1dpbmRvd3MnXSwgW1ZFUlNJT04sIG1hcHBlci5zdHIsIG1hcHMub3Mud2luZG93cy52ZXJzaW9uXV0sIFtcblxuICAgICAgICAgICAgLy8gTW9iaWxlL0VtYmVkZGVkIE9TXG4gICAgICAgICAgICAvXFwoKGJiKSgxMCk7L2kgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBCbGFja0JlcnJ5IDEwXG4gICAgICAgICAgICBdLCBbW05BTUUsICdCbGFja0JlcnJ5J10sIFZFUlNJT05dLCBbXG4gICAgICAgICAgICAvKGJsYWNrYmVycnkpXFx3KlxcLz8oW1xcd1xcLl0rKSovaSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBCbGFja2JlcnJ5XG4gICAgICAgICAgICAvKHRpemVuKVtcXC9cXHNdKFtcXHdcXC5dKykvaSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBUaXplblxuICAgICAgICAgICAgLyhhbmRyb2lkfHdlYm9zfHBhbG1cXHNvc3xxbnh8YmFkYXxyaW1cXHN0YWJsZXRcXHNvc3xtZWVnb3xjb250aWtpKVtcXC9cXHMtXT8oW1xcd1xcLl0rKSovaSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQW5kcm9pZC9XZWJPUy9QYWxtL1FOWC9CYWRhL1JJTS9NZWVHby9Db250aWtpXG4gICAgICAgICAgICAvbGludXg7Lisoc2FpbGZpc2gpOy9pICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFNhaWxmaXNoIE9TXG4gICAgICAgICAgICBdLCBbTkFNRSwgVkVSU0lPTl0sIFtcbiAgICAgICAgICAgIC8oc3ltYmlhblxccz9vc3xzeW1ib3N8czYwKD89OykpW1xcL1xccy1dPyhbXFx3XFwuXSspKi9pICAgICAgICAgICAgICAgICAvLyBTeW1iaWFuXG4gICAgICAgICAgICBdLCBbW05BTUUsICdTeW1iaWFuJ10sIFZFUlNJT05dLCBbXG4gICAgICAgICAgICAvXFwoKHNlcmllczQwKTsvaSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBTZXJpZXMgNDBcbiAgICAgICAgICAgIF0sIFtOQU1FXSwgW1xuICAgICAgICAgICAgL21vemlsbGEuK1xcKG1vYmlsZTsuK2dlY2tvLitmaXJlZm94L2kgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gRmlyZWZveCBPU1xuICAgICAgICAgICAgXSwgW1tOQU1FLCAnRmlyZWZveCBPUyddLCBWRVJTSU9OXSwgW1xuXG4gICAgICAgICAgICAvLyBDb25zb2xlXG4gICAgICAgICAgICAvKG5pbnRlbmRvfHBsYXlzdGF0aW9uKVxccyhbd2lkczM0cG9ydGFibGV2dV0rKS9pLCAgICAgICAgICAgICAgICAgICAvLyBOaW50ZW5kby9QbGF5c3RhdGlvblxuXG4gICAgICAgICAgICAvLyBHTlUvTGludXggYmFzZWRcbiAgICAgICAgICAgIC8obWludClbXFwvXFxzXFwoXT8oXFx3KykqL2ksICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE1pbnRcbiAgICAgICAgICAgIC8obWFnZWlhfHZlY3RvcmxpbnV4KVs7XFxzXS9pLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE1hZ2VpYS9WZWN0b3JMaW51eFxuICAgICAgICAgICAgLyhqb2xpfFtreGxuXT91YnVudHV8ZGViaWFufFtvcGVuXSpzdXNlfGdlbnRvb3woPz1cXHMpYXJjaHxzbGFja3dhcmV8ZmVkb3JhfG1hbmRyaXZhfGNlbnRvc3xwY2xpbnV4b3N8cmVkaGF0fHplbndhbGt8bGlucHVzKVtcXC9cXHMtXT8oPyFjaHJvbSkoW1xcd1xcLi1dKykqL2ksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEpvbGkvVWJ1bnR1L0RlYmlhbi9TVVNFL0dlbnRvby9BcmNoL1NsYWNrd2FyZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBGZWRvcmEvTWFuZHJpdmEvQ2VudE9TL1BDTGludXhPUy9SZWRIYXQvWmVud2Fsay9MaW5wdXNcbiAgICAgICAgICAgIC8oaHVyZHxsaW51eClcXHM/KFtcXHdcXC5dKykqL2ksICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gSHVyZC9MaW51eFxuICAgICAgICAgICAgLyhnbnUpXFxzPyhbXFx3XFwuXSspKi9pICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBHTlVcbiAgICAgICAgICAgIF0sIFtOQU1FLCBWRVJTSU9OXSwgW1xuXG4gICAgICAgICAgICAvKGNyb3MpXFxzW1xcd10rXFxzKFtcXHdcXC5dK1xcdykvaSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIENocm9taXVtIE9TXG4gICAgICAgICAgICBdLCBbW05BTUUsICdDaHJvbWl1bSBPUyddLCBWRVJTSU9OXSxbXG5cbiAgICAgICAgICAgIC8vIFNvbGFyaXNcbiAgICAgICAgICAgIC8oc3Vub3MpXFxzPyhbXFx3XFwuXStcXGQpKi9pICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFNvbGFyaXNcbiAgICAgICAgICAgIF0sIFtbTkFNRSwgJ1NvbGFyaXMnXSwgVkVSU0lPTl0sIFtcblxuICAgICAgICAgICAgLy8gQlNEIGJhc2VkXG4gICAgICAgICAgICAvXFxzKFtmcmVudG9wYy1dezAsNH1ic2R8ZHJhZ29uZmx5KVxccz8oW1xcd1xcLl0rKSovaSAgICAgICAgICAgICAgICAgICAvLyBGcmVlQlNEL05ldEJTRC9PcGVuQlNEL1BDLUJTRC9EcmFnb25GbHlcbiAgICAgICAgICAgIF0sIFtOQU1FLCBWRVJTSU9OXSxbXG5cbiAgICAgICAgICAgIC8oaGFpa3UpXFxzKFxcdyspL2kgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEhhaWt1XG4gICAgICAgICAgICBdLCBbTkFNRSwgVkVSU0lPTl0sW1xuXG4gICAgICAgICAgICAvY2ZuZXR3b3JrXFwvLitkYXJ3aW4vaSxcbiAgICAgICAgICAgIC9pcFtob25lYWRdKyg/Oi4qb3NcXHMoW1xcd10rKSpcXHNsaWtlXFxzbWFjfDtcXHNvcGVyYSkvaSAgICAgICAgICAgICAgICAvLyBpT1NcbiAgICAgICAgICAgIF0sIFtbVkVSU0lPTiwgL18vZywgJy4nXSwgW05BTUUsICdpT1MnXV0sIFtcblxuICAgICAgICAgICAgLyhtYWNcXHNvc1xcc3gpXFxzPyhbXFx3XFxzXFwuXStcXHcpKi9pLFxuICAgICAgICAgICAgLyhtYWNpbnRvc2h8bWFjKD89X3Bvd2VycGMpXFxzKS9pICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gTWFjIE9TXG4gICAgICAgICAgICBdLCBbW05BTUUsICdNYWMgT1MnXSwgW1ZFUlNJT04sIC9fL2csICcuJ11dLCBbXG5cbiAgICAgICAgICAgIC8vIE90aGVyXG4gICAgICAgICAgICAvKCg/Om9wZW4pP3NvbGFyaXMpW1xcL1xccy1dPyhbXFx3XFwuXSspKi9pLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBTb2xhcmlzXG4gICAgICAgICAgICAvKGFpeClcXHMoKFxcZCkoPz1cXC58XFwpfFxccylbXFx3XFwuXSopKi9pLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBBSVhcbiAgICAgICAgICAgIC8ocGxhblxcczl8bWluaXh8YmVvc3xvc1xcLzJ8YW1pZ2Fvc3xtb3JwaG9zfHJpc2NcXHNvc3xvcGVudm1zKS9pLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBQbGFuOS9NaW5peC9CZU9TL09TMi9BbWlnYU9TL01vcnBoT1MvUklTQ09TL09wZW5WTVNcbiAgICAgICAgICAgIC8odW5peClcXHM/KFtcXHdcXC5dKykqL2kgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gVU5JWFxuICAgICAgICAgICAgXSwgW05BTUUsIFZFUlNJT05dXG4gICAgICAgIF1cbiAgICB9O1xuXG5cbiAgICAvLy8vLy8vLy8vLy8vLy8vL1xuICAgIC8vIENvbnN0cnVjdG9yXG4gICAgLy8vLy8vLy8vLy8vLy8vL1xuXG4gICAgdmFyIEJyb3dzZXIgPSBmdW5jdGlvbiAobmFtZSwgdmVyc2lvbikge1xuICAgICAgICB0aGlzW05BTUVdID0gbmFtZTtcbiAgICAgICAgdGhpc1tWRVJTSU9OXSA9IHZlcnNpb247XG4gICAgfTtcbiAgICB2YXIgQ1BVID0gZnVuY3Rpb24gKGFyY2gpIHtcbiAgICAgICAgdGhpc1tBUkNISVRFQ1RVUkVdID0gYXJjaDtcbiAgICB9O1xuICAgIHZhciBEZXZpY2UgPSBmdW5jdGlvbiAodmVuZG9yLCBtb2RlbCwgdHlwZSkge1xuICAgICAgICB0aGlzW1ZFTkRPUl0gPSB2ZW5kb3I7XG4gICAgICAgIHRoaXNbTU9ERUxdID0gbW9kZWw7XG4gICAgICAgIHRoaXNbVFlQRV0gPSB0eXBlO1xuICAgIH07XG4gICAgdmFyIEVuZ2luZSA9IEJyb3dzZXI7XG4gICAgdmFyIE9TID0gQnJvd3NlcjtcblxuICAgIHZhciBVQVBhcnNlciA9IGZ1bmN0aW9uICh1YXN0cmluZywgZXh0ZW5zaW9ucykge1xuXG4gICAgICAgIGlmICh0eXBlb2YgdWFzdHJpbmcgPT09ICdvYmplY3QnKSB7XG4gICAgICAgICAgICBleHRlbnNpb25zID0gdWFzdHJpbmc7XG4gICAgICAgICAgICB1YXN0cmluZyA9IHVuZGVmaW5lZDtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghKHRoaXMgaW5zdGFuY2VvZiBVQVBhcnNlcikpIHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgVUFQYXJzZXIodWFzdHJpbmcsIGV4dGVuc2lvbnMpLmdldFJlc3VsdCgpO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIHVhID0gdWFzdHJpbmcgfHwgKCh3aW5kb3cgJiYgd2luZG93Lm5hdmlnYXRvciAmJiB3aW5kb3cubmF2aWdhdG9yLnVzZXJBZ2VudCkgPyB3aW5kb3cubmF2aWdhdG9yLnVzZXJBZ2VudCA6IEVNUFRZKTtcbiAgICAgICAgdmFyIHJneG1hcCA9IGV4dGVuc2lvbnMgPyB1dGlsLmV4dGVuZChyZWdleGVzLCBleHRlbnNpb25zKSA6IHJlZ2V4ZXM7XG4gICAgICAgIHZhciBicm93c2VyID0gbmV3IEJyb3dzZXIoKTtcbiAgICAgICAgdmFyIGNwdSA9IG5ldyBDUFUoKTtcbiAgICAgICAgdmFyIGRldmljZSA9IG5ldyBEZXZpY2UoKTtcbiAgICAgICAgdmFyIGVuZ2luZSA9IG5ldyBFbmdpbmUoKTtcbiAgICAgICAgdmFyIG9zID0gbmV3IE9TKCk7XG5cbiAgICAgICAgdGhpcy5nZXRCcm93c2VyID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgbWFwcGVyLnJneC5jYWxsKGJyb3dzZXIsIHVhLCByZ3htYXAuYnJvd3Nlcik7XG4gICAgICAgICAgICBicm93c2VyLm1ham9yID0gdXRpbC5tYWpvcihicm93c2VyLnZlcnNpb24pOyAvLyBkZXByZWNhdGVkXG4gICAgICAgICAgICByZXR1cm4gYnJvd3NlcjtcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5nZXRDUFUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBtYXBwZXIucmd4LmNhbGwoY3B1LCB1YSwgcmd4bWFwLmNwdSk7XG4gICAgICAgICAgICByZXR1cm4gY3B1O1xuICAgICAgICB9O1xuICAgICAgICB0aGlzLmdldERldmljZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIG1hcHBlci5yZ3guY2FsbChkZXZpY2UsIHVhLCByZ3htYXAuZGV2aWNlKTtcbiAgICAgICAgICAgIHJldHVybiBkZXZpY2U7XG4gICAgICAgIH07XG4gICAgICAgIHRoaXMuZ2V0RW5naW5lID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgbWFwcGVyLnJneC5jYWxsKGVuZ2luZSwgdWEsIHJneG1hcC5lbmdpbmUpO1xuICAgICAgICAgICAgcmV0dXJuIGVuZ2luZTtcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5nZXRPUyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIG1hcHBlci5yZ3guY2FsbChvcywgdWEsIHJneG1hcC5vcyk7XG4gICAgICAgICAgICByZXR1cm4gb3M7XG4gICAgICAgIH07XG4gICAgICAgIHRoaXMuZ2V0UmVzdWx0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICB1YSAgICAgIDogdGhpcy5nZXRVQSgpLFxuICAgICAgICAgICAgICAgIGJyb3dzZXIgOiB0aGlzLmdldEJyb3dzZXIoKSxcbiAgICAgICAgICAgICAgICBlbmdpbmUgIDogdGhpcy5nZXRFbmdpbmUoKSxcbiAgICAgICAgICAgICAgICBvcyAgICAgIDogdGhpcy5nZXRPUygpLFxuICAgICAgICAgICAgICAgIGRldmljZSAgOiB0aGlzLmdldERldmljZSgpLFxuICAgICAgICAgICAgICAgIGNwdSAgICAgOiB0aGlzLmdldENQVSgpXG4gICAgICAgICAgICB9O1xuICAgICAgICB9O1xuICAgICAgICB0aGlzLmdldFVBID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmV0dXJuIHVhO1xuICAgICAgICB9O1xuICAgICAgICB0aGlzLnNldFVBID0gZnVuY3Rpb24gKHVhc3RyaW5nKSB7XG4gICAgICAgICAgICB1YSA9IHVhc3RyaW5nO1xuICAgICAgICAgICAgYnJvd3NlciA9IG5ldyBCcm93c2VyKCk7XG4gICAgICAgICAgICBjcHUgPSBuZXcgQ1BVKCk7XG4gICAgICAgICAgICBkZXZpY2UgPSBuZXcgRGV2aWNlKCk7XG4gICAgICAgICAgICBlbmdpbmUgPSBuZXcgRW5naW5lKCk7XG4gICAgICAgICAgICBvcyA9IG5ldyBPUygpO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cbiAgICBVQVBhcnNlci5WRVJTSU9OID0gTElCVkVSU0lPTjtcbiAgICBVQVBhcnNlci5CUk9XU0VSID0ge1xuICAgICAgICBOQU1FICAgIDogTkFNRSxcbiAgICAgICAgTUFKT1IgICA6IE1BSk9SLCAvLyBkZXByZWNhdGVkXG4gICAgICAgIFZFUlNJT04gOiBWRVJTSU9OXG4gICAgfTtcbiAgICBVQVBhcnNlci5DUFUgPSB7XG4gICAgICAgIEFSQ0hJVEVDVFVSRSA6IEFSQ0hJVEVDVFVSRVxuICAgIH07XG4gICAgVUFQYXJzZXIuREVWSUNFID0ge1xuICAgICAgICBNT0RFTCAgIDogTU9ERUwsXG4gICAgICAgIFZFTkRPUiAgOiBWRU5ET1IsXG4gICAgICAgIFRZUEUgICAgOiBUWVBFLFxuICAgICAgICBDT05TT0xFIDogQ09OU09MRSxcbiAgICAgICAgTU9CSUxFICA6IE1PQklMRSxcbiAgICAgICAgU01BUlRUViA6IFNNQVJUVFYsXG4gICAgICAgIFRBQkxFVCAgOiBUQUJMRVQsXG4gICAgICAgIFdFQVJBQkxFOiBXRUFSQUJMRSxcbiAgICAgICAgRU1CRURERUQ6IEVNQkVEREVEXG4gICAgfTtcbiAgICBVQVBhcnNlci5FTkdJTkUgPSB7XG4gICAgICAgIE5BTUUgICAgOiBOQU1FLFxuICAgICAgICBWRVJTSU9OIDogVkVSU0lPTlxuICAgIH07XG4gICAgVUFQYXJzZXIuT1MgPSB7XG4gICAgICAgIE5BTUUgICAgOiBOQU1FLFxuICAgICAgICBWRVJTSU9OIDogVkVSU0lPTlxuICAgIH07XG4gICAgLy9VQVBhcnNlci5VdGlscyA9IHV0aWw7XG5cbiAgICAvLy8vLy8vLy8vL1xuICAgIC8vIEV4cG9ydFxuICAgIC8vLy8vLy8vLy9cblxuXG4gICAgLy8gY2hlY2sganMgZW52aXJvbm1lbnRcbiAgICBpZiAodHlwZW9mKGV4cG9ydHMpICE9PSBVTkRFRl9UWVBFKSB7XG4gICAgICAgIC8vIG5vZGVqcyBlbnZcbiAgICAgICAgaWYgKHR5cGVvZiBtb2R1bGUgIT09IFVOREVGX1RZUEUgJiYgbW9kdWxlLmV4cG9ydHMpIHtcbiAgICAgICAgICAgIGV4cG9ydHMgPSBtb2R1bGUuZXhwb3J0cyA9IFVBUGFyc2VyO1xuICAgICAgICB9XG4gICAgICAgIGV4cG9ydHMuVUFQYXJzZXIgPSBVQVBhcnNlcjtcbiAgICB9IGVsc2Uge1xuICAgICAgICAvLyByZXF1aXJlanMgZW52IChvcHRpb25hbClcbiAgICAgICAgaWYgKHR5cGVvZihkZWZpbmUpID09PSBGVU5DX1RZUEUgJiYgZGVmaW5lLmFtZCkge1xuICAgICAgICAgICAgZGVmaW5lKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gVUFQYXJzZXI7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIGlmICh3aW5kb3cpIHtcbiAgICAgICAgICAgIC8vIGJyb3dzZXIgZW52XG4gICAgICAgICAgICB3aW5kb3cuVUFQYXJzZXIgPSBVQVBhcnNlcjtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8vIGpRdWVyeS9aZXB0byBzcGVjaWZpYyAob3B0aW9uYWwpXG4gICAgLy8gTm90ZTpcbiAgICAvLyAgIEluIEFNRCBlbnYgdGhlIGdsb2JhbCBzY29wZSBzaG91bGQgYmUga2VwdCBjbGVhbiwgYnV0IGpRdWVyeSBpcyBhbiBleGNlcHRpb24uXG4gICAgLy8gICBqUXVlcnkgYWx3YXlzIGV4cG9ydHMgdG8gZ2xvYmFsIHNjb3BlLCB1bmxlc3MgalF1ZXJ5Lm5vQ29uZmxpY3QodHJ1ZSkgaXMgdXNlZCxcbiAgICAvLyAgIGFuZCB3ZSBzaG91bGQgY2F0Y2ggdGhhdC5cbiAgICB2YXIgJCA9IHdpbmRvdyAmJiAod2luZG93LmpRdWVyeSB8fCB3aW5kb3cuWmVwdG8pO1xuICAgIGlmICh0eXBlb2YgJCAhPT0gVU5ERUZfVFlQRSkge1xuICAgICAgICB2YXIgcGFyc2VyID0gbmV3IFVBUGFyc2VyKCk7XG4gICAgICAgICQudWEgPSBwYXJzZXIuZ2V0UmVzdWx0KCk7XG4gICAgICAgICQudWEuZ2V0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmV0dXJuIHBhcnNlci5nZXRVQSgpO1xuICAgICAgICB9O1xuICAgICAgICAkLnVhLnNldCA9IGZ1bmN0aW9uICh1YXN0cmluZykge1xuICAgICAgICAgICAgcGFyc2VyLnNldFVBKHVhc3RyaW5nKTtcbiAgICAgICAgICAgIHZhciByZXN1bHQgPSBwYXJzZXIuZ2V0UmVzdWx0KCk7XG4gICAgICAgICAgICBmb3IgKHZhciBwcm9wIGluIHJlc3VsdCkge1xuICAgICAgICAgICAgICAgICQudWFbcHJvcF0gPSByZXN1bHRbcHJvcF07XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgfVxuXG59KSh0eXBlb2Ygd2luZG93ID09PSAnb2JqZWN0JyA/IHdpbmRvdyA6IHRoaXMpO1xuIiwiXG52YXIgcm5nO1xuXG52YXIgY3J5cHRvID0gZ2xvYmFsLmNyeXB0byB8fCBnbG9iYWwubXNDcnlwdG87IC8vIGZvciBJRSAxMVxuaWYgKGNyeXB0byAmJiBjcnlwdG8uZ2V0UmFuZG9tVmFsdWVzKSB7XG4gIC8vIFdIQVRXRyBjcnlwdG8tYmFzZWQgUk5HIC0gaHR0cDovL3dpa2kud2hhdHdnLm9yZy93aWtpL0NyeXB0b1xuICAvLyBNb2RlcmF0ZWx5IGZhc3QsIGhpZ2ggcXVhbGl0eVxuICB2YXIgX3JuZHM4ID0gbmV3IFVpbnQ4QXJyYXkoMTYpO1xuICBybmcgPSBmdW5jdGlvbiB3aGF0d2dSTkcoKSB7XG4gICAgY3J5cHRvLmdldFJhbmRvbVZhbHVlcyhfcm5kczgpO1xuICAgIHJldHVybiBfcm5kczg7XG4gIH07XG59XG5cbmlmICghcm5nKSB7XG4gIC8vIE1hdGgucmFuZG9tKCktYmFzZWQgKFJORylcbiAgLy9cbiAgLy8gSWYgYWxsIGVsc2UgZmFpbHMsIHVzZSBNYXRoLnJhbmRvbSgpLiAgSXQncyBmYXN0LCBidXQgaXMgb2YgdW5zcGVjaWZpZWRcbiAgLy8gcXVhbGl0eS5cbiAgdmFyICBfcm5kcyA9IG5ldyBBcnJheSgxNik7XG4gIHJuZyA9IGZ1bmN0aW9uKCkge1xuICAgIGZvciAodmFyIGkgPSAwLCByOyBpIDwgMTY7IGkrKykge1xuICAgICAgaWYgKChpICYgMHgwMykgPT09IDApIHIgPSBNYXRoLnJhbmRvbSgpICogMHgxMDAwMDAwMDA7XG4gICAgICBfcm5kc1tpXSA9IHIgPj4+ICgoaSAmIDB4MDMpIDw8IDMpICYgMHhmZjtcbiAgICB9XG5cbiAgICByZXR1cm4gX3JuZHM7XG4gIH07XG59XG5cbm1vZHVsZS5leHBvcnRzID0gcm5nO1xuXG4iLCIvLyAgICAgdXVpZC5qc1xuLy9cbi8vICAgICBDb3B5cmlnaHQgKGMpIDIwMTAtMjAxMiBSb2JlcnQgS2llZmZlclxuLy8gICAgIE1JVCBMaWNlbnNlIC0gaHR0cDovL29wZW5zb3VyY2Uub3JnL2xpY2Vuc2VzL21pdC1saWNlbnNlLnBocFxuXG4vLyBVbmlxdWUgSUQgY3JlYXRpb24gcmVxdWlyZXMgYSBoaWdoIHF1YWxpdHkgcmFuZG9tICMgZ2VuZXJhdG9yLiAgV2UgZmVhdHVyZVxuLy8gZGV0ZWN0IHRvIGRldGVybWluZSB0aGUgYmVzdCBSTkcgc291cmNlLCBub3JtYWxpemluZyB0byBhIGZ1bmN0aW9uIHRoYXRcbi8vIHJldHVybnMgMTI4LWJpdHMgb2YgcmFuZG9tbmVzcywgc2luY2UgdGhhdCdzIHdoYXQncyB1c3VhbGx5IHJlcXVpcmVkXG52YXIgX3JuZyA9IHJlcXVpcmUoJy4vcm5nJyk7XG5cbi8vIE1hcHMgZm9yIG51bWJlciA8LT4gaGV4IHN0cmluZyBjb252ZXJzaW9uXG52YXIgX2J5dGVUb0hleCA9IFtdO1xudmFyIF9oZXhUb0J5dGUgPSB7fTtcbmZvciAodmFyIGkgPSAwOyBpIDwgMjU2OyBpKyspIHtcbiAgX2J5dGVUb0hleFtpXSA9IChpICsgMHgxMDApLnRvU3RyaW5nKDE2KS5zdWJzdHIoMSk7XG4gIF9oZXhUb0J5dGVbX2J5dGVUb0hleFtpXV0gPSBpO1xufVxuXG4vLyAqKmBwYXJzZSgpYCAtIFBhcnNlIGEgVVVJRCBpbnRvIGl0J3MgY29tcG9uZW50IGJ5dGVzKipcbmZ1bmN0aW9uIHBhcnNlKHMsIGJ1Ziwgb2Zmc2V0KSB7XG4gIHZhciBpID0gKGJ1ZiAmJiBvZmZzZXQpIHx8IDAsIGlpID0gMDtcblxuICBidWYgPSBidWYgfHwgW107XG4gIHMudG9Mb3dlckNhc2UoKS5yZXBsYWNlKC9bMC05YS1mXXsyfS9nLCBmdW5jdGlvbihvY3QpIHtcbiAgICBpZiAoaWkgPCAxNikgeyAvLyBEb24ndCBvdmVyZmxvdyFcbiAgICAgIGJ1ZltpICsgaWkrK10gPSBfaGV4VG9CeXRlW29jdF07XG4gICAgfVxuICB9KTtcblxuICAvLyBaZXJvIG91dCByZW1haW5pbmcgYnl0ZXMgaWYgc3RyaW5nIHdhcyBzaG9ydFxuICB3aGlsZSAoaWkgPCAxNikge1xuICAgIGJ1ZltpICsgaWkrK10gPSAwO1xuICB9XG5cbiAgcmV0dXJuIGJ1Zjtcbn1cblxuLy8gKipgdW5wYXJzZSgpYCAtIENvbnZlcnQgVVVJRCBieXRlIGFycmF5IChhbGEgcGFyc2UoKSkgaW50byBhIHN0cmluZyoqXG5mdW5jdGlvbiB1bnBhcnNlKGJ1Ziwgb2Zmc2V0KSB7XG4gIHZhciBpID0gb2Zmc2V0IHx8IDAsIGJ0aCA9IF9ieXRlVG9IZXg7XG4gIHJldHVybiAgYnRoW2J1ZltpKytdXSArIGJ0aFtidWZbaSsrXV0gK1xuICAgICAgICAgIGJ0aFtidWZbaSsrXV0gKyBidGhbYnVmW2krK11dICsgJy0nICtcbiAgICAgICAgICBidGhbYnVmW2krK11dICsgYnRoW2J1ZltpKytdXSArICctJyArXG4gICAgICAgICAgYnRoW2J1ZltpKytdXSArIGJ0aFtidWZbaSsrXV0gKyAnLScgK1xuICAgICAgICAgIGJ0aFtidWZbaSsrXV0gKyBidGhbYnVmW2krK11dICsgJy0nICtcbiAgICAgICAgICBidGhbYnVmW2krK11dICsgYnRoW2J1ZltpKytdXSArXG4gICAgICAgICAgYnRoW2J1ZltpKytdXSArIGJ0aFtidWZbaSsrXV0gK1xuICAgICAgICAgIGJ0aFtidWZbaSsrXV0gKyBidGhbYnVmW2krK11dO1xufVxuXG4vLyAqKmB2MSgpYCAtIEdlbmVyYXRlIHRpbWUtYmFzZWQgVVVJRCoqXG4vL1xuLy8gSW5zcGlyZWQgYnkgaHR0cHM6Ly9naXRodWIuY29tL0xpb3NLL1VVSUQuanNcbi8vIGFuZCBodHRwOi8vZG9jcy5weXRob24ub3JnL2xpYnJhcnkvdXVpZC5odG1sXG5cbi8vIHJhbmRvbSAjJ3Mgd2UgbmVlZCB0byBpbml0IG5vZGUgYW5kIGNsb2Nrc2VxXG52YXIgX3NlZWRCeXRlcyA9IF9ybmcoKTtcblxuLy8gUGVyIDQuNSwgY3JlYXRlIGFuZCA0OC1iaXQgbm9kZSBpZCwgKDQ3IHJhbmRvbSBiaXRzICsgbXVsdGljYXN0IGJpdCA9IDEpXG52YXIgX25vZGVJZCA9IFtcbiAgX3NlZWRCeXRlc1swXSB8IDB4MDEsXG4gIF9zZWVkQnl0ZXNbMV0sIF9zZWVkQnl0ZXNbMl0sIF9zZWVkQnl0ZXNbM10sIF9zZWVkQnl0ZXNbNF0sIF9zZWVkQnl0ZXNbNV1cbl07XG5cbi8vIFBlciA0LjIuMiwgcmFuZG9taXplICgxNCBiaXQpIGNsb2Nrc2VxXG52YXIgX2Nsb2Nrc2VxID0gKF9zZWVkQnl0ZXNbNl0gPDwgOCB8IF9zZWVkQnl0ZXNbN10pICYgMHgzZmZmO1xuXG4vLyBQcmV2aW91cyB1dWlkIGNyZWF0aW9uIHRpbWVcbnZhciBfbGFzdE1TZWNzID0gMCwgX2xhc3ROU2VjcyA9IDA7XG5cbi8vIFNlZSBodHRwczovL2dpdGh1Yi5jb20vYnJvb2ZhL25vZGUtdXVpZCBmb3IgQVBJIGRldGFpbHNcbmZ1bmN0aW9uIHYxKG9wdGlvbnMsIGJ1Ziwgb2Zmc2V0KSB7XG4gIHZhciBpID0gYnVmICYmIG9mZnNldCB8fCAwO1xuICB2YXIgYiA9IGJ1ZiB8fCBbXTtcblxuICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcblxuICB2YXIgY2xvY2tzZXEgPSBvcHRpb25zLmNsb2Nrc2VxICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLmNsb2Nrc2VxIDogX2Nsb2Nrc2VxO1xuXG4gIC8vIFVVSUQgdGltZXN0YW1wcyBhcmUgMTAwIG5hbm8tc2Vjb25kIHVuaXRzIHNpbmNlIHRoZSBHcmVnb3JpYW4gZXBvY2gsXG4gIC8vICgxNTgyLTEwLTE1IDAwOjAwKS4gIEpTTnVtYmVycyBhcmVuJ3QgcHJlY2lzZSBlbm91Z2ggZm9yIHRoaXMsIHNvXG4gIC8vIHRpbWUgaXMgaGFuZGxlZCBpbnRlcm5hbGx5IGFzICdtc2VjcycgKGludGVnZXIgbWlsbGlzZWNvbmRzKSBhbmQgJ25zZWNzJ1xuICAvLyAoMTAwLW5hbm9zZWNvbmRzIG9mZnNldCBmcm9tIG1zZWNzKSBzaW5jZSB1bml4IGVwb2NoLCAxOTcwLTAxLTAxIDAwOjAwLlxuICB2YXIgbXNlY3MgPSBvcHRpb25zLm1zZWNzICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLm1zZWNzIDogbmV3IERhdGUoKS5nZXRUaW1lKCk7XG5cbiAgLy8gUGVyIDQuMi4xLjIsIHVzZSBjb3VudCBvZiB1dWlkJ3MgZ2VuZXJhdGVkIGR1cmluZyB0aGUgY3VycmVudCBjbG9ja1xuICAvLyBjeWNsZSB0byBzaW11bGF0ZSBoaWdoZXIgcmVzb2x1dGlvbiBjbG9ja1xuICB2YXIgbnNlY3MgPSBvcHRpb25zLm5zZWNzICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLm5zZWNzIDogX2xhc3ROU2VjcyArIDE7XG5cbiAgLy8gVGltZSBzaW5jZSBsYXN0IHV1aWQgY3JlYXRpb24gKGluIG1zZWNzKVxuICB2YXIgZHQgPSAobXNlY3MgLSBfbGFzdE1TZWNzKSArIChuc2VjcyAtIF9sYXN0TlNlY3MpLzEwMDAwO1xuXG4gIC8vIFBlciA0LjIuMS4yLCBCdW1wIGNsb2Nrc2VxIG9uIGNsb2NrIHJlZ3Jlc3Npb25cbiAgaWYgKGR0IDwgMCAmJiBvcHRpb25zLmNsb2Nrc2VxID09PSB1bmRlZmluZWQpIHtcbiAgICBjbG9ja3NlcSA9IGNsb2Nrc2VxICsgMSAmIDB4M2ZmZjtcbiAgfVxuXG4gIC8vIFJlc2V0IG5zZWNzIGlmIGNsb2NrIHJlZ3Jlc3NlcyAobmV3IGNsb2Nrc2VxKSBvciB3ZSd2ZSBtb3ZlZCBvbnRvIGEgbmV3XG4gIC8vIHRpbWUgaW50ZXJ2YWxcbiAgaWYgKChkdCA8IDAgfHwgbXNlY3MgPiBfbGFzdE1TZWNzKSAmJiBvcHRpb25zLm5zZWNzID09PSB1bmRlZmluZWQpIHtcbiAgICBuc2VjcyA9IDA7XG4gIH1cblxuICAvLyBQZXIgNC4yLjEuMiBUaHJvdyBlcnJvciBpZiB0b28gbWFueSB1dWlkcyBhcmUgcmVxdWVzdGVkXG4gIGlmIChuc2VjcyA+PSAxMDAwMCkge1xuICAgIHRocm93IG5ldyBFcnJvcigndXVpZC52MSgpOiBDYW5cXCd0IGNyZWF0ZSBtb3JlIHRoYW4gMTBNIHV1aWRzL3NlYycpO1xuICB9XG5cbiAgX2xhc3RNU2VjcyA9IG1zZWNzO1xuICBfbGFzdE5TZWNzID0gbnNlY3M7XG4gIF9jbG9ja3NlcSA9IGNsb2Nrc2VxO1xuXG4gIC8vIFBlciA0LjEuNCAtIENvbnZlcnQgZnJvbSB1bml4IGVwb2NoIHRvIEdyZWdvcmlhbiBlcG9jaFxuICBtc2VjcyArPSAxMjIxOTI5MjgwMDAwMDtcblxuICAvLyBgdGltZV9sb3dgXG4gIHZhciB0bCA9ICgobXNlY3MgJiAweGZmZmZmZmYpICogMTAwMDAgKyBuc2VjcykgJSAweDEwMDAwMDAwMDtcbiAgYltpKytdID0gdGwgPj4+IDI0ICYgMHhmZjtcbiAgYltpKytdID0gdGwgPj4+IDE2ICYgMHhmZjtcbiAgYltpKytdID0gdGwgPj4+IDggJiAweGZmO1xuICBiW2krK10gPSB0bCAmIDB4ZmY7XG5cbiAgLy8gYHRpbWVfbWlkYFxuICB2YXIgdG1oID0gKG1zZWNzIC8gMHgxMDAwMDAwMDAgKiAxMDAwMCkgJiAweGZmZmZmZmY7XG4gIGJbaSsrXSA9IHRtaCA+Pj4gOCAmIDB4ZmY7XG4gIGJbaSsrXSA9IHRtaCAmIDB4ZmY7XG5cbiAgLy8gYHRpbWVfaGlnaF9hbmRfdmVyc2lvbmBcbiAgYltpKytdID0gdG1oID4+PiAyNCAmIDB4ZiB8IDB4MTA7IC8vIGluY2x1ZGUgdmVyc2lvblxuICBiW2krK10gPSB0bWggPj4+IDE2ICYgMHhmZjtcblxuICAvLyBgY2xvY2tfc2VxX2hpX2FuZF9yZXNlcnZlZGAgKFBlciA0LjIuMiAtIGluY2x1ZGUgdmFyaWFudClcbiAgYltpKytdID0gY2xvY2tzZXEgPj4+IDggfCAweDgwO1xuXG4gIC8vIGBjbG9ja19zZXFfbG93YFxuICBiW2krK10gPSBjbG9ja3NlcSAmIDB4ZmY7XG5cbiAgLy8gYG5vZGVgXG4gIHZhciBub2RlID0gb3B0aW9ucy5ub2RlIHx8IF9ub2RlSWQ7XG4gIGZvciAodmFyIG4gPSAwOyBuIDwgNjsgbisrKSB7XG4gICAgYltpICsgbl0gPSBub2RlW25dO1xuICB9XG5cbiAgcmV0dXJuIGJ1ZiA/IGJ1ZiA6IHVucGFyc2UoYik7XG59XG5cbi8vICoqYHY0KClgIC0gR2VuZXJhdGUgcmFuZG9tIFVVSUQqKlxuXG4vLyBTZWUgaHR0cHM6Ly9naXRodWIuY29tL2Jyb29mYS9ub2RlLXV1aWQgZm9yIEFQSSBkZXRhaWxzXG5mdW5jdGlvbiB2NChvcHRpb25zLCBidWYsIG9mZnNldCkge1xuICAvLyBEZXByZWNhdGVkIC0gJ2Zvcm1hdCcgYXJndW1lbnQsIGFzIHN1cHBvcnRlZCBpbiB2MS4yXG4gIHZhciBpID0gYnVmICYmIG9mZnNldCB8fCAwO1xuXG4gIGlmICh0eXBlb2Yob3B0aW9ucykgPT0gJ3N0cmluZycpIHtcbiAgICBidWYgPSBvcHRpb25zID09ICdiaW5hcnknID8gbmV3IEFycmF5KDE2KSA6IG51bGw7XG4gICAgb3B0aW9ucyA9IG51bGw7XG4gIH1cbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG5cbiAgdmFyIHJuZHMgPSBvcHRpb25zLnJhbmRvbSB8fCAob3B0aW9ucy5ybmcgfHwgX3JuZykoKTtcblxuICAvLyBQZXIgNC40LCBzZXQgYml0cyBmb3IgdmVyc2lvbiBhbmQgYGNsb2NrX3NlcV9oaV9hbmRfcmVzZXJ2ZWRgXG4gIHJuZHNbNl0gPSAocm5kc1s2XSAmIDB4MGYpIHwgMHg0MDtcbiAgcm5kc1s4XSA9IChybmRzWzhdICYgMHgzZikgfCAweDgwO1xuXG4gIC8vIENvcHkgYnl0ZXMgdG8gYnVmZmVyLCBpZiBwcm92aWRlZFxuICBpZiAoYnVmKSB7XG4gICAgZm9yICh2YXIgaWkgPSAwOyBpaSA8IDE2OyBpaSsrKSB7XG4gICAgICBidWZbaSArIGlpXSA9IHJuZHNbaWldO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBidWYgfHwgdW5wYXJzZShybmRzKTtcbn1cblxuLy8gRXhwb3J0IHB1YmxpYyBBUElcbnZhciB1dWlkID0gdjQ7XG51dWlkLnYxID0gdjE7XG51dWlkLnY0ID0gdjQ7XG51dWlkLnBhcnNlID0gcGFyc2U7XG51dWlkLnVucGFyc2UgPSB1bnBhcnNlO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHV1aWQ7XG4iLCIvKlxuICogIENvcHlyaWdodCAoYykgMjAxNiBUaGUgV2ViUlRDIHByb2plY3QgYXV0aG9ycy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqXG4gKiAgVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZVxuICogIHRoYXQgY2FuIGJlIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgaW4gdGhlIHJvb3Qgb2YgdGhlIHNvdXJjZVxuICogIHRyZWUuXG4gKi9cbiAvKiBlc2xpbnQtZW52IG5vZGUgKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG52YXIgYWRhcHRlckZhY3RvcnkgPSByZXF1aXJlKCcuL2FkYXB0ZXJfZmFjdG9yeS5qcycpO1xubW9kdWxlLmV4cG9ydHMgPSBhZGFwdGVyRmFjdG9yeSh7d2luZG93OiBnbG9iYWwud2luZG93fSk7XG4iLCIvKlxuICogIENvcHlyaWdodCAoYykgMjAxNiBUaGUgV2ViUlRDIHByb2plY3QgYXV0aG9ycy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqXG4gKiAgVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZVxuICogIHRoYXQgY2FuIGJlIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgaW4gdGhlIHJvb3Qgb2YgdGhlIHNvdXJjZVxuICogIHRyZWUuXG4gKi9cbiAvKiBlc2xpbnQtZW52IG5vZGUgKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG52YXIgdXRpbHMgPSByZXF1aXJlKCcuL3V0aWxzJyk7XG4vLyBTaGltbWluZyBzdGFydHMgaGVyZS5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oZGVwZW5kZW5jaWVzLCBvcHRzKSB7XG4gIHZhciB3aW5kb3cgPSBkZXBlbmRlbmNpZXMgJiYgZGVwZW5kZW5jaWVzLndpbmRvdztcblxuICB2YXIgb3B0aW9ucyA9IHtcbiAgICBzaGltQ2hyb21lOiB0cnVlLFxuICAgIHNoaW1GaXJlZm94OiB0cnVlLFxuICAgIHNoaW1FZGdlOiB0cnVlLFxuICAgIHNoaW1TYWZhcmk6IHRydWUsXG4gIH07XG5cbiAgZm9yICh2YXIga2V5IGluIG9wdHMpIHtcbiAgICBpZiAoaGFzT3duUHJvcGVydHkuY2FsbChvcHRzLCBrZXkpKSB7XG4gICAgICBvcHRpb25zW2tleV0gPSBvcHRzW2tleV07XG4gICAgfVxuICB9XG5cbiAgLy8gVXRpbHMuXG4gIHZhciBsb2dnaW5nID0gdXRpbHMubG9nO1xuICB2YXIgYnJvd3NlckRldGFpbHMgPSB1dGlscy5kZXRlY3RCcm93c2VyKHdpbmRvdyk7XG5cbiAgLy8gRXhwb3J0IHRvIHRoZSBhZGFwdGVyIGdsb2JhbCBvYmplY3QgdmlzaWJsZSBpbiB0aGUgYnJvd3Nlci5cbiAgdmFyIGFkYXB0ZXIgPSB7XG4gICAgYnJvd3NlckRldGFpbHM6IGJyb3dzZXJEZXRhaWxzLFxuICAgIGV4dHJhY3RWZXJzaW9uOiB1dGlscy5leHRyYWN0VmVyc2lvbixcbiAgICBkaXNhYmxlTG9nOiB1dGlscy5kaXNhYmxlTG9nLFxuICAgIGRpc2FibGVXYXJuaW5nczogdXRpbHMuZGlzYWJsZVdhcm5pbmdzXG4gIH07XG5cbiAgLy8gVW5jb21tZW50IHRoZSBsaW5lIGJlbG93IGlmIHlvdSB3YW50IGxvZ2dpbmcgdG8gb2NjdXIsIGluY2x1ZGluZyBsb2dnaW5nXG4gIC8vIGZvciB0aGUgc3dpdGNoIHN0YXRlbWVudCBiZWxvdy4gQ2FuIGFsc28gYmUgdHVybmVkIG9uIGluIHRoZSBicm93c2VyIHZpYVxuICAvLyBhZGFwdGVyLmRpc2FibGVMb2coZmFsc2UpLCBidXQgdGhlbiBsb2dnaW5nIGZyb20gdGhlIHN3aXRjaCBzdGF0ZW1lbnQgYmVsb3dcbiAgLy8gd2lsbCBub3QgYXBwZWFyLlxuICAvLyByZXF1aXJlKCcuL3V0aWxzJykuZGlzYWJsZUxvZyhmYWxzZSk7XG5cbiAgLy8gQnJvd3NlciBzaGltcy5cbiAgdmFyIGNocm9tZVNoaW0gPSByZXF1aXJlKCcuL2Nocm9tZS9jaHJvbWVfc2hpbScpIHx8IG51bGw7XG4gIHZhciBlZGdlU2hpbSA9IHJlcXVpcmUoJy4vZWRnZS9lZGdlX3NoaW0nKSB8fCBudWxsO1xuICB2YXIgZmlyZWZveFNoaW0gPSByZXF1aXJlKCcuL2ZpcmVmb3gvZmlyZWZveF9zaGltJykgfHwgbnVsbDtcbiAgdmFyIHNhZmFyaVNoaW0gPSByZXF1aXJlKCcuL3NhZmFyaS9zYWZhcmlfc2hpbScpIHx8IG51bGw7XG4gIHZhciBjb21tb25TaGltID0gcmVxdWlyZSgnLi9jb21tb25fc2hpbScpIHx8IG51bGw7XG5cbiAgLy8gU2hpbSBicm93c2VyIGlmIGZvdW5kLlxuICBzd2l0Y2ggKGJyb3dzZXJEZXRhaWxzLmJyb3dzZXIpIHtcbiAgICBjYXNlICdjaHJvbWUnOlxuICAgICAgaWYgKCFjaHJvbWVTaGltIHx8ICFjaHJvbWVTaGltLnNoaW1QZWVyQ29ubmVjdGlvbiB8fFxuICAgICAgICAgICFvcHRpb25zLnNoaW1DaHJvbWUpIHtcbiAgICAgICAgbG9nZ2luZygnQ2hyb21lIHNoaW0gaXMgbm90IGluY2x1ZGVkIGluIHRoaXMgYWRhcHRlciByZWxlYXNlLicpO1xuICAgICAgICByZXR1cm4gYWRhcHRlcjtcbiAgICAgIH1cbiAgICAgIGxvZ2dpbmcoJ2FkYXB0ZXIuanMgc2hpbW1pbmcgY2hyb21lLicpO1xuICAgICAgLy8gRXhwb3J0IHRvIHRoZSBhZGFwdGVyIGdsb2JhbCBvYmplY3QgdmlzaWJsZSBpbiB0aGUgYnJvd3Nlci5cbiAgICAgIGFkYXB0ZXIuYnJvd3NlclNoaW0gPSBjaHJvbWVTaGltO1xuICAgICAgY29tbW9uU2hpbS5zaGltQ3JlYXRlT2JqZWN0VVJMKHdpbmRvdyk7XG5cbiAgICAgIGNocm9tZVNoaW0uc2hpbUdldFVzZXJNZWRpYSh3aW5kb3cpO1xuICAgICAgY2hyb21lU2hpbS5zaGltTWVkaWFTdHJlYW0od2luZG93KTtcbiAgICAgIGNocm9tZVNoaW0uc2hpbVNvdXJjZU9iamVjdCh3aW5kb3cpO1xuICAgICAgY2hyb21lU2hpbS5zaGltUGVlckNvbm5lY3Rpb24od2luZG93KTtcbiAgICAgIGNocm9tZVNoaW0uc2hpbU9uVHJhY2sod2luZG93KTtcbiAgICAgIGNocm9tZVNoaW0uc2hpbUFkZFRyYWNrUmVtb3ZlVHJhY2sod2luZG93KTtcbiAgICAgIGNocm9tZVNoaW0uc2hpbUdldFNlbmRlcnNXaXRoRHRtZih3aW5kb3cpO1xuXG4gICAgICBjb21tb25TaGltLnNoaW1SVENJY2VDYW5kaWRhdGUod2luZG93KTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ2ZpcmVmb3gnOlxuICAgICAgaWYgKCFmaXJlZm94U2hpbSB8fCAhZmlyZWZveFNoaW0uc2hpbVBlZXJDb25uZWN0aW9uIHx8XG4gICAgICAgICAgIW9wdGlvbnMuc2hpbUZpcmVmb3gpIHtcbiAgICAgICAgbG9nZ2luZygnRmlyZWZveCBzaGltIGlzIG5vdCBpbmNsdWRlZCBpbiB0aGlzIGFkYXB0ZXIgcmVsZWFzZS4nKTtcbiAgICAgICAgcmV0dXJuIGFkYXB0ZXI7XG4gICAgICB9XG4gICAgICBsb2dnaW5nKCdhZGFwdGVyLmpzIHNoaW1taW5nIGZpcmVmb3guJyk7XG4gICAgICAvLyBFeHBvcnQgdG8gdGhlIGFkYXB0ZXIgZ2xvYmFsIG9iamVjdCB2aXNpYmxlIGluIHRoZSBicm93c2VyLlxuICAgICAgYWRhcHRlci5icm93c2VyU2hpbSA9IGZpcmVmb3hTaGltO1xuICAgICAgY29tbW9uU2hpbS5zaGltQ3JlYXRlT2JqZWN0VVJMKHdpbmRvdyk7XG5cbiAgICAgIGZpcmVmb3hTaGltLnNoaW1HZXRVc2VyTWVkaWEod2luZG93KTtcbiAgICAgIGZpcmVmb3hTaGltLnNoaW1Tb3VyY2VPYmplY3Qod2luZG93KTtcbiAgICAgIGZpcmVmb3hTaGltLnNoaW1QZWVyQ29ubmVjdGlvbih3aW5kb3cpO1xuICAgICAgZmlyZWZveFNoaW0uc2hpbU9uVHJhY2sod2luZG93KTtcblxuICAgICAgY29tbW9uU2hpbS5zaGltUlRDSWNlQ2FuZGlkYXRlKHdpbmRvdyk7XG4gICAgICBicmVhaztcbiAgICBjYXNlICdlZGdlJzpcbiAgICAgIGlmICghZWRnZVNoaW0gfHwgIWVkZ2VTaGltLnNoaW1QZWVyQ29ubmVjdGlvbiB8fCAhb3B0aW9ucy5zaGltRWRnZSkge1xuICAgICAgICBsb2dnaW5nKCdNUyBlZGdlIHNoaW0gaXMgbm90IGluY2x1ZGVkIGluIHRoaXMgYWRhcHRlciByZWxlYXNlLicpO1xuICAgICAgICByZXR1cm4gYWRhcHRlcjtcbiAgICAgIH1cbiAgICAgIGxvZ2dpbmcoJ2FkYXB0ZXIuanMgc2hpbW1pbmcgZWRnZS4nKTtcbiAgICAgIC8vIEV4cG9ydCB0byB0aGUgYWRhcHRlciBnbG9iYWwgb2JqZWN0IHZpc2libGUgaW4gdGhlIGJyb3dzZXIuXG4gICAgICBhZGFwdGVyLmJyb3dzZXJTaGltID0gZWRnZVNoaW07XG4gICAgICBjb21tb25TaGltLnNoaW1DcmVhdGVPYmplY3RVUkwod2luZG93KTtcblxuICAgICAgZWRnZVNoaW0uc2hpbUdldFVzZXJNZWRpYSh3aW5kb3cpO1xuICAgICAgZWRnZVNoaW0uc2hpbVBlZXJDb25uZWN0aW9uKHdpbmRvdyk7XG4gICAgICBlZGdlU2hpbS5zaGltUmVwbGFjZVRyYWNrKHdpbmRvdyk7XG5cbiAgICAgIC8vIHRoZSBlZGdlIHNoaW0gaW1wbGVtZW50cyB0aGUgZnVsbCBSVENJY2VDYW5kaWRhdGUgb2JqZWN0LlxuICAgICAgYnJlYWs7XG4gICAgY2FzZSAnc2FmYXJpJzpcbiAgICAgIGlmICghc2FmYXJpU2hpbSB8fCAhb3B0aW9ucy5zaGltU2FmYXJpKSB7XG4gICAgICAgIGxvZ2dpbmcoJ1NhZmFyaSBzaGltIGlzIG5vdCBpbmNsdWRlZCBpbiB0aGlzIGFkYXB0ZXIgcmVsZWFzZS4nKTtcbiAgICAgICAgcmV0dXJuIGFkYXB0ZXI7XG4gICAgICB9XG4gICAgICBsb2dnaW5nKCdhZGFwdGVyLmpzIHNoaW1taW5nIHNhZmFyaS4nKTtcbiAgICAgIC8vIEV4cG9ydCB0byB0aGUgYWRhcHRlciBnbG9iYWwgb2JqZWN0IHZpc2libGUgaW4gdGhlIGJyb3dzZXIuXG4gICAgICBhZGFwdGVyLmJyb3dzZXJTaGltID0gc2FmYXJpU2hpbTtcbiAgICAgIGNvbW1vblNoaW0uc2hpbUNyZWF0ZU9iamVjdFVSTCh3aW5kb3cpO1xuXG4gICAgICBzYWZhcmlTaGltLnNoaW1SVENJY2VTZXJ2ZXJVcmxzKHdpbmRvdyk7XG4gICAgICBzYWZhcmlTaGltLnNoaW1DYWxsYmFja3NBUEkod2luZG93KTtcbiAgICAgIHNhZmFyaVNoaW0uc2hpbUxvY2FsU3RyZWFtc0FQSSh3aW5kb3cpO1xuICAgICAgc2FmYXJpU2hpbS5zaGltUmVtb3RlU3RyZWFtc0FQSSh3aW5kb3cpO1xuICAgICAgc2FmYXJpU2hpbS5zaGltVHJhY2tFdmVudFRyYW5zY2VpdmVyKHdpbmRvdyk7XG4gICAgICBzYWZhcmlTaGltLnNoaW1HZXRVc2VyTWVkaWEod2luZG93KTtcblxuICAgICAgY29tbW9uU2hpbS5zaGltUlRDSWNlQ2FuZGlkYXRlKHdpbmRvdyk7XG4gICAgICBicmVhaztcbiAgICBkZWZhdWx0OlxuICAgICAgbG9nZ2luZygnVW5zdXBwb3J0ZWQgYnJvd3NlciEnKTtcbiAgICAgIGJyZWFrO1xuICB9XG5cbiAgcmV0dXJuIGFkYXB0ZXI7XG59O1xuIiwiXG4vKlxuICogIENvcHlyaWdodCAoYykgMjAxNiBUaGUgV2ViUlRDIHByb2plY3QgYXV0aG9ycy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqXG4gKiAgVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZVxuICogIHRoYXQgY2FuIGJlIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgaW4gdGhlIHJvb3Qgb2YgdGhlIHNvdXJjZVxuICogIHRyZWUuXG4gKi9cbiAvKiBlc2xpbnQtZW52IG5vZGUgKi9cbid1c2Ugc3RyaWN0JztcbnZhciB1dGlscyA9IHJlcXVpcmUoJy4uL3V0aWxzLmpzJyk7XG52YXIgbG9nZ2luZyA9IHV0aWxzLmxvZztcblxudmFyIGNocm9tZVNoaW0gPSB7XG4gIHNoaW1NZWRpYVN0cmVhbTogZnVuY3Rpb24od2luZG93KSB7XG4gICAgd2luZG93Lk1lZGlhU3RyZWFtID0gd2luZG93Lk1lZGlhU3RyZWFtIHx8IHdpbmRvdy53ZWJraXRNZWRpYVN0cmVhbTtcbiAgfSxcblxuICBzaGltT25UcmFjazogZnVuY3Rpb24od2luZG93KSB7XG4gICAgaWYgKHR5cGVvZiB3aW5kb3cgPT09ICdvYmplY3QnICYmIHdpbmRvdy5SVENQZWVyQ29ubmVjdGlvbiAmJiAhKCdvbnRyYWNrJyBpblxuICAgICAgICB3aW5kb3cuUlRDUGVlckNvbm5lY3Rpb24ucHJvdG90eXBlKSkge1xuICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHdpbmRvdy5SVENQZWVyQ29ubmVjdGlvbi5wcm90b3R5cGUsICdvbnRyYWNrJywge1xuICAgICAgICBnZXQ6IGZ1bmN0aW9uKCkge1xuICAgICAgICAgIHJldHVybiB0aGlzLl9vbnRyYWNrO1xuICAgICAgICB9LFxuICAgICAgICBzZXQ6IGZ1bmN0aW9uKGYpIHtcbiAgICAgICAgICBpZiAodGhpcy5fb250cmFjaykge1xuICAgICAgICAgICAgdGhpcy5yZW1vdmVFdmVudExpc3RlbmVyKCd0cmFjaycsIHRoaXMuX29udHJhY2spO1xuICAgICAgICAgIH1cbiAgICAgICAgICB0aGlzLmFkZEV2ZW50TGlzdGVuZXIoJ3RyYWNrJywgdGhpcy5fb250cmFjayA9IGYpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIHZhciBvcmlnU2V0UmVtb3RlRGVzY3JpcHRpb24gPVxuICAgICAgICAgIHdpbmRvdy5SVENQZWVyQ29ubmVjdGlvbi5wcm90b3R5cGUuc2V0UmVtb3RlRGVzY3JpcHRpb247XG4gICAgICB3aW5kb3cuUlRDUGVlckNvbm5lY3Rpb24ucHJvdG90eXBlLnNldFJlbW90ZURlc2NyaXB0aW9uID0gZnVuY3Rpb24oKSB7XG4gICAgICAgIHZhciBwYyA9IHRoaXM7XG4gICAgICAgIGlmICghcGMuX29udHJhY2twb2x5KSB7XG4gICAgICAgICAgcGMuX29udHJhY2twb2x5ID0gZnVuY3Rpb24oZSkge1xuICAgICAgICAgICAgLy8gb25hZGRzdHJlYW0gZG9lcyBub3QgZmlyZSB3aGVuIGEgdHJhY2sgaXMgYWRkZWQgdG8gYW4gZXhpc3RpbmdcbiAgICAgICAgICAgIC8vIHN0cmVhbS4gQnV0IHN0cmVhbS5vbmFkZHRyYWNrIGlzIGltcGxlbWVudGVkIHNvIHdlIHVzZSB0aGF0LlxuICAgICAgICAgICAgZS5zdHJlYW0uYWRkRXZlbnRMaXN0ZW5lcignYWRkdHJhY2snLCBmdW5jdGlvbih0ZSkge1xuICAgICAgICAgICAgICB2YXIgcmVjZWl2ZXI7XG4gICAgICAgICAgICAgIGlmICh3aW5kb3cuUlRDUGVlckNvbm5lY3Rpb24ucHJvdG90eXBlLmdldFJlY2VpdmVycykge1xuICAgICAgICAgICAgICAgIHJlY2VpdmVyID0gcGMuZ2V0UmVjZWl2ZXJzKCkuZmluZChmdW5jdGlvbihyKSB7XG4gICAgICAgICAgICAgICAgICByZXR1cm4gci50cmFjayAmJiByLnRyYWNrLmlkID09PSB0ZS50cmFjay5pZDtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZWNlaXZlciA9IHt0cmFjazogdGUudHJhY2t9O1xuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgdmFyIGV2ZW50ID0gbmV3IEV2ZW50KCd0cmFjaycpO1xuICAgICAgICAgICAgICBldmVudC50cmFjayA9IHRlLnRyYWNrO1xuICAgICAgICAgICAgICBldmVudC5yZWNlaXZlciA9IHJlY2VpdmVyO1xuICAgICAgICAgICAgICBldmVudC50cmFuc2NlaXZlciA9IHtyZWNlaXZlcjogcmVjZWl2ZXJ9O1xuICAgICAgICAgICAgICBldmVudC5zdHJlYW1zID0gW2Uuc3RyZWFtXTtcbiAgICAgICAgICAgICAgcGMuZGlzcGF0Y2hFdmVudChldmVudCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGUuc3RyZWFtLmdldFRyYWNrcygpLmZvckVhY2goZnVuY3Rpb24odHJhY2spIHtcbiAgICAgICAgICAgICAgdmFyIHJlY2VpdmVyO1xuICAgICAgICAgICAgICBpZiAod2luZG93LlJUQ1BlZXJDb25uZWN0aW9uLnByb3RvdHlwZS5nZXRSZWNlaXZlcnMpIHtcbiAgICAgICAgICAgICAgICByZWNlaXZlciA9IHBjLmdldFJlY2VpdmVycygpLmZpbmQoZnVuY3Rpb24ocikge1xuICAgICAgICAgICAgICAgICAgcmV0dXJuIHIudHJhY2sgJiYgci50cmFjay5pZCA9PT0gdHJhY2suaWQ7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmVjZWl2ZXIgPSB7dHJhY2s6IHRyYWNrfTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB2YXIgZXZlbnQgPSBuZXcgRXZlbnQoJ3RyYWNrJyk7XG4gICAgICAgICAgICAgIGV2ZW50LnRyYWNrID0gdHJhY2s7XG4gICAgICAgICAgICAgIGV2ZW50LnJlY2VpdmVyID0gcmVjZWl2ZXI7XG4gICAgICAgICAgICAgIGV2ZW50LnRyYW5zY2VpdmVyID0ge3JlY2VpdmVyOiByZWNlaXZlcn07XG4gICAgICAgICAgICAgIGV2ZW50LnN0cmVhbXMgPSBbZS5zdHJlYW1dO1xuICAgICAgICAgICAgICBwYy5kaXNwYXRjaEV2ZW50KGV2ZW50KTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH07XG4gICAgICAgICAgcGMuYWRkRXZlbnRMaXN0ZW5lcignYWRkc3RyZWFtJywgcGMuX29udHJhY2twb2x5KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gb3JpZ1NldFJlbW90ZURlc2NyaXB0aW9uLmFwcGx5KHBjLCBhcmd1bWVudHMpO1xuICAgICAgfTtcbiAgICB9XG4gIH0sXG5cbiAgc2hpbUdldFNlbmRlcnNXaXRoRHRtZjogZnVuY3Rpb24od2luZG93KSB7XG4gICAgLy8gT3ZlcnJpZGVzIGFkZFRyYWNrL3JlbW92ZVRyYWNrLCBkZXBlbmRzIG9uIHNoaW1BZGRUcmFja1JlbW92ZVRyYWNrLlxuICAgIGlmICh0eXBlb2Ygd2luZG93ID09PSAnb2JqZWN0JyAmJiB3aW5kb3cuUlRDUGVlckNvbm5lY3Rpb24gJiZcbiAgICAgICAgISgnZ2V0U2VuZGVycycgaW4gd2luZG93LlJUQ1BlZXJDb25uZWN0aW9uLnByb3RvdHlwZSkgJiZcbiAgICAgICAgJ2NyZWF0ZURUTUZTZW5kZXInIGluIHdpbmRvdy5SVENQZWVyQ29ubmVjdGlvbi5wcm90b3R5cGUpIHtcbiAgICAgIHZhciBzaGltU2VuZGVyV2l0aER0bWYgPSBmdW5jdGlvbihwYywgdHJhY2spIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICB0cmFjazogdHJhY2ssXG4gICAgICAgICAgZ2V0IGR0bWYoKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5fZHRtZiA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgIGlmICh0cmFjay5raW5kID09PSAnYXVkaW8nKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fZHRtZiA9IHBjLmNyZWF0ZURUTUZTZW5kZXIodHJhY2spO1xuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuX2R0bWYgPSBudWxsO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fZHRtZjtcbiAgICAgICAgICB9LFxuICAgICAgICAgIF9wYzogcGNcbiAgICAgICAgfTtcbiAgICAgIH07XG5cbiAgICAgIC8vIGF1Z21lbnQgYWRkVHJhY2sgd2hlbiBnZXRTZW5kZXJzIGlzIG5vdCBhdmFpbGFibGUuXG4gICAgICBpZiAoIXdpbmRvdy5SVENQZWVyQ29ubmVjdGlvbi5wcm90b3R5cGUuZ2V0U2VuZGVycykge1xuICAgICAgICB3aW5kb3cuUlRDUGVlckNvbm5lY3Rpb24ucHJvdG90eXBlLmdldFNlbmRlcnMgPSBmdW5jdGlvbigpIHtcbiAgICAgICAgICB0aGlzLl9zZW5kZXJzID0gdGhpcy5fc2VuZGVycyB8fCBbXTtcbiAgICAgICAgICByZXR1cm4gdGhpcy5fc2VuZGVycy5zbGljZSgpOyAvLyByZXR1cm4gYSBjb3B5IG9mIHRoZSBpbnRlcm5hbCBzdGF0ZS5cbiAgICAgICAgfTtcbiAgICAgICAgdmFyIG9yaWdBZGRUcmFjayA9IHdpbmRvdy5SVENQZWVyQ29ubmVjdGlvbi5wcm90b3R5cGUuYWRkVHJhY2s7XG4gICAgICAgIHdpbmRvdy5SVENQZWVyQ29ubmVjdGlvbi5wcm90b3R5cGUuYWRkVHJhY2sgPSBmdW5jdGlvbih0cmFjaywgc3RyZWFtKSB7XG4gICAgICAgICAgdmFyIHBjID0gdGhpcztcbiAgICAgICAgICB2YXIgc2VuZGVyID0gb3JpZ0FkZFRyYWNrLmFwcGx5KHBjLCBhcmd1bWVudHMpO1xuICAgICAgICAgIGlmICghc2VuZGVyKSB7XG4gICAgICAgICAgICBzZW5kZXIgPSBzaGltU2VuZGVyV2l0aER0bWYocGMsIHRyYWNrKTtcbiAgICAgICAgICAgIHBjLl9zZW5kZXJzLnB1c2goc2VuZGVyKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIHNlbmRlcjtcbiAgICAgICAgfTtcblxuICAgICAgICB2YXIgb3JpZ1JlbW92ZVRyYWNrID0gd2luZG93LlJUQ1BlZXJDb25uZWN0aW9uLnByb3RvdHlwZS5yZW1vdmVUcmFjaztcbiAgICAgICAgd2luZG93LlJUQ1BlZXJDb25uZWN0aW9uLnByb3RvdHlwZS5yZW1vdmVUcmFjayA9IGZ1bmN0aW9uKHNlbmRlcikge1xuICAgICAgICAgIHZhciBwYyA9IHRoaXM7XG4gICAgICAgICAgb3JpZ1JlbW92ZVRyYWNrLmFwcGx5KHBjLCBhcmd1bWVudHMpO1xuICAgICAgICAgIHZhciBpZHggPSBwYy5fc2VuZGVycy5pbmRleE9mKHNlbmRlcik7XG4gICAgICAgICAgaWYgKGlkeCAhPT0gLTEpIHtcbiAgICAgICAgICAgIHBjLl9zZW5kZXJzLnNwbGljZShpZHgsIDEpO1xuICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICAgIHZhciBvcmlnQWRkU3RyZWFtID0gd2luZG93LlJUQ1BlZXJDb25uZWN0aW9uLnByb3RvdHlwZS5hZGRTdHJlYW07XG4gICAgICB3aW5kb3cuUlRDUGVlckNvbm5lY3Rpb24ucHJvdG90eXBlLmFkZFN0cmVhbSA9IGZ1bmN0aW9uKHN0cmVhbSkge1xuICAgICAgICB2YXIgcGMgPSB0aGlzO1xuICAgICAgICBwYy5fc2VuZGVycyA9IHBjLl9zZW5kZXJzIHx8IFtdO1xuICAgICAgICBvcmlnQWRkU3RyZWFtLmFwcGx5KHBjLCBbc3RyZWFtXSk7XG4gICAgICAgIHN0cmVhbS5nZXRUcmFja3MoKS5mb3JFYWNoKGZ1bmN0aW9uKHRyYWNrKSB7XG4gICAgICAgICAgcGMuX3NlbmRlcnMucHVzaChzaGltU2VuZGVyV2l0aER0bWYocGMsIHRyYWNrKSk7XG4gICAgICAgIH0pO1xuICAgICAgfTtcblxuICAgICAgdmFyIG9yaWdSZW1vdmVTdHJlYW0gPSB3aW5kb3cuUlRDUGVlckNvbm5lY3Rpb24ucHJvdG90eXBlLnJlbW92ZVN0cmVhbTtcbiAgICAgIHdpbmRvdy5SVENQZWVyQ29ubmVjdGlvbi5wcm90b3R5cGUucmVtb3ZlU3RyZWFtID0gZnVuY3Rpb24oc3RyZWFtKSB7XG4gICAgICAgIHZhciBwYyA9IHRoaXM7XG4gICAgICAgIHBjLl9zZW5kZXJzID0gcGMuX3NlbmRlcnMgfHwgW107XG4gICAgICAgIG9yaWdSZW1vdmVTdHJlYW0uYXBwbHkocGMsIFsocGMuX3N0cmVhbXNbc3RyZWFtLmlkXSB8fCBzdHJlYW0pXSk7XG5cbiAgICAgICAgc3RyZWFtLmdldFRyYWNrcygpLmZvckVhY2goZnVuY3Rpb24odHJhY2spIHtcbiAgICAgICAgICB2YXIgc2VuZGVyID0gcGMuX3NlbmRlcnMuZmluZChmdW5jdGlvbihzKSB7XG4gICAgICAgICAgICByZXR1cm4gcy50cmFjayA9PT0gdHJhY2s7XG4gICAgICAgICAgfSk7XG4gICAgICAgICAgaWYgKHNlbmRlcikge1xuICAgICAgICAgICAgcGMuX3NlbmRlcnMuc3BsaWNlKHBjLl9zZW5kZXJzLmluZGV4T2Yoc2VuZGVyKSwgMSk7IC8vIHJlbW92ZSBzZW5kZXJcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfTtcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiB3aW5kb3cgPT09ICdvYmplY3QnICYmIHdpbmRvdy5SVENQZWVyQ29ubmVjdGlvbiAmJlxuICAgICAgICAgICAgICAgJ2dldFNlbmRlcnMnIGluIHdpbmRvdy5SVENQZWVyQ29ubmVjdGlvbi5wcm90b3R5cGUgJiZcbiAgICAgICAgICAgICAgICdjcmVhdGVEVE1GU2VuZGVyJyBpbiB3aW5kb3cuUlRDUGVlckNvbm5lY3Rpb24ucHJvdG90eXBlICYmXG4gICAgICAgICAgICAgICB3aW5kb3cuUlRDUnRwU2VuZGVyICYmXG4gICAgICAgICAgICAgICAhKCdkdG1mJyBpbiB3aW5kb3cuUlRDUnRwU2VuZGVyLnByb3RvdHlwZSkpIHtcbiAgICAgIHZhciBvcmlnR2V0U2VuZGVycyA9IHdpbmRvdy5SVENQZWVyQ29ubmVjdGlvbi5wcm90b3R5cGUuZ2V0U2VuZGVycztcbiAgICAgIHdpbmRvdy5SVENQZWVyQ29ubmVjdGlvbi5wcm90b3R5cGUuZ2V0U2VuZGVycyA9IGZ1bmN0aW9uKCkge1xuICAgICAgICB2YXIgcGMgPSB0aGlzO1xuICAgICAgICB2YXIgc2VuZGVycyA9IG9yaWdHZXRTZW5kZXJzLmFwcGx5KHBjLCBbXSk7XG4gICAgICAgIHNlbmRlcnMuZm9yRWFjaChmdW5jdGlvbihzZW5kZXIpIHtcbiAgICAgICAgICBzZW5kZXIuX3BjID0gcGM7XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gc2VuZGVycztcbiAgICAgIH07XG5cbiAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh3aW5kb3cuUlRDUnRwU2VuZGVyLnByb3RvdHlwZSwgJ2R0bWYnLCB7XG4gICAgICAgIGdldDogZnVuY3Rpb24oKSB7XG4gICAgICAgICAgaWYgKHRoaXMuX2R0bWYgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgaWYgKHRoaXMudHJhY2sua2luZCA9PT0gJ2F1ZGlvJykge1xuICAgICAgICAgICAgICB0aGlzLl9kdG1mID0gdGhpcy5fcGMuY3JlYXRlRFRNRlNlbmRlcih0aGlzLnRyYWNrKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIHRoaXMuX2R0bWYgPSBudWxsO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gdGhpcy5fZHRtZjtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuICB9LFxuXG4gIHNoaW1Tb3VyY2VPYmplY3Q6IGZ1bmN0aW9uKHdpbmRvdykge1xuICAgIHZhciBVUkwgPSB3aW5kb3cgJiYgd2luZG93LlVSTDtcblxuICAgIGlmICh0eXBlb2Ygd2luZG93ID09PSAnb2JqZWN0Jykge1xuICAgICAgaWYgKHdpbmRvdy5IVE1MTWVkaWFFbGVtZW50ICYmXG4gICAgICAgICEoJ3NyY09iamVjdCcgaW4gd2luZG93LkhUTUxNZWRpYUVsZW1lbnQucHJvdG90eXBlKSkge1xuICAgICAgICAvLyBTaGltIHRoZSBzcmNPYmplY3QgcHJvcGVydHksIG9uY2UsIHdoZW4gSFRNTE1lZGlhRWxlbWVudCBpcyBmb3VuZC5cbiAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHdpbmRvdy5IVE1MTWVkaWFFbGVtZW50LnByb3RvdHlwZSwgJ3NyY09iamVjdCcsIHtcbiAgICAgICAgICBnZXQ6IGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3NyY09iamVjdDtcbiAgICAgICAgICB9LFxuICAgICAgICAgIHNldDogZnVuY3Rpb24oc3RyZWFtKSB7XG4gICAgICAgICAgICB2YXIgc2VsZiA9IHRoaXM7XG4gICAgICAgICAgICAvLyBVc2UgX3NyY09iamVjdCBhcyBhIHByaXZhdGUgcHJvcGVydHkgZm9yIHRoaXMgc2hpbVxuICAgICAgICAgICAgdGhpcy5fc3JjT2JqZWN0ID0gc3RyZWFtO1xuICAgICAgICAgICAgaWYgKHRoaXMuc3JjKSB7XG4gICAgICAgICAgICAgIFVSTC5yZXZva2VPYmplY3RVUkwodGhpcy5zcmMpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoIXN0cmVhbSkge1xuICAgICAgICAgICAgICB0aGlzLnNyYyA9ICcnO1xuICAgICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5zcmMgPSBVUkwuY3JlYXRlT2JqZWN0VVJMKHN0cmVhbSk7XG4gICAgICAgICAgICAvLyBXZSBuZWVkIHRvIHJlY3JlYXRlIHRoZSBibG9iIHVybCB3aGVuIGEgdHJhY2sgaXMgYWRkZWQgb3JcbiAgICAgICAgICAgIC8vIHJlbW92ZWQuIERvaW5nIGl0IG1hbnVhbGx5IHNpbmNlIHdlIHdhbnQgdG8gYXZvaWQgYSByZWN1cnNpb24uXG4gICAgICAgICAgICBzdHJlYW0uYWRkRXZlbnRMaXN0ZW5lcignYWRkdHJhY2snLCBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgICAgaWYgKHNlbGYuc3JjKSB7XG4gICAgICAgICAgICAgICAgVVJMLnJldm9rZU9iamVjdFVSTChzZWxmLnNyYyk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgc2VsZi5zcmMgPSBVUkwuY3JlYXRlT2JqZWN0VVJMKHN0cmVhbSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHN0cmVhbS5hZGRFdmVudExpc3RlbmVyKCdyZW1vdmV0cmFjaycsIGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgICBpZiAoc2VsZi5zcmMpIHtcbiAgICAgICAgICAgICAgICBVUkwucmV2b2tlT2JqZWN0VVJMKHNlbGYuc3JjKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBzZWxmLnNyYyA9IFVSTC5jcmVhdGVPYmplY3RVUkwoc3RyZWFtKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuICB9LFxuXG4gIHNoaW1BZGRUcmFja1JlbW92ZVRyYWNrOiBmdW5jdGlvbih3aW5kb3cpIHtcbiAgICB2YXIgYnJvd3NlckRldGFpbHMgPSB1dGlscy5kZXRlY3RCcm93c2VyKHdpbmRvdyk7XG4gICAgLy8gc2hpbSBhZGRUcmFjayBhbmQgcmVtb3ZlVHJhY2suXG4gICAgaWYgKHdpbmRvdy5SVENQZWVyQ29ubmVjdGlvbi5wcm90b3R5cGUuYWRkVHJhY2sgJiZcbiAgICAgICAgYnJvd3NlckRldGFpbHMudmVyc2lvbiA+PSA2Mikge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIGFsc28gc2hpbSBwYy5nZXRMb2NhbFN0cmVhbXMgd2hlbiBhZGRUcmFjayBpcyBzaGltbWVkXG4gICAgLy8gdG8gcmV0dXJuIHRoZSBvcmlnaW5hbCBzdHJlYW1zLlxuICAgIHZhciBvcmlnR2V0TG9jYWxTdHJlYW1zID0gd2luZG93LlJUQ1BlZXJDb25uZWN0aW9uLnByb3RvdHlwZVxuICAgICAgICAuZ2V0TG9jYWxTdHJlYW1zO1xuICAgIHdpbmRvdy5SVENQZWVyQ29ubmVjdGlvbi5wcm90b3R5cGUuZ2V0TG9jYWxTdHJlYW1zID0gZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgc2VsZiA9IHRoaXM7XG4gICAgICB2YXIgbmF0aXZlU3RyZWFtcyA9IG9yaWdHZXRMb2NhbFN0cmVhbXMuYXBwbHkodGhpcyk7XG4gICAgICBzZWxmLl9yZXZlcnNlU3RyZWFtcyA9IHNlbGYuX3JldmVyc2VTdHJlYW1zIHx8IHt9O1xuICAgICAgcmV0dXJuIG5hdGl2ZVN0cmVhbXMubWFwKGZ1bmN0aW9uKHN0cmVhbSkge1xuICAgICAgICByZXR1cm4gc2VsZi5fcmV2ZXJzZVN0cmVhbXNbc3RyZWFtLmlkXTtcbiAgICAgIH0pO1xuICAgIH07XG5cbiAgICB2YXIgb3JpZ0FkZFN0cmVhbSA9IHdpbmRvdy5SVENQZWVyQ29ubmVjdGlvbi5wcm90b3R5cGUuYWRkU3RyZWFtO1xuICAgIHdpbmRvdy5SVENQZWVyQ29ubmVjdGlvbi5wcm90b3R5cGUuYWRkU3RyZWFtID0gZnVuY3Rpb24oc3RyZWFtKSB7XG4gICAgICB2YXIgcGMgPSB0aGlzO1xuICAgICAgcGMuX3N0cmVhbXMgPSBwYy5fc3RyZWFtcyB8fCB7fTtcbiAgICAgIHBjLl9yZXZlcnNlU3RyZWFtcyA9IHBjLl9yZXZlcnNlU3RyZWFtcyB8fCB7fTtcblxuICAgICAgc3RyZWFtLmdldFRyYWNrcygpLmZvckVhY2goZnVuY3Rpb24odHJhY2spIHtcbiAgICAgICAgdmFyIGFscmVhZHlFeGlzdHMgPSBwYy5nZXRTZW5kZXJzKCkuZmluZChmdW5jdGlvbihzKSB7XG4gICAgICAgICAgcmV0dXJuIHMudHJhY2sgPT09IHRyYWNrO1xuICAgICAgICB9KTtcbiAgICAgICAgaWYgKGFscmVhZHlFeGlzdHMpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKCdUcmFjayBhbHJlYWR5IGV4aXN0cy4nLFxuICAgICAgICAgICAgICAnSW52YWxpZEFjY2Vzc0Vycm9yJyk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgLy8gQWRkIGlkZW50aXR5IG1hcHBpbmcgZm9yIGNvbnNpc3RlbmN5IHdpdGggYWRkVHJhY2suXG4gICAgICAvLyBVbmxlc3MgdGhpcyBpcyBiZWluZyB1c2VkIHdpdGggYSBzdHJlYW0gZnJvbSBhZGRUcmFjay5cbiAgICAgIGlmICghcGMuX3JldmVyc2VTdHJlYW1zW3N0cmVhbS5pZF0pIHtcbiAgICAgICAgdmFyIG5ld1N0cmVhbSA9IG5ldyB3aW5kb3cuTWVkaWFTdHJlYW0oc3RyZWFtLmdldFRyYWNrcygpKTtcbiAgICAgICAgcGMuX3N0cmVhbXNbc3RyZWFtLmlkXSA9IG5ld1N0cmVhbTtcbiAgICAgICAgcGMuX3JldmVyc2VTdHJlYW1zW25ld1N0cmVhbS5pZF0gPSBzdHJlYW07XG4gICAgICAgIHN0cmVhbSA9IG5ld1N0cmVhbTtcbiAgICAgIH1cbiAgICAgIG9yaWdBZGRTdHJlYW0uYXBwbHkocGMsIFtzdHJlYW1dKTtcbiAgICB9O1xuXG4gICAgdmFyIG9yaWdSZW1vdmVTdHJlYW0gPSB3aW5kb3cuUlRDUGVlckNvbm5lY3Rpb24ucHJvdG90eXBlLnJlbW92ZVN0cmVhbTtcbiAgICB3aW5kb3cuUlRDUGVlckNvbm5lY3Rpb24ucHJvdG90eXBlLnJlbW92ZVN0cmVhbSA9IGZ1bmN0aW9uKHN0cmVhbSkge1xuICAgICAgdmFyIHBjID0gdGhpcztcbiAgICAgIHBjLl9zdHJlYW1zID0gcGMuX3N0cmVhbXMgfHwge307XG4gICAgICBwYy5fcmV2ZXJzZVN0cmVhbXMgPSBwYy5fcmV2ZXJzZVN0cmVhbXMgfHwge307XG5cbiAgICAgIG9yaWdSZW1vdmVTdHJlYW0uYXBwbHkocGMsIFsocGMuX3N0cmVhbXNbc3RyZWFtLmlkXSB8fCBzdHJlYW0pXSk7XG4gICAgICBkZWxldGUgcGMuX3JldmVyc2VTdHJlYW1zWyhwYy5fc3RyZWFtc1tzdHJlYW0uaWRdID9cbiAgICAgICAgICBwYy5fc3RyZWFtc1tzdHJlYW0uaWRdLmlkIDogc3RyZWFtLmlkKV07XG4gICAgICBkZWxldGUgcGMuX3N0cmVhbXNbc3RyZWFtLmlkXTtcbiAgICB9O1xuXG4gICAgd2luZG93LlJUQ1BlZXJDb25uZWN0aW9uLnByb3RvdHlwZS5hZGRUcmFjayA9IGZ1bmN0aW9uKHRyYWNrLCBzdHJlYW0pIHtcbiAgICAgIHZhciBwYyA9IHRoaXM7XG4gICAgICBpZiAocGMuc2lnbmFsaW5nU3RhdGUgPT09ICdjbG9zZWQnKSB7XG4gICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oXG4gICAgICAgICAgJ1RoZSBSVENQZWVyQ29ubmVjdGlvblxcJ3Mgc2lnbmFsaW5nU3RhdGUgaXMgXFwnY2xvc2VkXFwnLicsXG4gICAgICAgICAgJ0ludmFsaWRTdGF0ZUVycm9yJyk7XG4gICAgICB9XG4gICAgICB2YXIgc3RyZWFtcyA9IFtdLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKTtcbiAgICAgIGlmIChzdHJlYW1zLmxlbmd0aCAhPT0gMSB8fFxuICAgICAgICAgICFzdHJlYW1zWzBdLmdldFRyYWNrcygpLmZpbmQoZnVuY3Rpb24odCkge1xuICAgICAgICAgICAgcmV0dXJuIHQgPT09IHRyYWNrO1xuICAgICAgICAgIH0pKSB7XG4gICAgICAgIC8vIHRoaXMgaXMgbm90IGZ1bGx5IGNvcnJlY3QgYnV0IGFsbCB3ZSBjYW4gbWFuYWdlIHdpdGhvdXRcbiAgICAgICAgLy8gW1thc3NvY2lhdGVkIE1lZGlhU3RyZWFtc11dIGludGVybmFsIHNsb3QuXG4gICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oXG4gICAgICAgICAgJ1RoZSBhZGFwdGVyLmpzIGFkZFRyYWNrIHBvbHlmaWxsIG9ubHkgc3VwcG9ydHMgYSBzaW5nbGUgJyArXG4gICAgICAgICAgJyBzdHJlYW0gd2hpY2ggaXMgYXNzb2NpYXRlZCB3aXRoIHRoZSBzcGVjaWZpZWQgdHJhY2suJyxcbiAgICAgICAgICAnTm90U3VwcG9ydGVkRXJyb3InKTtcbiAgICAgIH1cblxuICAgICAgdmFyIGFscmVhZHlFeGlzdHMgPSBwYy5nZXRTZW5kZXJzKCkuZmluZChmdW5jdGlvbihzKSB7XG4gICAgICAgIHJldHVybiBzLnRyYWNrID09PSB0cmFjaztcbiAgICAgIH0pO1xuICAgICAgaWYgKGFscmVhZHlFeGlzdHMpIHtcbiAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbignVHJhY2sgYWxyZWFkeSBleGlzdHMuJyxcbiAgICAgICAgICAgICdJbnZhbGlkQWNjZXNzRXJyb3InKTtcbiAgICAgIH1cblxuICAgICAgcGMuX3N0cmVhbXMgPSBwYy5fc3RyZWFtcyB8fCB7fTtcbiAgICAgIHBjLl9yZXZlcnNlU3RyZWFtcyA9IHBjLl9yZXZlcnNlU3RyZWFtcyB8fCB7fTtcbiAgICAgIHZhciBvbGRTdHJlYW0gPSBwYy5fc3RyZWFtc1tzdHJlYW0uaWRdO1xuICAgICAgaWYgKG9sZFN0cmVhbSkge1xuICAgICAgICAvLyB0aGlzIGlzIHVzaW5nIG9kZCBDaHJvbWUgYmVoYXZpb3VyLCB1c2Ugd2l0aCBjYXV0aW9uOlxuICAgICAgICAvLyBodHRwczovL2J1Z3MuY2hyb21pdW0ub3JnL3Avd2VicnRjL2lzc3Vlcy9kZXRhaWw/aWQ9NzgxNVxuICAgICAgICAvLyBOb3RlOiB3ZSByZWx5IG9uIHRoZSBoaWdoLWxldmVsIGFkZFRyYWNrL2R0bWYgc2hpbSB0b1xuICAgICAgICAvLyBjcmVhdGUgdGhlIHNlbmRlciB3aXRoIGEgZHRtZiBzZW5kZXIuXG4gICAgICAgIG9sZFN0cmVhbS5hZGRUcmFjayh0cmFjayk7XG5cbiAgICAgICAgLy8gVHJpZ2dlciBPTk4gYXN5bmMuXG4gICAgICAgIFByb21pc2UucmVzb2x2ZSgpLnRoZW4oZnVuY3Rpb24oKSB7XG4gICAgICAgICAgcGMuZGlzcGF0Y2hFdmVudChuZXcgRXZlbnQoJ25lZ290aWF0aW9ubmVlZGVkJykpO1xuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHZhciBuZXdTdHJlYW0gPSBuZXcgd2luZG93Lk1lZGlhU3RyZWFtKFt0cmFja10pO1xuICAgICAgICBwYy5fc3RyZWFtc1tzdHJlYW0uaWRdID0gbmV3U3RyZWFtO1xuICAgICAgICBwYy5fcmV2ZXJzZVN0cmVhbXNbbmV3U3RyZWFtLmlkXSA9IHN0cmVhbTtcbiAgICAgICAgcGMuYWRkU3RyZWFtKG5ld1N0cmVhbSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gcGMuZ2V0U2VuZGVycygpLmZpbmQoZnVuY3Rpb24ocykge1xuICAgICAgICByZXR1cm4gcy50cmFjayA9PT0gdHJhY2s7XG4gICAgICB9KTtcbiAgICB9O1xuXG4gICAgLy8gcmVwbGFjZSB0aGUgaW50ZXJuYWwgc3RyZWFtIGlkIHdpdGggdGhlIGV4dGVybmFsIG9uZSBhbmRcbiAgICAvLyB2aWNlIHZlcnNhLlxuICAgIGZ1bmN0aW9uIHJlcGxhY2VJbnRlcm5hbFN0cmVhbUlkKHBjLCBkZXNjcmlwdGlvbikge1xuICAgICAgdmFyIHNkcCA9IGRlc2NyaXB0aW9uLnNkcDtcbiAgICAgIE9iamVjdC5rZXlzKHBjLl9yZXZlcnNlU3RyZWFtcyB8fCBbXSkuZm9yRWFjaChmdW5jdGlvbihpbnRlcm5hbElkKSB7XG4gICAgICAgIHZhciBleHRlcm5hbFN0cmVhbSA9IHBjLl9yZXZlcnNlU3RyZWFtc1tpbnRlcm5hbElkXTtcbiAgICAgICAgdmFyIGludGVybmFsU3RyZWFtID0gcGMuX3N0cmVhbXNbZXh0ZXJuYWxTdHJlYW0uaWRdO1xuICAgICAgICBzZHAgPSBzZHAucmVwbGFjZShuZXcgUmVnRXhwKGludGVybmFsU3RyZWFtLmlkLCAnZycpLFxuICAgICAgICAgICAgZXh0ZXJuYWxTdHJlYW0uaWQpO1xuICAgICAgfSk7XG4gICAgICByZXR1cm4gbmV3IFJUQ1Nlc3Npb25EZXNjcmlwdGlvbih7XG4gICAgICAgIHR5cGU6IGRlc2NyaXB0aW9uLnR5cGUsXG4gICAgICAgIHNkcDogc2RwXG4gICAgICB9KTtcbiAgICB9XG4gICAgZnVuY3Rpb24gcmVwbGFjZUV4dGVybmFsU3RyZWFtSWQocGMsIGRlc2NyaXB0aW9uKSB7XG4gICAgICB2YXIgc2RwID0gZGVzY3JpcHRpb24uc2RwO1xuICAgICAgT2JqZWN0LmtleXMocGMuX3JldmVyc2VTdHJlYW1zIHx8IFtdKS5mb3JFYWNoKGZ1bmN0aW9uKGludGVybmFsSWQpIHtcbiAgICAgICAgdmFyIGV4dGVybmFsU3RyZWFtID0gcGMuX3JldmVyc2VTdHJlYW1zW2ludGVybmFsSWRdO1xuICAgICAgICB2YXIgaW50ZXJuYWxTdHJlYW0gPSBwYy5fc3RyZWFtc1tleHRlcm5hbFN0cmVhbS5pZF07XG4gICAgICAgIHNkcCA9IHNkcC5yZXBsYWNlKG5ldyBSZWdFeHAoZXh0ZXJuYWxTdHJlYW0uaWQsICdnJyksXG4gICAgICAgICAgICBpbnRlcm5hbFN0cmVhbS5pZCk7XG4gICAgICB9KTtcbiAgICAgIHJldHVybiBuZXcgUlRDU2Vzc2lvbkRlc2NyaXB0aW9uKHtcbiAgICAgICAgdHlwZTogZGVzY3JpcHRpb24udHlwZSxcbiAgICAgICAgc2RwOiBzZHBcbiAgICAgIH0pO1xuICAgIH1cbiAgICBbJ2NyZWF0ZU9mZmVyJywgJ2NyZWF0ZUFuc3dlciddLmZvckVhY2goZnVuY3Rpb24obWV0aG9kKSB7XG4gICAgICB2YXIgbmF0aXZlTWV0aG9kID0gd2luZG93LlJUQ1BlZXJDb25uZWN0aW9uLnByb3RvdHlwZVttZXRob2RdO1xuICAgICAgd2luZG93LlJUQ1BlZXJDb25uZWN0aW9uLnByb3RvdHlwZVttZXRob2RdID0gZnVuY3Rpb24oKSB7XG4gICAgICAgIHZhciBwYyA9IHRoaXM7XG4gICAgICAgIHZhciBhcmdzID0gYXJndW1lbnRzO1xuICAgICAgICB2YXIgaXNMZWdhY3lDYWxsID0gYXJndW1lbnRzLmxlbmd0aCAmJlxuICAgICAgICAgICAgdHlwZW9mIGFyZ3VtZW50c1swXSA9PT0gJ2Z1bmN0aW9uJztcbiAgICAgICAgaWYgKGlzTGVnYWN5Q2FsbCkge1xuICAgICAgICAgIHJldHVybiBuYXRpdmVNZXRob2QuYXBwbHkocGMsIFtcbiAgICAgICAgICAgIGZ1bmN0aW9uKGRlc2NyaXB0aW9uKSB7XG4gICAgICAgICAgICAgIHZhciBkZXNjID0gcmVwbGFjZUludGVybmFsU3RyZWFtSWQocGMsIGRlc2NyaXB0aW9uKTtcbiAgICAgICAgICAgICAgYXJnc1swXS5hcHBseShudWxsLCBbZGVzY10pO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGZ1bmN0aW9uKGVycikge1xuICAgICAgICAgICAgICBpZiAoYXJnc1sxXSkge1xuICAgICAgICAgICAgICAgIGFyZ3NbMV0uYXBwbHkobnVsbCwgZXJyKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSwgYXJndW1lbnRzWzJdXG4gICAgICAgICAgXSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG5hdGl2ZU1ldGhvZC5hcHBseShwYywgYXJndW1lbnRzKVxuICAgICAgICAudGhlbihmdW5jdGlvbihkZXNjcmlwdGlvbikge1xuICAgICAgICAgIHJldHVybiByZXBsYWNlSW50ZXJuYWxTdHJlYW1JZChwYywgZGVzY3JpcHRpb24pO1xuICAgICAgICB9KTtcbiAgICAgIH07XG4gICAgfSk7XG5cbiAgICB2YXIgb3JpZ1NldExvY2FsRGVzY3JpcHRpb24gPVxuICAgICAgICB3aW5kb3cuUlRDUGVlckNvbm5lY3Rpb24ucHJvdG90eXBlLnNldExvY2FsRGVzY3JpcHRpb247XG4gICAgd2luZG93LlJUQ1BlZXJDb25uZWN0aW9uLnByb3RvdHlwZS5zZXRMb2NhbERlc2NyaXB0aW9uID0gZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgcGMgPSB0aGlzO1xuICAgICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoIHx8ICFhcmd1bWVudHNbMF0udHlwZSkge1xuICAgICAgICByZXR1cm4gb3JpZ1NldExvY2FsRGVzY3JpcHRpb24uYXBwbHkocGMsIGFyZ3VtZW50cyk7XG4gICAgICB9XG4gICAgICBhcmd1bWVudHNbMF0gPSByZXBsYWNlRXh0ZXJuYWxTdHJlYW1JZChwYywgYXJndW1lbnRzWzBdKTtcbiAgICAgIHJldHVybiBvcmlnU2V0TG9jYWxEZXNjcmlwdGlvbi5hcHBseShwYywgYXJndW1lbnRzKTtcbiAgICB9O1xuXG4gICAgLy8gVE9ETzogbWFuZ2xlIGdldFN0YXRzOiBodHRwczovL3czYy5naXRodWIuaW8vd2VicnRjLXN0YXRzLyNkb20tcnRjbWVkaWFzdHJlYW1zdGF0cy1zdHJlYW1pZGVudGlmaWVyXG5cbiAgICB2YXIgb3JpZ0xvY2FsRGVzY3JpcHRpb24gPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKFxuICAgICAgICB3aW5kb3cuUlRDUGVlckNvbm5lY3Rpb24ucHJvdG90eXBlLCAnbG9jYWxEZXNjcmlwdGlvbicpO1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh3aW5kb3cuUlRDUGVlckNvbm5lY3Rpb24ucHJvdG90eXBlLFxuICAgICAgICAnbG9jYWxEZXNjcmlwdGlvbicsIHtcbiAgICAgICAgICBnZXQ6IGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgdmFyIHBjID0gdGhpcztcbiAgICAgICAgICAgIHZhciBkZXNjcmlwdGlvbiA9IG9yaWdMb2NhbERlc2NyaXB0aW9uLmdldC5hcHBseSh0aGlzKTtcbiAgICAgICAgICAgIGlmIChkZXNjcmlwdGlvbi50eXBlID09PSAnJykge1xuICAgICAgICAgICAgICByZXR1cm4gZGVzY3JpcHRpb247XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gcmVwbGFjZUludGVybmFsU3RyZWFtSWQocGMsIGRlc2NyaXB0aW9uKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgd2luZG93LlJUQ1BlZXJDb25uZWN0aW9uLnByb3RvdHlwZS5yZW1vdmVUcmFjayA9IGZ1bmN0aW9uKHNlbmRlcikge1xuICAgICAgdmFyIHBjID0gdGhpcztcbiAgICAgIGlmIChwYy5zaWduYWxpbmdTdGF0ZSA9PT0gJ2Nsb3NlZCcpIHtcbiAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbihcbiAgICAgICAgICAnVGhlIFJUQ1BlZXJDb25uZWN0aW9uXFwncyBzaWduYWxpbmdTdGF0ZSBpcyBcXCdjbG9zZWRcXCcuJyxcbiAgICAgICAgICAnSW52YWxpZFN0YXRlRXJyb3InKTtcbiAgICAgIH1cbiAgICAgIC8vIFdlIGNhbiBub3QgeWV0IGNoZWNrIGZvciBzZW5kZXIgaW5zdGFuY2VvZiBSVENSdHBTZW5kZXJcbiAgICAgIC8vIHNpbmNlIHdlIHNoaW0gUlRQU2VuZGVyLiBTbyB3ZSBjaGVjayBpZiBzZW5kZXIuX3BjIGlzIHNldC5cbiAgICAgIGlmICghc2VuZGVyLl9wYykge1xuICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKCdBcmd1bWVudCAxIG9mIFJUQ1BlZXJDb25uZWN0aW9uLnJlbW92ZVRyYWNrICcgK1xuICAgICAgICAgICAgJ2RvZXMgbm90IGltcGxlbWVudCBpbnRlcmZhY2UgUlRDUnRwU2VuZGVyLicsICdUeXBlRXJyb3InKTtcbiAgICAgIH1cbiAgICAgIHZhciBpc0xvY2FsID0gc2VuZGVyLl9wYyA9PT0gcGM7XG4gICAgICBpZiAoIWlzTG9jYWwpIHtcbiAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbignU2VuZGVyIHdhcyBub3QgY3JlYXRlZCBieSB0aGlzIGNvbm5lY3Rpb24uJyxcbiAgICAgICAgICAgICdJbnZhbGlkQWNjZXNzRXJyb3InKTtcbiAgICAgIH1cblxuICAgICAgLy8gU2VhcmNoIGZvciB0aGUgbmF0aXZlIHN0cmVhbSB0aGUgc2VuZGVycyB0cmFjayBiZWxvbmdzIHRvLlxuICAgICAgcGMuX3N0cmVhbXMgPSBwYy5fc3RyZWFtcyB8fCB7fTtcbiAgICAgIHZhciBzdHJlYW07XG4gICAgICBPYmplY3Qua2V5cyhwYy5fc3RyZWFtcykuZm9yRWFjaChmdW5jdGlvbihzdHJlYW1pZCkge1xuICAgICAgICB2YXIgaGFzVHJhY2sgPSBwYy5fc3RyZWFtc1tzdHJlYW1pZF0uZ2V0VHJhY2tzKCkuZmluZChmdW5jdGlvbih0cmFjaykge1xuICAgICAgICAgIHJldHVybiBzZW5kZXIudHJhY2sgPT09IHRyYWNrO1xuICAgICAgICB9KTtcbiAgICAgICAgaWYgKGhhc1RyYWNrKSB7XG4gICAgICAgICAgc3RyZWFtID0gcGMuX3N0cmVhbXNbc3RyZWFtaWRdO1xuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgaWYgKHN0cmVhbSkge1xuICAgICAgICBpZiAoc3RyZWFtLmdldFRyYWNrcygpLmxlbmd0aCA9PT0gMSkge1xuICAgICAgICAgIC8vIGlmIHRoaXMgaXMgdGhlIGxhc3QgdHJhY2sgb2YgdGhlIHN0cmVhbSwgcmVtb3ZlIHRoZSBzdHJlYW0uIFRoaXNcbiAgICAgICAgICAvLyB0YWtlcyBjYXJlIG9mIGFueSBzaGltbWVkIF9zZW5kZXJzLlxuICAgICAgICAgIHBjLnJlbW92ZVN0cmVhbShzdHJlYW0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIHJlbHlpbmcgb24gdGhlIHNhbWUgb2RkIGNocm9tZSBiZWhhdmlvdXIgYXMgYWJvdmUuXG4gICAgICAgICAgc3RyZWFtLnJlbW92ZVRyYWNrKHNlbmRlci50cmFjayk7XG4gICAgICAgIH1cbiAgICAgICAgcGMuZGlzcGF0Y2hFdmVudChuZXcgRXZlbnQoJ25lZ290aWF0aW9ubmVlZGVkJykpO1xuICAgICAgfVxuICAgIH07XG4gIH0sXG5cbiAgc2hpbVBlZXJDb25uZWN0aW9uOiBmdW5jdGlvbih3aW5kb3cpIHtcbiAgICB2YXIgYnJvd3NlckRldGFpbHMgPSB1dGlscy5kZXRlY3RCcm93c2VyKHdpbmRvdyk7XG5cbiAgICAvLyBUaGUgUlRDUGVlckNvbm5lY3Rpb24gb2JqZWN0LlxuICAgIGlmICghd2luZG93LlJUQ1BlZXJDb25uZWN0aW9uKSB7XG4gICAgICB3aW5kb3cuUlRDUGVlckNvbm5lY3Rpb24gPSBmdW5jdGlvbihwY0NvbmZpZywgcGNDb25zdHJhaW50cykge1xuICAgICAgICAvLyBUcmFuc2xhdGUgaWNlVHJhbnNwb3J0UG9saWN5IHRvIGljZVRyYW5zcG9ydHMsXG4gICAgICAgIC8vIHNlZSBodHRwczovL2NvZGUuZ29vZ2xlLmNvbS9wL3dlYnJ0Yy9pc3N1ZXMvZGV0YWlsP2lkPTQ4NjlcbiAgICAgICAgLy8gdGhpcyB3YXMgZml4ZWQgaW4gTTU2IGFsb25nIHdpdGggdW5wcmVmaXhpbmcgUlRDUGVlckNvbm5lY3Rpb24uXG4gICAgICAgIGxvZ2dpbmcoJ1BlZXJDb25uZWN0aW9uJyk7XG4gICAgICAgIGlmIChwY0NvbmZpZyAmJiBwY0NvbmZpZy5pY2VUcmFuc3BvcnRQb2xpY3kpIHtcbiAgICAgICAgICBwY0NvbmZpZy5pY2VUcmFuc3BvcnRzID0gcGNDb25maWcuaWNlVHJhbnNwb3J0UG9saWN5O1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG5ldyB3aW5kb3cud2Via2l0UlRDUGVlckNvbm5lY3Rpb24ocGNDb25maWcsIHBjQ29uc3RyYWludHMpO1xuICAgICAgfTtcbiAgICAgIHdpbmRvdy5SVENQZWVyQ29ubmVjdGlvbi5wcm90b3R5cGUgPVxuICAgICAgICAgIHdpbmRvdy53ZWJraXRSVENQZWVyQ29ubmVjdGlvbi5wcm90b3R5cGU7XG4gICAgICAvLyB3cmFwIHN0YXRpYyBtZXRob2RzLiBDdXJyZW50bHkganVzdCBnZW5lcmF0ZUNlcnRpZmljYXRlLlxuICAgICAgaWYgKHdpbmRvdy53ZWJraXRSVENQZWVyQ29ubmVjdGlvbi5nZW5lcmF0ZUNlcnRpZmljYXRlKSB7XG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh3aW5kb3cuUlRDUGVlckNvbm5lY3Rpb24sICdnZW5lcmF0ZUNlcnRpZmljYXRlJywge1xuICAgICAgICAgIGdldDogZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICByZXR1cm4gd2luZG93LndlYmtpdFJUQ1BlZXJDb25uZWN0aW9uLmdlbmVyYXRlQ2VydGlmaWNhdGU7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgLy8gbWlncmF0ZSBmcm9tIG5vbi1zcGVjIFJUQ0ljZVNlcnZlci51cmwgdG8gUlRDSWNlU2VydmVyLnVybHNcbiAgICAgIHZhciBPcmlnUGVlckNvbm5lY3Rpb24gPSB3aW5kb3cuUlRDUGVlckNvbm5lY3Rpb247XG4gICAgICB3aW5kb3cuUlRDUGVlckNvbm5lY3Rpb24gPSBmdW5jdGlvbihwY0NvbmZpZywgcGNDb25zdHJhaW50cykge1xuICAgICAgICBpZiAocGNDb25maWcgJiYgcGNDb25maWcuaWNlU2VydmVycykge1xuICAgICAgICAgIHZhciBuZXdJY2VTZXJ2ZXJzID0gW107XG4gICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBwY0NvbmZpZy5pY2VTZXJ2ZXJzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICB2YXIgc2VydmVyID0gcGNDb25maWcuaWNlU2VydmVyc1tpXTtcbiAgICAgICAgICAgIGlmICghc2VydmVyLmhhc093blByb3BlcnR5KCd1cmxzJykgJiZcbiAgICAgICAgICAgICAgICBzZXJ2ZXIuaGFzT3duUHJvcGVydHkoJ3VybCcpKSB7XG4gICAgICAgICAgICAgIHV0aWxzLmRlcHJlY2F0ZWQoJ1JUQ0ljZVNlcnZlci51cmwnLCAnUlRDSWNlU2VydmVyLnVybHMnKTtcbiAgICAgICAgICAgICAgc2VydmVyID0gSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeShzZXJ2ZXIpKTtcbiAgICAgICAgICAgICAgc2VydmVyLnVybHMgPSBzZXJ2ZXIudXJsO1xuICAgICAgICAgICAgICBuZXdJY2VTZXJ2ZXJzLnB1c2goc2VydmVyKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIG5ld0ljZVNlcnZlcnMucHVzaChwY0NvbmZpZy5pY2VTZXJ2ZXJzW2ldKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgcGNDb25maWcuaWNlU2VydmVycyA9IG5ld0ljZVNlcnZlcnM7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG5ldyBPcmlnUGVlckNvbm5lY3Rpb24ocGNDb25maWcsIHBjQ29uc3RyYWludHMpO1xuICAgICAgfTtcbiAgICAgIHdpbmRvdy5SVENQZWVyQ29ubmVjdGlvbi5wcm90b3R5cGUgPSBPcmlnUGVlckNvbm5lY3Rpb24ucHJvdG90eXBlO1xuICAgICAgLy8gd3JhcCBzdGF0aWMgbWV0aG9kcy4gQ3VycmVudGx5IGp1c3QgZ2VuZXJhdGVDZXJ0aWZpY2F0ZS5cbiAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh3aW5kb3cuUlRDUGVlckNvbm5lY3Rpb24sICdnZW5lcmF0ZUNlcnRpZmljYXRlJywge1xuICAgICAgICBnZXQ6IGZ1bmN0aW9uKCkge1xuICAgICAgICAgIHJldHVybiBPcmlnUGVlckNvbm5lY3Rpb24uZ2VuZXJhdGVDZXJ0aWZpY2F0ZTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgdmFyIG9yaWdHZXRTdGF0cyA9IHdpbmRvdy5SVENQZWVyQ29ubmVjdGlvbi5wcm90b3R5cGUuZ2V0U3RhdHM7XG4gICAgd2luZG93LlJUQ1BlZXJDb25uZWN0aW9uLnByb3RvdHlwZS5nZXRTdGF0cyA9IGZ1bmN0aW9uKHNlbGVjdG9yLFxuICAgICAgICBzdWNjZXNzQ2FsbGJhY2ssIGVycm9yQ2FsbGJhY2spIHtcbiAgICAgIHZhciBzZWxmID0gdGhpcztcbiAgICAgIHZhciBhcmdzID0gYXJndW1lbnRzO1xuXG4gICAgICAvLyBJZiBzZWxlY3RvciBpcyBhIGZ1bmN0aW9uIHRoZW4gd2UgYXJlIGluIHRoZSBvbGQgc3R5bGUgc3RhdHMgc28ganVzdFxuICAgICAgLy8gcGFzcyBiYWNrIHRoZSBvcmlnaW5hbCBnZXRTdGF0cyBmb3JtYXQgdG8gYXZvaWQgYnJlYWtpbmcgb2xkIHVzZXJzLlxuICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPiAwICYmIHR5cGVvZiBzZWxlY3RvciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICByZXR1cm4gb3JpZ0dldFN0YXRzLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICB9XG5cbiAgICAgIC8vIFdoZW4gc3BlYy1zdHlsZSBnZXRTdGF0cyBpcyBzdXBwb3J0ZWQsIHJldHVybiB0aG9zZSB3aGVuIGNhbGxlZCB3aXRoXG4gICAgICAvLyBlaXRoZXIgbm8gYXJndW1lbnRzIG9yIHRoZSBzZWxlY3RvciBhcmd1bWVudCBpcyBudWxsLlxuICAgICAgaWYgKG9yaWdHZXRTdGF0cy5sZW5ndGggPT09IDAgJiYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDAgfHxcbiAgICAgICAgICB0eXBlb2YgYXJndW1lbnRzWzBdICE9PSAnZnVuY3Rpb24nKSkge1xuICAgICAgICByZXR1cm4gb3JpZ0dldFN0YXRzLmFwcGx5KHRoaXMsIFtdKTtcbiAgICAgIH1cblxuICAgICAgdmFyIGZpeENocm9tZVN0YXRzXyA9IGZ1bmN0aW9uKHJlc3BvbnNlKSB7XG4gICAgICAgIHZhciBzdGFuZGFyZFJlcG9ydCA9IHt9O1xuICAgICAgICB2YXIgcmVwb3J0cyA9IHJlc3BvbnNlLnJlc3VsdCgpO1xuICAgICAgICByZXBvcnRzLmZvckVhY2goZnVuY3Rpb24ocmVwb3J0KSB7XG4gICAgICAgICAgdmFyIHN0YW5kYXJkU3RhdHMgPSB7XG4gICAgICAgICAgICBpZDogcmVwb3J0LmlkLFxuICAgICAgICAgICAgdGltZXN0YW1wOiByZXBvcnQudGltZXN0YW1wLFxuICAgICAgICAgICAgdHlwZToge1xuICAgICAgICAgICAgICBsb2NhbGNhbmRpZGF0ZTogJ2xvY2FsLWNhbmRpZGF0ZScsXG4gICAgICAgICAgICAgIHJlbW90ZWNhbmRpZGF0ZTogJ3JlbW90ZS1jYW5kaWRhdGUnXG4gICAgICAgICAgICB9W3JlcG9ydC50eXBlXSB8fCByZXBvcnQudHlwZVxuICAgICAgICAgIH07XG4gICAgICAgICAgcmVwb3J0Lm5hbWVzKCkuZm9yRWFjaChmdW5jdGlvbihuYW1lKSB7XG4gICAgICAgICAgICBzdGFuZGFyZFN0YXRzW25hbWVdID0gcmVwb3J0LnN0YXQobmFtZSk7XG4gICAgICAgICAgfSk7XG4gICAgICAgICAgc3RhbmRhcmRSZXBvcnRbc3RhbmRhcmRTdGF0cy5pZF0gPSBzdGFuZGFyZFN0YXRzO1xuICAgICAgICB9KTtcblxuICAgICAgICByZXR1cm4gc3RhbmRhcmRSZXBvcnQ7XG4gICAgICB9O1xuXG4gICAgICAvLyBzaGltIGdldFN0YXRzIHdpdGggbWFwbGlrZSBzdXBwb3J0XG4gICAgICB2YXIgbWFrZU1hcFN0YXRzID0gZnVuY3Rpb24oc3RhdHMpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBNYXAoT2JqZWN0LmtleXMoc3RhdHMpLm1hcChmdW5jdGlvbihrZXkpIHtcbiAgICAgICAgICByZXR1cm4gW2tleSwgc3RhdHNba2V5XV07XG4gICAgICAgIH0pKTtcbiAgICAgIH07XG5cbiAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID49IDIpIHtcbiAgICAgICAgdmFyIHN1Y2Nlc3NDYWxsYmFja1dyYXBwZXJfID0gZnVuY3Rpb24ocmVzcG9uc2UpIHtcbiAgICAgICAgICBhcmdzWzFdKG1ha2VNYXBTdGF0cyhmaXhDaHJvbWVTdGF0c18ocmVzcG9uc2UpKSk7XG4gICAgICAgIH07XG5cbiAgICAgICAgcmV0dXJuIG9yaWdHZXRTdGF0cy5hcHBseSh0aGlzLCBbc3VjY2Vzc0NhbGxiYWNrV3JhcHBlcl8sXG4gICAgICAgICAgYXJndW1lbnRzWzBdXSk7XG4gICAgICB9XG5cbiAgICAgIC8vIHByb21pc2Utc3VwcG9ydFxuICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uKHJlc29sdmUsIHJlamVjdCkge1xuICAgICAgICBvcmlnR2V0U3RhdHMuYXBwbHkoc2VsZiwgW1xuICAgICAgICAgIGZ1bmN0aW9uKHJlc3BvbnNlKSB7XG4gICAgICAgICAgICByZXNvbHZlKG1ha2VNYXBTdGF0cyhmaXhDaHJvbWVTdGF0c18ocmVzcG9uc2UpKSk7XG4gICAgICAgICAgfSwgcmVqZWN0XSk7XG4gICAgICB9KS50aGVuKHN1Y2Nlc3NDYWxsYmFjaywgZXJyb3JDYWxsYmFjayk7XG4gICAgfTtcblxuICAgIC8vIGFkZCBwcm9taXNlIHN1cHBvcnQgLS0gbmF0aXZlbHkgYXZhaWxhYmxlIGluIENocm9tZSA1MVxuICAgIGlmIChicm93c2VyRGV0YWlscy52ZXJzaW9uIDwgNTEpIHtcbiAgICAgIFsnc2V0TG9jYWxEZXNjcmlwdGlvbicsICdzZXRSZW1vdGVEZXNjcmlwdGlvbicsICdhZGRJY2VDYW5kaWRhdGUnXVxuICAgICAgICAgIC5mb3JFYWNoKGZ1bmN0aW9uKG1ldGhvZCkge1xuICAgICAgICAgICAgdmFyIG5hdGl2ZU1ldGhvZCA9IHdpbmRvdy5SVENQZWVyQ29ubmVjdGlvbi5wcm90b3R5cGVbbWV0aG9kXTtcbiAgICAgICAgICAgIHdpbmRvdy5SVENQZWVyQ29ubmVjdGlvbi5wcm90b3R5cGVbbWV0aG9kXSA9IGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgICB2YXIgYXJncyA9IGFyZ3VtZW50cztcbiAgICAgICAgICAgICAgdmFyIHNlbGYgPSB0aGlzO1xuICAgICAgICAgICAgICB2YXIgcHJvbWlzZSA9IG5ldyBQcm9taXNlKGZ1bmN0aW9uKHJlc29sdmUsIHJlamVjdCkge1xuICAgICAgICAgICAgICAgIG5hdGl2ZU1ldGhvZC5hcHBseShzZWxmLCBbYXJnc1swXSwgcmVzb2x2ZSwgcmVqZWN0XSk7XG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICBpZiAoYXJncy5sZW5ndGggPCAyKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHByb21pc2U7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgcmV0dXJuIHByb21pc2UudGhlbihmdW5jdGlvbigpIHtcbiAgICAgICAgICAgICAgICBhcmdzWzFdLmFwcGx5KG51bGwsIFtdKTtcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgZnVuY3Rpb24oZXJyKSB7XG4gICAgICAgICAgICAgICAgaWYgKGFyZ3MubGVuZ3RoID49IDMpIHtcbiAgICAgICAgICAgICAgICAgIGFyZ3NbMl0uYXBwbHkobnVsbCwgW2Vycl0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8vIHByb21pc2Ugc3VwcG9ydCBmb3IgY3JlYXRlT2ZmZXIgYW5kIGNyZWF0ZUFuc3dlci4gQXZhaWxhYmxlICh3aXRob3V0XG4gICAgLy8gYnVncykgc2luY2UgTTUyOiBjcmJ1Zy82MTkyODlcbiAgICBpZiAoYnJvd3NlckRldGFpbHMudmVyc2lvbiA8IDUyKSB7XG4gICAgICBbJ2NyZWF0ZU9mZmVyJywgJ2NyZWF0ZUFuc3dlciddLmZvckVhY2goZnVuY3Rpb24obWV0aG9kKSB7XG4gICAgICAgIHZhciBuYXRpdmVNZXRob2QgPSB3aW5kb3cuUlRDUGVlckNvbm5lY3Rpb24ucHJvdG90eXBlW21ldGhvZF07XG4gICAgICAgIHdpbmRvdy5SVENQZWVyQ29ubmVjdGlvbi5wcm90b3R5cGVbbWV0aG9kXSA9IGZ1bmN0aW9uKCkge1xuICAgICAgICAgIHZhciBzZWxmID0gdGhpcztcbiAgICAgICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA8IDEgfHwgKGFyZ3VtZW50cy5sZW5ndGggPT09IDEgJiZcbiAgICAgICAgICAgICAgdHlwZW9mIGFyZ3VtZW50c1swXSA9PT0gJ29iamVjdCcpKSB7XG4gICAgICAgICAgICB2YXIgb3B0cyA9IGFyZ3VtZW50cy5sZW5ndGggPT09IDEgPyBhcmd1bWVudHNbMF0gOiB1bmRlZmluZWQ7XG4gICAgICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24ocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgICAgICAgICAgIG5hdGl2ZU1ldGhvZC5hcHBseShzZWxmLCBbcmVzb2x2ZSwgcmVqZWN0LCBvcHRzXSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIG5hdGl2ZU1ldGhvZC5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgICB9O1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLy8gc2hpbSBpbXBsaWNpdCBjcmVhdGlvbiBvZiBSVENTZXNzaW9uRGVzY3JpcHRpb24vUlRDSWNlQ2FuZGlkYXRlXG4gICAgWydzZXRMb2NhbERlc2NyaXB0aW9uJywgJ3NldFJlbW90ZURlc2NyaXB0aW9uJywgJ2FkZEljZUNhbmRpZGF0ZSddXG4gICAgICAgIC5mb3JFYWNoKGZ1bmN0aW9uKG1ldGhvZCkge1xuICAgICAgICAgIHZhciBuYXRpdmVNZXRob2QgPSB3aW5kb3cuUlRDUGVlckNvbm5lY3Rpb24ucHJvdG90eXBlW21ldGhvZF07XG4gICAgICAgICAgd2luZG93LlJUQ1BlZXJDb25uZWN0aW9uLnByb3RvdHlwZVttZXRob2RdID0gZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICBhcmd1bWVudHNbMF0gPSBuZXcgKChtZXRob2QgPT09ICdhZGRJY2VDYW5kaWRhdGUnKSA/XG4gICAgICAgICAgICAgICAgd2luZG93LlJUQ0ljZUNhbmRpZGF0ZSA6XG4gICAgICAgICAgICAgICAgd2luZG93LlJUQ1Nlc3Npb25EZXNjcmlwdGlvbikoYXJndW1lbnRzWzBdKTtcbiAgICAgICAgICAgIHJldHVybiBuYXRpdmVNZXRob2QuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgICAgICB9O1xuICAgICAgICB9KTtcblxuICAgIC8vIHN1cHBvcnQgZm9yIGFkZEljZUNhbmRpZGF0ZShudWxsIG9yIHVuZGVmaW5lZClcbiAgICB2YXIgbmF0aXZlQWRkSWNlQ2FuZGlkYXRlID1cbiAgICAgICAgd2luZG93LlJUQ1BlZXJDb25uZWN0aW9uLnByb3RvdHlwZS5hZGRJY2VDYW5kaWRhdGU7XG4gICAgd2luZG93LlJUQ1BlZXJDb25uZWN0aW9uLnByb3RvdHlwZS5hZGRJY2VDYW5kaWRhdGUgPSBmdW5jdGlvbigpIHtcbiAgICAgIGlmICghYXJndW1lbnRzWzBdKSB7XG4gICAgICAgIGlmIChhcmd1bWVudHNbMV0pIHtcbiAgICAgICAgICBhcmd1bWVudHNbMV0uYXBwbHkobnVsbCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG5hdGl2ZUFkZEljZUNhbmRpZGF0ZS5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIH07XG4gIH1cbn07XG5cblxuLy8gRXhwb3NlIHB1YmxpYyBtZXRob2RzLlxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIHNoaW1NZWRpYVN0cmVhbTogY2hyb21lU2hpbS5zaGltTWVkaWFTdHJlYW0sXG4gIHNoaW1PblRyYWNrOiBjaHJvbWVTaGltLnNoaW1PblRyYWNrLFxuICBzaGltQWRkVHJhY2tSZW1vdmVUcmFjazogY2hyb21lU2hpbS5zaGltQWRkVHJhY2tSZW1vdmVUcmFjayxcbiAgc2hpbUdldFNlbmRlcnNXaXRoRHRtZjogY2hyb21lU2hpbS5zaGltR2V0U2VuZGVyc1dpdGhEdG1mLFxuICBzaGltU291cmNlT2JqZWN0OiBjaHJvbWVTaGltLnNoaW1Tb3VyY2VPYmplY3QsXG4gIHNoaW1QZWVyQ29ubmVjdGlvbjogY2hyb21lU2hpbS5zaGltUGVlckNvbm5lY3Rpb24sXG4gIHNoaW1HZXRVc2VyTWVkaWE6IHJlcXVpcmUoJy4vZ2V0dXNlcm1lZGlhJylcbn07XG4iLCIvKlxuICogIENvcHlyaWdodCAoYykgMjAxNiBUaGUgV2ViUlRDIHByb2plY3QgYXV0aG9ycy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqXG4gKiAgVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZVxuICogIHRoYXQgY2FuIGJlIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgaW4gdGhlIHJvb3Qgb2YgdGhlIHNvdXJjZVxuICogIHRyZWUuXG4gKi9cbiAvKiBlc2xpbnQtZW52IG5vZGUgKi9cbid1c2Ugc3RyaWN0JztcbnZhciB1dGlscyA9IHJlcXVpcmUoJy4uL3V0aWxzLmpzJyk7XG52YXIgbG9nZ2luZyA9IHV0aWxzLmxvZztcblxuLy8gRXhwb3NlIHB1YmxpYyBtZXRob2RzLlxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbih3aW5kb3cpIHtcbiAgdmFyIGJyb3dzZXJEZXRhaWxzID0gdXRpbHMuZGV0ZWN0QnJvd3Nlcih3aW5kb3cpO1xuICB2YXIgbmF2aWdhdG9yID0gd2luZG93ICYmIHdpbmRvdy5uYXZpZ2F0b3I7XG5cbiAgdmFyIGNvbnN0cmFpbnRzVG9DaHJvbWVfID0gZnVuY3Rpb24oYykge1xuICAgIGlmICh0eXBlb2YgYyAhPT0gJ29iamVjdCcgfHwgYy5tYW5kYXRvcnkgfHwgYy5vcHRpb25hbCkge1xuICAgICAgcmV0dXJuIGM7XG4gICAgfVxuICAgIHZhciBjYyA9IHt9O1xuICAgIE9iamVjdC5rZXlzKGMpLmZvckVhY2goZnVuY3Rpb24oa2V5KSB7XG4gICAgICBpZiAoa2V5ID09PSAncmVxdWlyZScgfHwga2V5ID09PSAnYWR2YW5jZWQnIHx8IGtleSA9PT0gJ21lZGlhU291cmNlJykge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICB2YXIgciA9ICh0eXBlb2YgY1trZXldID09PSAnb2JqZWN0JykgPyBjW2tleV0gOiB7aWRlYWw6IGNba2V5XX07XG4gICAgICBpZiAoci5leGFjdCAhPT0gdW5kZWZpbmVkICYmIHR5cGVvZiByLmV4YWN0ID09PSAnbnVtYmVyJykge1xuICAgICAgICByLm1pbiA9IHIubWF4ID0gci5leGFjdDtcbiAgICAgIH1cbiAgICAgIHZhciBvbGRuYW1lXyA9IGZ1bmN0aW9uKHByZWZpeCwgbmFtZSkge1xuICAgICAgICBpZiAocHJlZml4KSB7XG4gICAgICAgICAgcmV0dXJuIHByZWZpeCArIG5hbWUuY2hhckF0KDApLnRvVXBwZXJDYXNlKCkgKyBuYW1lLnNsaWNlKDEpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiAobmFtZSA9PT0gJ2RldmljZUlkJykgPyAnc291cmNlSWQnIDogbmFtZTtcbiAgICAgIH07XG4gICAgICBpZiAoci5pZGVhbCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGNjLm9wdGlvbmFsID0gY2Mub3B0aW9uYWwgfHwgW107XG4gICAgICAgIHZhciBvYyA9IHt9O1xuICAgICAgICBpZiAodHlwZW9mIHIuaWRlYWwgPT09ICdudW1iZXInKSB7XG4gICAgICAgICAgb2Nbb2xkbmFtZV8oJ21pbicsIGtleSldID0gci5pZGVhbDtcbiAgICAgICAgICBjYy5vcHRpb25hbC5wdXNoKG9jKTtcbiAgICAgICAgICBvYyA9IHt9O1xuICAgICAgICAgIG9jW29sZG5hbWVfKCdtYXgnLCBrZXkpXSA9IHIuaWRlYWw7XG4gICAgICAgICAgY2Mub3B0aW9uYWwucHVzaChvYyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgb2Nbb2xkbmFtZV8oJycsIGtleSldID0gci5pZGVhbDtcbiAgICAgICAgICBjYy5vcHRpb25hbC5wdXNoKG9jKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKHIuZXhhY3QgIT09IHVuZGVmaW5lZCAmJiB0eXBlb2Ygci5leGFjdCAhPT0gJ251bWJlcicpIHtcbiAgICAgICAgY2MubWFuZGF0b3J5ID0gY2MubWFuZGF0b3J5IHx8IHt9O1xuICAgICAgICBjYy5tYW5kYXRvcnlbb2xkbmFtZV8oJycsIGtleSldID0gci5leGFjdDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIFsnbWluJywgJ21heCddLmZvckVhY2goZnVuY3Rpb24obWl4KSB7XG4gICAgICAgICAgaWYgKHJbbWl4XSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBjYy5tYW5kYXRvcnkgPSBjYy5tYW5kYXRvcnkgfHwge307XG4gICAgICAgICAgICBjYy5tYW5kYXRvcnlbb2xkbmFtZV8obWl4LCBrZXkpXSA9IHJbbWl4XTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0pO1xuICAgIGlmIChjLmFkdmFuY2VkKSB7XG4gICAgICBjYy5vcHRpb25hbCA9IChjYy5vcHRpb25hbCB8fCBbXSkuY29uY2F0KGMuYWR2YW5jZWQpO1xuICAgIH1cbiAgICByZXR1cm4gY2M7XG4gIH07XG5cbiAgdmFyIHNoaW1Db25zdHJhaW50c18gPSBmdW5jdGlvbihjb25zdHJhaW50cywgZnVuYykge1xuICAgIGNvbnN0cmFpbnRzID0gSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeShjb25zdHJhaW50cykpO1xuICAgIGlmIChjb25zdHJhaW50cyAmJiB0eXBlb2YgY29uc3RyYWludHMuYXVkaW8gPT09ICdvYmplY3QnKSB7XG4gICAgICB2YXIgcmVtYXAgPSBmdW5jdGlvbihvYmosIGEsIGIpIHtcbiAgICAgICAgaWYgKGEgaW4gb2JqICYmICEoYiBpbiBvYmopKSB7XG4gICAgICAgICAgb2JqW2JdID0gb2JqW2FdO1xuICAgICAgICAgIGRlbGV0ZSBvYmpbYV07XG4gICAgICAgIH1cbiAgICAgIH07XG4gICAgICBjb25zdHJhaW50cyA9IEpTT04ucGFyc2UoSlNPTi5zdHJpbmdpZnkoY29uc3RyYWludHMpKTtcbiAgICAgIHJlbWFwKGNvbnN0cmFpbnRzLmF1ZGlvLCAnYXV0b0dhaW5Db250cm9sJywgJ2dvb2dBdXRvR2FpbkNvbnRyb2wnKTtcbiAgICAgIHJlbWFwKGNvbnN0cmFpbnRzLmF1ZGlvLCAnbm9pc2VTdXBwcmVzc2lvbicsICdnb29nTm9pc2VTdXBwcmVzc2lvbicpO1xuICAgICAgY29uc3RyYWludHMuYXVkaW8gPSBjb25zdHJhaW50c1RvQ2hyb21lXyhjb25zdHJhaW50cy5hdWRpbyk7XG4gICAgfVxuICAgIGlmIChjb25zdHJhaW50cyAmJiB0eXBlb2YgY29uc3RyYWludHMudmlkZW8gPT09ICdvYmplY3QnKSB7XG4gICAgICAvLyBTaGltIGZhY2luZ01vZGUgZm9yIG1vYmlsZSAmIHN1cmZhY2UgcHJvLlxuICAgICAgdmFyIGZhY2UgPSBjb25zdHJhaW50cy52aWRlby5mYWNpbmdNb2RlO1xuICAgICAgZmFjZSA9IGZhY2UgJiYgKCh0eXBlb2YgZmFjZSA9PT0gJ29iamVjdCcpID8gZmFjZSA6IHtpZGVhbDogZmFjZX0pO1xuICAgICAgdmFyIGdldFN1cHBvcnRlZEZhY2luZ01vZGVMaWVzID0gYnJvd3NlckRldGFpbHMudmVyc2lvbiA8IDYxO1xuXG4gICAgICBpZiAoKGZhY2UgJiYgKGZhY2UuZXhhY3QgPT09ICd1c2VyJyB8fCBmYWNlLmV4YWN0ID09PSAnZW52aXJvbm1lbnQnIHx8XG4gICAgICAgICAgICAgICAgICAgIGZhY2UuaWRlYWwgPT09ICd1c2VyJyB8fCBmYWNlLmlkZWFsID09PSAnZW52aXJvbm1lbnQnKSkgJiZcbiAgICAgICAgICAhKG5hdmlnYXRvci5tZWRpYURldmljZXMuZ2V0U3VwcG9ydGVkQ29uc3RyYWludHMgJiZcbiAgICAgICAgICAgIG5hdmlnYXRvci5tZWRpYURldmljZXMuZ2V0U3VwcG9ydGVkQ29uc3RyYWludHMoKS5mYWNpbmdNb2RlICYmXG4gICAgICAgICAgICAhZ2V0U3VwcG9ydGVkRmFjaW5nTW9kZUxpZXMpKSB7XG4gICAgICAgIGRlbGV0ZSBjb25zdHJhaW50cy52aWRlby5mYWNpbmdNb2RlO1xuICAgICAgICB2YXIgbWF0Y2hlcztcbiAgICAgICAgaWYgKGZhY2UuZXhhY3QgPT09ICdlbnZpcm9ubWVudCcgfHwgZmFjZS5pZGVhbCA9PT0gJ2Vudmlyb25tZW50Jykge1xuICAgICAgICAgIG1hdGNoZXMgPSBbJ2JhY2snLCAncmVhciddO1xuICAgICAgICB9IGVsc2UgaWYgKGZhY2UuZXhhY3QgPT09ICd1c2VyJyB8fCBmYWNlLmlkZWFsID09PSAndXNlcicpIHtcbiAgICAgICAgICBtYXRjaGVzID0gWydmcm9udCddO1xuICAgICAgICB9XG4gICAgICAgIGlmIChtYXRjaGVzKSB7XG4gICAgICAgICAgLy8gTG9vayBmb3IgbWF0Y2hlcyBpbiBsYWJlbCwgb3IgdXNlIGxhc3QgY2FtIGZvciBiYWNrICh0eXBpY2FsKS5cbiAgICAgICAgICByZXR1cm4gbmF2aWdhdG9yLm1lZGlhRGV2aWNlcy5lbnVtZXJhdGVEZXZpY2VzKClcbiAgICAgICAgICAudGhlbihmdW5jdGlvbihkZXZpY2VzKSB7XG4gICAgICAgICAgICBkZXZpY2VzID0gZGV2aWNlcy5maWx0ZXIoZnVuY3Rpb24oZCkge1xuICAgICAgICAgICAgICByZXR1cm4gZC5raW5kID09PSAndmlkZW9pbnB1dCc7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHZhciBkZXYgPSBkZXZpY2VzLmZpbmQoZnVuY3Rpb24oZCkge1xuICAgICAgICAgICAgICByZXR1cm4gbWF0Y2hlcy5zb21lKGZ1bmN0aW9uKG1hdGNoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGQubGFiZWwudG9Mb3dlckNhc2UoKS5pbmRleE9mKG1hdGNoKSAhPT0gLTE7XG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBpZiAoIWRldiAmJiBkZXZpY2VzLmxlbmd0aCAmJiBtYXRjaGVzLmluZGV4T2YoJ2JhY2snKSAhPT0gLTEpIHtcbiAgICAgICAgICAgICAgZGV2ID0gZGV2aWNlc1tkZXZpY2VzLmxlbmd0aCAtIDFdOyAvLyBtb3JlIGxpa2VseSB0aGUgYmFjayBjYW1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChkZXYpIHtcbiAgICAgICAgICAgICAgY29uc3RyYWludHMudmlkZW8uZGV2aWNlSWQgPSBmYWNlLmV4YWN0ID8ge2V4YWN0OiBkZXYuZGV2aWNlSWR9IDpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge2lkZWFsOiBkZXYuZGV2aWNlSWR9O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3RyYWludHMudmlkZW8gPSBjb25zdHJhaW50c1RvQ2hyb21lXyhjb25zdHJhaW50cy52aWRlbyk7XG4gICAgICAgICAgICBsb2dnaW5nKCdjaHJvbWU6ICcgKyBKU09OLnN0cmluZ2lmeShjb25zdHJhaW50cykpO1xuICAgICAgICAgICAgcmV0dXJuIGZ1bmMoY29uc3RyYWludHMpO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBjb25zdHJhaW50cy52aWRlbyA9IGNvbnN0cmFpbnRzVG9DaHJvbWVfKGNvbnN0cmFpbnRzLnZpZGVvKTtcbiAgICB9XG4gICAgbG9nZ2luZygnY2hyb21lOiAnICsgSlNPTi5zdHJpbmdpZnkoY29uc3RyYWludHMpKTtcbiAgICByZXR1cm4gZnVuYyhjb25zdHJhaW50cyk7XG4gIH07XG5cbiAgdmFyIHNoaW1FcnJvcl8gPSBmdW5jdGlvbihlKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIG5hbWU6IHtcbiAgICAgICAgUGVybWlzc2lvbkRlbmllZEVycm9yOiAnTm90QWxsb3dlZEVycm9yJyxcbiAgICAgICAgSW52YWxpZFN0YXRlRXJyb3I6ICdOb3RSZWFkYWJsZUVycm9yJyxcbiAgICAgICAgRGV2aWNlc05vdEZvdW5kRXJyb3I6ICdOb3RGb3VuZEVycm9yJyxcbiAgICAgICAgQ29uc3RyYWludE5vdFNhdGlzZmllZEVycm9yOiAnT3ZlcmNvbnN0cmFpbmVkRXJyb3InLFxuICAgICAgICBUcmFja1N0YXJ0RXJyb3I6ICdOb3RSZWFkYWJsZUVycm9yJyxcbiAgICAgICAgTWVkaWFEZXZpY2VGYWlsZWREdWVUb1NodXRkb3duOiAnTm90UmVhZGFibGVFcnJvcicsXG4gICAgICAgIE1lZGlhRGV2aWNlS2lsbFN3aXRjaE9uOiAnTm90UmVhZGFibGVFcnJvcidcbiAgICAgIH1bZS5uYW1lXSB8fCBlLm5hbWUsXG4gICAgICBtZXNzYWdlOiBlLm1lc3NhZ2UsXG4gICAgICBjb25zdHJhaW50OiBlLmNvbnN0cmFpbnROYW1lLFxuICAgICAgdG9TdHJpbmc6IGZ1bmN0aW9uKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5uYW1lICsgKHRoaXMubWVzc2FnZSAmJiAnOiAnKSArIHRoaXMubWVzc2FnZTtcbiAgICAgIH1cbiAgICB9O1xuICB9O1xuXG4gIHZhciBnZXRVc2VyTWVkaWFfID0gZnVuY3Rpb24oY29uc3RyYWludHMsIG9uU3VjY2Vzcywgb25FcnJvcikge1xuICAgIHNoaW1Db25zdHJhaW50c18oY29uc3RyYWludHMsIGZ1bmN0aW9uKGMpIHtcbiAgICAgIG5hdmlnYXRvci53ZWJraXRHZXRVc2VyTWVkaWEoYywgb25TdWNjZXNzLCBmdW5jdGlvbihlKSB7XG4gICAgICAgIGlmIChvbkVycm9yKSB7XG4gICAgICAgICAgb25FcnJvcihzaGltRXJyb3JfKGUpKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfSk7XG4gIH07XG5cbiAgbmF2aWdhdG9yLmdldFVzZXJNZWRpYSA9IGdldFVzZXJNZWRpYV87XG5cbiAgLy8gUmV0dXJucyB0aGUgcmVzdWx0IG9mIGdldFVzZXJNZWRpYSBhcyBhIFByb21pc2UuXG4gIHZhciBnZXRVc2VyTWVkaWFQcm9taXNlXyA9IGZ1bmN0aW9uKGNvbnN0cmFpbnRzKSB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uKHJlc29sdmUsIHJlamVjdCkge1xuICAgICAgbmF2aWdhdG9yLmdldFVzZXJNZWRpYShjb25zdHJhaW50cywgcmVzb2x2ZSwgcmVqZWN0KTtcbiAgICB9KTtcbiAgfTtcblxuICBpZiAoIW5hdmlnYXRvci5tZWRpYURldmljZXMpIHtcbiAgICBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzID0ge1xuICAgICAgZ2V0VXNlck1lZGlhOiBnZXRVc2VyTWVkaWFQcm9taXNlXyxcbiAgICAgIGVudW1lcmF0ZURldmljZXM6IGZ1bmN0aW9uKCkge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24ocmVzb2x2ZSkge1xuICAgICAgICAgIHZhciBraW5kcyA9IHthdWRpbzogJ2F1ZGlvaW5wdXQnLCB2aWRlbzogJ3ZpZGVvaW5wdXQnfTtcbiAgICAgICAgICByZXR1cm4gd2luZG93Lk1lZGlhU3RyZWFtVHJhY2suZ2V0U291cmNlcyhmdW5jdGlvbihkZXZpY2VzKSB7XG4gICAgICAgICAgICByZXNvbHZlKGRldmljZXMubWFwKGZ1bmN0aW9uKGRldmljZSkge1xuICAgICAgICAgICAgICByZXR1cm4ge2xhYmVsOiBkZXZpY2UubGFiZWwsXG4gICAgICAgICAgICAgICAga2luZDoga2luZHNbZGV2aWNlLmtpbmRdLFxuICAgICAgICAgICAgICAgIGRldmljZUlkOiBkZXZpY2UuaWQsXG4gICAgICAgICAgICAgICAgZ3JvdXBJZDogJyd9O1xuICAgICAgICAgICAgfSkpO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICAgIH0sXG4gICAgICBnZXRTdXBwb3J0ZWRDb25zdHJhaW50czogZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgZGV2aWNlSWQ6IHRydWUsIGVjaG9DYW5jZWxsYXRpb246IHRydWUsIGZhY2luZ01vZGU6IHRydWUsXG4gICAgICAgICAgZnJhbWVSYXRlOiB0cnVlLCBoZWlnaHQ6IHRydWUsIHdpZHRoOiB0cnVlXG4gICAgICAgIH07XG4gICAgICB9XG4gICAgfTtcbiAgfVxuXG4gIC8vIEEgc2hpbSBmb3IgZ2V0VXNlck1lZGlhIG1ldGhvZCBvbiB0aGUgbWVkaWFEZXZpY2VzIG9iamVjdC5cbiAgLy8gVE9ETyhLYXB0ZW5KYW5zc29uKSByZW1vdmUgb25jZSBpbXBsZW1lbnRlZCBpbiBDaHJvbWUgc3RhYmxlLlxuICBpZiAoIW5hdmlnYXRvci5tZWRpYURldmljZXMuZ2V0VXNlck1lZGlhKSB7XG4gICAgbmF2aWdhdG9yLm1lZGlhRGV2aWNlcy5nZXRVc2VyTWVkaWEgPSBmdW5jdGlvbihjb25zdHJhaW50cykge1xuICAgICAgcmV0dXJuIGdldFVzZXJNZWRpYVByb21pc2VfKGNvbnN0cmFpbnRzKTtcbiAgICB9O1xuICB9IGVsc2Uge1xuICAgIC8vIEV2ZW4gdGhvdWdoIENocm9tZSA0NSBoYXMgbmF2aWdhdG9yLm1lZGlhRGV2aWNlcyBhbmQgYSBnZXRVc2VyTWVkaWFcbiAgICAvLyBmdW5jdGlvbiB3aGljaCByZXR1cm5zIGEgUHJvbWlzZSwgaXQgZG9lcyBub3QgYWNjZXB0IHNwZWMtc3R5bGVcbiAgICAvLyBjb25zdHJhaW50cy5cbiAgICB2YXIgb3JpZ0dldFVzZXJNZWRpYSA9IG5hdmlnYXRvci5tZWRpYURldmljZXMuZ2V0VXNlck1lZGlhLlxuICAgICAgICBiaW5kKG5hdmlnYXRvci5tZWRpYURldmljZXMpO1xuICAgIG5hdmlnYXRvci5tZWRpYURldmljZXMuZ2V0VXNlck1lZGlhID0gZnVuY3Rpb24oY3MpIHtcbiAgICAgIHJldHVybiBzaGltQ29uc3RyYWludHNfKGNzLCBmdW5jdGlvbihjKSB7XG4gICAgICAgIHJldHVybiBvcmlnR2V0VXNlck1lZGlhKGMpLnRoZW4oZnVuY3Rpb24oc3RyZWFtKSB7XG4gICAgICAgICAgaWYgKGMuYXVkaW8gJiYgIXN0cmVhbS5nZXRBdWRpb1RyYWNrcygpLmxlbmd0aCB8fFxuICAgICAgICAgICAgICBjLnZpZGVvICYmICFzdHJlYW0uZ2V0VmlkZW9UcmFja3MoKS5sZW5ndGgpIHtcbiAgICAgICAgICAgIHN0cmVhbS5nZXRUcmFja3MoKS5mb3JFYWNoKGZ1bmN0aW9uKHRyYWNrKSB7XG4gICAgICAgICAgICAgIHRyYWNrLnN0b3AoKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbignJywgJ05vdEZvdW5kRXJyb3InKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIHN0cmVhbTtcbiAgICAgICAgfSwgZnVuY3Rpb24oZSkge1xuICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChzaGltRXJyb3JfKGUpKTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICB9O1xuICB9XG5cbiAgLy8gRHVtbXkgZGV2aWNlY2hhbmdlIGV2ZW50IG1ldGhvZHMuXG4gIC8vIFRPRE8oS2FwdGVuSmFuc3NvbikgcmVtb3ZlIG9uY2UgaW1wbGVtZW50ZWQgaW4gQ2hyb21lIHN0YWJsZS5cbiAgaWYgKHR5cGVvZiBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmFkZEV2ZW50TGlzdGVuZXIgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgbmF2aWdhdG9yLm1lZGlhRGV2aWNlcy5hZGRFdmVudExpc3RlbmVyID0gZnVuY3Rpb24oKSB7XG4gICAgICBsb2dnaW5nKCdEdW1teSBtZWRpYURldmljZXMuYWRkRXZlbnRMaXN0ZW5lciBjYWxsZWQuJyk7XG4gICAgfTtcbiAgfVxuICBpZiAodHlwZW9mIG5hdmlnYXRvci5tZWRpYURldmljZXMucmVtb3ZlRXZlbnRMaXN0ZW5lciA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLnJlbW92ZUV2ZW50TGlzdGVuZXIgPSBmdW5jdGlvbigpIHtcbiAgICAgIGxvZ2dpbmcoJ0R1bW15IG1lZGlhRGV2aWNlcy5yZW1vdmVFdmVudExpc3RlbmVyIGNhbGxlZC4nKTtcbiAgICB9O1xuICB9XG59O1xuIiwiLypcbiAqICBDb3B5cmlnaHQgKGMpIDIwMTcgVGhlIFdlYlJUQyBwcm9qZWN0IGF1dGhvcnMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKlxuICogIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2VcbiAqICB0aGF0IGNhbiBiZSBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlIGluIHRoZSByb290IG9mIHRoZSBzb3VyY2VcbiAqICB0cmVlLlxuICovXG4gLyogZXNsaW50LWVudiBub2RlICovXG4ndXNlIHN0cmljdCc7XG5cbnZhciBTRFBVdGlscyA9IHJlcXVpcmUoJ3NkcCcpO1xudmFyIHV0aWxzID0gcmVxdWlyZSgnLi91dGlscycpO1xuXG4vLyBXcmFwcyB0aGUgcGVlcmNvbm5lY3Rpb24gZXZlbnQgZXZlbnROYW1lVG9XcmFwIGluIGEgZnVuY3Rpb25cbi8vIHdoaWNoIHJldHVybnMgdGhlIG1vZGlmaWVkIGV2ZW50IG9iamVjdC5cbmZ1bmN0aW9uIHdyYXBQZWVyQ29ubmVjdGlvbkV2ZW50KHdpbmRvdywgZXZlbnROYW1lVG9XcmFwLCB3cmFwcGVyKSB7XG4gIGlmICghd2luZG93LlJUQ1BlZXJDb25uZWN0aW9uKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIHZhciBwcm90byA9IHdpbmRvdy5SVENQZWVyQ29ubmVjdGlvbi5wcm90b3R5cGU7XG4gIHZhciBuYXRpdmVBZGRFdmVudExpc3RlbmVyID0gcHJvdG8uYWRkRXZlbnRMaXN0ZW5lcjtcbiAgcHJvdG8uYWRkRXZlbnRMaXN0ZW5lciA9IGZ1bmN0aW9uKG5hdGl2ZUV2ZW50TmFtZSwgY2IpIHtcbiAgICBpZiAobmF0aXZlRXZlbnROYW1lICE9PSBldmVudE5hbWVUb1dyYXApIHtcbiAgICAgIHJldHVybiBuYXRpdmVBZGRFdmVudExpc3RlbmVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgfVxuICAgIHZhciB3cmFwcGVkQ2FsbGJhY2sgPSBmdW5jdGlvbihlKSB7XG4gICAgICBjYih3cmFwcGVyKGUpKTtcbiAgICB9O1xuICAgIHRoaXMuX2V2ZW50TWFwID0gdGhpcy5fZXZlbnRNYXAgfHwge307XG4gICAgdGhpcy5fZXZlbnRNYXBbY2JdID0gd3JhcHBlZENhbGxiYWNrO1xuICAgIHJldHVybiBuYXRpdmVBZGRFdmVudExpc3RlbmVyLmFwcGx5KHRoaXMsIFtuYXRpdmVFdmVudE5hbWUsXG4gICAgICB3cmFwcGVkQ2FsbGJhY2tdKTtcbiAgfTtcblxuICB2YXIgbmF0aXZlUmVtb3ZlRXZlbnRMaXN0ZW5lciA9IHByb3RvLnJlbW92ZUV2ZW50TGlzdGVuZXI7XG4gIHByb3RvLnJlbW92ZUV2ZW50TGlzdGVuZXIgPSBmdW5jdGlvbihuYXRpdmVFdmVudE5hbWUsIGNiKSB7XG4gICAgaWYgKG5hdGl2ZUV2ZW50TmFtZSAhPT0gZXZlbnROYW1lVG9XcmFwIHx8ICF0aGlzLl9ldmVudE1hcFxuICAgICAgICB8fCAhdGhpcy5fZXZlbnRNYXBbY2JdKSB7XG4gICAgICByZXR1cm4gbmF0aXZlUmVtb3ZlRXZlbnRMaXN0ZW5lci5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIH1cbiAgICB2YXIgdW53cmFwcGVkQ2IgPSB0aGlzLl9ldmVudE1hcFtjYl07XG4gICAgZGVsZXRlIHRoaXMuX2V2ZW50TWFwW2NiXTtcbiAgICByZXR1cm4gbmF0aXZlUmVtb3ZlRXZlbnRMaXN0ZW5lci5hcHBseSh0aGlzLCBbbmF0aXZlRXZlbnROYW1lLFxuICAgICAgdW53cmFwcGVkQ2JdKTtcbiAgfTtcblxuICBPYmplY3QuZGVmaW5lUHJvcGVydHkocHJvdG8sICdvbicgKyBldmVudE5hbWVUb1dyYXAsIHtcbiAgICBnZXQ6IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHRoaXNbJ19vbicgKyBldmVudE5hbWVUb1dyYXBdO1xuICAgIH0sXG4gICAgc2V0OiBmdW5jdGlvbihjYikge1xuICAgICAgaWYgKHRoaXNbJ19vbicgKyBldmVudE5hbWVUb1dyYXBdKSB7XG4gICAgICAgIHRoaXMucmVtb3ZlRXZlbnRMaXN0ZW5lcihldmVudE5hbWVUb1dyYXAsXG4gICAgICAgICAgICB0aGlzWydfb24nICsgZXZlbnROYW1lVG9XcmFwXSk7XG4gICAgICAgIGRlbGV0ZSB0aGlzWydfb24nICsgZXZlbnROYW1lVG9XcmFwXTtcbiAgICAgIH1cbiAgICAgIGlmIChjYikge1xuICAgICAgICB0aGlzLmFkZEV2ZW50TGlzdGVuZXIoZXZlbnROYW1lVG9XcmFwLFxuICAgICAgICAgICAgdGhpc1snX29uJyArIGV2ZW50TmFtZVRvV3JhcF0gPSBjYik7XG4gICAgICB9XG4gICAgfVxuICB9KTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIHNoaW1SVENJY2VDYW5kaWRhdGU6IGZ1bmN0aW9uKHdpbmRvdykge1xuICAgIC8vIGZvdW5kYXRpb24gaXMgYXJiaXRyYXJpbHkgY2hvc2VuIGFzIGFuIGluZGljYXRvciBmb3IgZnVsbCBzdXBwb3J0IGZvclxuICAgIC8vIGh0dHBzOi8vdzNjLmdpdGh1Yi5pby93ZWJydGMtcGMvI3J0Y2ljZWNhbmRpZGF0ZS1pbnRlcmZhY2VcbiAgICBpZiAod2luZG93LlJUQ0ljZUNhbmRpZGF0ZSAmJiAnZm91bmRhdGlvbicgaW5cbiAgICAgICAgd2luZG93LlJUQ0ljZUNhbmRpZGF0ZS5wcm90b3R5cGUpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB2YXIgTmF0aXZlUlRDSWNlQ2FuZGlkYXRlID0gd2luZG93LlJUQ0ljZUNhbmRpZGF0ZTtcbiAgICB3aW5kb3cuUlRDSWNlQ2FuZGlkYXRlID0gZnVuY3Rpb24oYXJncykge1xuICAgICAgLy8gUmVtb3ZlIHRoZSBhPSB3aGljaCBzaG91bGRuJ3QgYmUgcGFydCBvZiB0aGUgY2FuZGlkYXRlIHN0cmluZy5cbiAgICAgIGlmICh0eXBlb2YgYXJncyA9PT0gJ29iamVjdCcgJiYgYXJncy5jYW5kaWRhdGUgJiZcbiAgICAgICAgICBhcmdzLmNhbmRpZGF0ZS5pbmRleE9mKCdhPScpID09PSAwKSB7XG4gICAgICAgIGFyZ3MgPSBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KGFyZ3MpKTtcbiAgICAgICAgYXJncy5jYW5kaWRhdGUgPSBhcmdzLmNhbmRpZGF0ZS5zdWJzdHIoMik7XG4gICAgICB9XG5cbiAgICAgIC8vIEF1Z21lbnQgdGhlIG5hdGl2ZSBjYW5kaWRhdGUgd2l0aCB0aGUgcGFyc2VkIGZpZWxkcy5cbiAgICAgIHZhciBuYXRpdmVDYW5kaWRhdGUgPSBuZXcgTmF0aXZlUlRDSWNlQ2FuZGlkYXRlKGFyZ3MpO1xuICAgICAgdmFyIHBhcnNlZENhbmRpZGF0ZSA9IFNEUFV0aWxzLnBhcnNlQ2FuZGlkYXRlKGFyZ3MuY2FuZGlkYXRlKTtcbiAgICAgIHZhciBhdWdtZW50ZWRDYW5kaWRhdGUgPSBPYmplY3QuYXNzaWduKG5hdGl2ZUNhbmRpZGF0ZSxcbiAgICAgICAgICBwYXJzZWRDYW5kaWRhdGUpO1xuXG4gICAgICAvLyBBZGQgYSBzZXJpYWxpemVyIHRoYXQgZG9lcyBub3Qgc2VyaWFsaXplIHRoZSBleHRyYSBhdHRyaWJ1dGVzLlxuICAgICAgYXVnbWVudGVkQ2FuZGlkYXRlLnRvSlNPTiA9IGZ1bmN0aW9uKCkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIGNhbmRpZGF0ZTogYXVnbWVudGVkQ2FuZGlkYXRlLmNhbmRpZGF0ZSxcbiAgICAgICAgICBzZHBNaWQ6IGF1Z21lbnRlZENhbmRpZGF0ZS5zZHBNaWQsXG4gICAgICAgICAgc2RwTUxpbmVJbmRleDogYXVnbWVudGVkQ2FuZGlkYXRlLnNkcE1MaW5lSW5kZXgsXG4gICAgICAgICAgdXNlcm5hbWVGcmFnbWVudDogYXVnbWVudGVkQ2FuZGlkYXRlLnVzZXJuYW1lRnJhZ21lbnQsXG4gICAgICAgIH07XG4gICAgICB9O1xuICAgICAgcmV0dXJuIGF1Z21lbnRlZENhbmRpZGF0ZTtcbiAgICB9O1xuXG4gICAgLy8gSG9vayB1cCB0aGUgYXVnbWVudGVkIGNhbmRpZGF0ZSBpbiBvbmljZWNhbmRpZGF0ZSBhbmRcbiAgICAvLyBhZGRFdmVudExpc3RlbmVyKCdpY2VjYW5kaWRhdGUnLCAuLi4pXG4gICAgd3JhcFBlZXJDb25uZWN0aW9uRXZlbnQod2luZG93LCAnaWNlY2FuZGlkYXRlJywgZnVuY3Rpb24oZSkge1xuICAgICAgaWYgKGUuY2FuZGlkYXRlKSB7XG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShlLCAnY2FuZGlkYXRlJywge1xuICAgICAgICAgIHZhbHVlOiBuZXcgd2luZG93LlJUQ0ljZUNhbmRpZGF0ZShlLmNhbmRpZGF0ZSksXG4gICAgICAgICAgd3JpdGFibGU6ICdmYWxzZSdcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gZTtcbiAgICB9KTtcbiAgfSxcblxuICAvLyBzaGltQ3JlYXRlT2JqZWN0VVJMIG11c3QgYmUgY2FsbGVkIGJlZm9yZSBzaGltU291cmNlT2JqZWN0IHRvIGF2b2lkIGxvb3AuXG5cbiAgc2hpbUNyZWF0ZU9iamVjdFVSTDogZnVuY3Rpb24od2luZG93KSB7XG4gICAgdmFyIFVSTCA9IHdpbmRvdyAmJiB3aW5kb3cuVVJMO1xuXG4gICAgaWYgKCEodHlwZW9mIHdpbmRvdyA9PT0gJ29iamVjdCcgJiYgd2luZG93LkhUTUxNZWRpYUVsZW1lbnQgJiZcbiAgICAgICAgICAnc3JjT2JqZWN0JyBpbiB3aW5kb3cuSFRNTE1lZGlhRWxlbWVudC5wcm90b3R5cGUgJiZcbiAgICAgICAgVVJMLmNyZWF0ZU9iamVjdFVSTCAmJiBVUkwucmV2b2tlT2JqZWN0VVJMKSkge1xuICAgICAgLy8gT25seSBzaGltIENyZWF0ZU9iamVjdFVSTCB1c2luZyBzcmNPYmplY3QgaWYgc3JjT2JqZWN0IGV4aXN0cy5cbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgdmFyIG5hdGl2ZUNyZWF0ZU9iamVjdFVSTCA9IFVSTC5jcmVhdGVPYmplY3RVUkwuYmluZChVUkwpO1xuICAgIHZhciBuYXRpdmVSZXZva2VPYmplY3RVUkwgPSBVUkwucmV2b2tlT2JqZWN0VVJMLmJpbmQoVVJMKTtcbiAgICB2YXIgc3RyZWFtcyA9IG5ldyBNYXAoKSwgbmV3SWQgPSAwO1xuXG4gICAgVVJMLmNyZWF0ZU9iamVjdFVSTCA9IGZ1bmN0aW9uKHN0cmVhbSkge1xuICAgICAgaWYgKCdnZXRUcmFja3MnIGluIHN0cmVhbSkge1xuICAgICAgICB2YXIgdXJsID0gJ3BvbHlibG9iOicgKyAoKytuZXdJZCk7XG4gICAgICAgIHN0cmVhbXMuc2V0KHVybCwgc3RyZWFtKTtcbiAgICAgICAgdXRpbHMuZGVwcmVjYXRlZCgnVVJMLmNyZWF0ZU9iamVjdFVSTChzdHJlYW0pJyxcbiAgICAgICAgICAgICdlbGVtLnNyY09iamVjdCA9IHN0cmVhbScpO1xuICAgICAgICByZXR1cm4gdXJsO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG5hdGl2ZUNyZWF0ZU9iamVjdFVSTChzdHJlYW0pO1xuICAgIH07XG4gICAgVVJMLnJldm9rZU9iamVjdFVSTCA9IGZ1bmN0aW9uKHVybCkge1xuICAgICAgbmF0aXZlUmV2b2tlT2JqZWN0VVJMKHVybCk7XG4gICAgICBzdHJlYW1zLmRlbGV0ZSh1cmwpO1xuICAgIH07XG5cbiAgICB2YXIgZHNjID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcih3aW5kb3cuSFRNTE1lZGlhRWxlbWVudC5wcm90b3R5cGUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3NyYycpO1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh3aW5kb3cuSFRNTE1lZGlhRWxlbWVudC5wcm90b3R5cGUsICdzcmMnLCB7XG4gICAgICBnZXQ6IGZ1bmN0aW9uKCkge1xuICAgICAgICByZXR1cm4gZHNjLmdldC5hcHBseSh0aGlzKTtcbiAgICAgIH0sXG4gICAgICBzZXQ6IGZ1bmN0aW9uKHVybCkge1xuICAgICAgICB0aGlzLnNyY09iamVjdCA9IHN0cmVhbXMuZ2V0KHVybCkgfHwgbnVsbDtcbiAgICAgICAgcmV0dXJuIGRzYy5zZXQuYXBwbHkodGhpcywgW3VybF0pO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgdmFyIG5hdGl2ZVNldEF0dHJpYnV0ZSA9IHdpbmRvdy5IVE1MTWVkaWFFbGVtZW50LnByb3RvdHlwZS5zZXRBdHRyaWJ1dGU7XG4gICAgd2luZG93LkhUTUxNZWRpYUVsZW1lbnQucHJvdG90eXBlLnNldEF0dHJpYnV0ZSA9IGZ1bmN0aW9uKCkge1xuICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDIgJiZcbiAgICAgICAgICAoJycgKyBhcmd1bWVudHNbMF0pLnRvTG93ZXJDYXNlKCkgPT09ICdzcmMnKSB7XG4gICAgICAgIHRoaXMuc3JjT2JqZWN0ID0gc3RyZWFtcy5nZXQoYXJndW1lbnRzWzFdKSB8fCBudWxsO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG5hdGl2ZVNldEF0dHJpYnV0ZS5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIH07XG4gIH1cbn07XG4iLCIvKlxuICogIENvcHlyaWdodCAoYykgMjAxNiBUaGUgV2ViUlRDIHByb2plY3QgYXV0aG9ycy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqXG4gKiAgVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZVxuICogIHRoYXQgY2FuIGJlIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgaW4gdGhlIHJvb3Qgb2YgdGhlIHNvdXJjZVxuICogIHRyZWUuXG4gKi9cbiAvKiBlc2xpbnQtZW52IG5vZGUgKi9cbid1c2Ugc3RyaWN0JztcblxudmFyIHV0aWxzID0gcmVxdWlyZSgnLi4vdXRpbHMnKTtcbnZhciBzaGltUlRDUGVlckNvbm5lY3Rpb24gPSByZXF1aXJlKCdydGNwZWVyY29ubmVjdGlvbi1zaGltJyk7XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBzaGltR2V0VXNlck1lZGlhOiByZXF1aXJlKCcuL2dldHVzZXJtZWRpYScpLFxuICBzaGltUGVlckNvbm5lY3Rpb246IGZ1bmN0aW9uKHdpbmRvdykge1xuICAgIHZhciBicm93c2VyRGV0YWlscyA9IHV0aWxzLmRldGVjdEJyb3dzZXIod2luZG93KTtcblxuICAgIGlmICh3aW5kb3cuUlRDSWNlR2F0aGVyZXIpIHtcbiAgICAgIC8vIE9SVEMgZGVmaW5lcyBhbiBSVENJY2VDYW5kaWRhdGUgb2JqZWN0IGJ1dCBubyBjb25zdHJ1Y3Rvci5cbiAgICAgIC8vIE5vdCBpbXBsZW1lbnRlZCBpbiBFZGdlLlxuICAgICAgaWYgKCF3aW5kb3cuUlRDSWNlQ2FuZGlkYXRlKSB7XG4gICAgICAgIHdpbmRvdy5SVENJY2VDYW5kaWRhdGUgPSBmdW5jdGlvbihhcmdzKSB7XG4gICAgICAgICAgcmV0dXJuIGFyZ3M7XG4gICAgICAgIH07XG4gICAgICB9XG4gICAgICAvLyBPUlRDIGRvZXMgbm90IGhhdmUgYSBzZXNzaW9uIGRlc2NyaXB0aW9uIG9iamVjdCBidXRcbiAgICAgIC8vIG90aGVyIGJyb3dzZXJzIChpLmUuIENocm9tZSkgdGhhdCB3aWxsIHN1cHBvcnQgYm90aCBQQyBhbmQgT1JUQ1xuICAgICAgLy8gaW4gdGhlIGZ1dHVyZSBtaWdodCBoYXZlIHRoaXMgZGVmaW5lZCBhbHJlYWR5LlxuICAgICAgaWYgKCF3aW5kb3cuUlRDU2Vzc2lvbkRlc2NyaXB0aW9uKSB7XG4gICAgICAgIHdpbmRvdy5SVENTZXNzaW9uRGVzY3JpcHRpb24gPSBmdW5jdGlvbihhcmdzKSB7XG4gICAgICAgICAgcmV0dXJuIGFyZ3M7XG4gICAgICAgIH07XG4gICAgICB9XG4gICAgICAvLyB0aGlzIGFkZHMgYW4gYWRkaXRpb25hbCBldmVudCBsaXN0ZW5lciB0byBNZWRpYVN0cmFja1RyYWNrIHRoYXQgc2lnbmFsc1xuICAgICAgLy8gd2hlbiBhIHRyYWNrcyBlbmFibGVkIHByb3BlcnR5IHdhcyBjaGFuZ2VkLiBXb3JrYXJvdW5kIGZvciBhIGJ1ZyBpblxuICAgICAgLy8gYWRkU3RyZWFtLCBzZWUgYmVsb3cuIE5vIGxvbmdlciByZXF1aXJlZCBpbiAxNTAyNStcbiAgICAgIGlmIChicm93c2VyRGV0YWlscy52ZXJzaW9uIDwgMTUwMjUpIHtcbiAgICAgICAgdmFyIG9yaWdNU1RFbmFibGVkID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihcbiAgICAgICAgICAgIHdpbmRvdy5NZWRpYVN0cmVhbVRyYWNrLnByb3RvdHlwZSwgJ2VuYWJsZWQnKTtcbiAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHdpbmRvdy5NZWRpYVN0cmVhbVRyYWNrLnByb3RvdHlwZSwgJ2VuYWJsZWQnLCB7XG4gICAgICAgICAgc2V0OiBmdW5jdGlvbih2YWx1ZSkge1xuICAgICAgICAgICAgb3JpZ01TVEVuYWJsZWQuc2V0LmNhbGwodGhpcywgdmFsdWUpO1xuICAgICAgICAgICAgdmFyIGV2ID0gbmV3IEV2ZW50KCdlbmFibGVkJyk7XG4gICAgICAgICAgICBldi5lbmFibGVkID0gdmFsdWU7XG4gICAgICAgICAgICB0aGlzLmRpc3BhdGNoRXZlbnQoZXYpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gT1JUQyBkZWZpbmVzIHRoZSBEVE1GIHNlbmRlciBhIGJpdCBkaWZmZXJlbnQuXG4gICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL3czYy9vcnRjL2lzc3Vlcy83MTRcbiAgICBpZiAod2luZG93LlJUQ1J0cFNlbmRlciAmJiAhKCdkdG1mJyBpbiB3aW5kb3cuUlRDUnRwU2VuZGVyLnByb3RvdHlwZSkpIHtcbiAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh3aW5kb3cuUlRDUnRwU2VuZGVyLnByb3RvdHlwZSwgJ2R0bWYnLCB7XG4gICAgICAgIGdldDogZnVuY3Rpb24oKSB7XG4gICAgICAgICAgaWYgKHRoaXMuX2R0bWYgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgaWYgKHRoaXMudHJhY2sua2luZCA9PT0gJ2F1ZGlvJykge1xuICAgICAgICAgICAgICB0aGlzLl9kdG1mID0gbmV3IHdpbmRvdy5SVENEdG1mU2VuZGVyKHRoaXMpO1xuICAgICAgICAgICAgfSBlbHNlIGlmICh0aGlzLnRyYWNrLmtpbmQgPT09ICd2aWRlbycpIHtcbiAgICAgICAgICAgICAgdGhpcy5fZHRtZiA9IG51bGw7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiB0aGlzLl9kdG1mO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICB3aW5kb3cuUlRDUGVlckNvbm5lY3Rpb24gPVxuICAgICAgICBzaGltUlRDUGVlckNvbm5lY3Rpb24od2luZG93LCBicm93c2VyRGV0YWlscy52ZXJzaW9uKTtcbiAgfSxcbiAgc2hpbVJlcGxhY2VUcmFjazogZnVuY3Rpb24od2luZG93KSB7XG4gICAgLy8gT1JUQyBoYXMgcmVwbGFjZVRyYWNrIC0tIGh0dHBzOi8vZ2l0aHViLmNvbS93M2Mvb3J0Yy9pc3N1ZXMvNjE0XG4gICAgaWYgKHdpbmRvdy5SVENSdHBTZW5kZXIgJiZcbiAgICAgICAgISgncmVwbGFjZVRyYWNrJyBpbiB3aW5kb3cuUlRDUnRwU2VuZGVyLnByb3RvdHlwZSkpIHtcbiAgICAgIHdpbmRvdy5SVENSdHBTZW5kZXIucHJvdG90eXBlLnJlcGxhY2VUcmFjayA9XG4gICAgICAgICAgd2luZG93LlJUQ1J0cFNlbmRlci5wcm90b3R5cGUuc2V0VHJhY2s7XG4gICAgfVxuICB9XG59O1xuIiwiLypcbiAqICBDb3B5cmlnaHQgKGMpIDIwMTYgVGhlIFdlYlJUQyBwcm9qZWN0IGF1dGhvcnMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKlxuICogIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2VcbiAqICB0aGF0IGNhbiBiZSBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlIGluIHRoZSByb290IG9mIHRoZSBzb3VyY2VcbiAqICB0cmVlLlxuICovXG4gLyogZXNsaW50LWVudiBub2RlICovXG4ndXNlIHN0cmljdCc7XG5cbi8vIEV4cG9zZSBwdWJsaWMgbWV0aG9kcy5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24od2luZG93KSB7XG4gIHZhciBuYXZpZ2F0b3IgPSB3aW5kb3cgJiYgd2luZG93Lm5hdmlnYXRvcjtcblxuICB2YXIgc2hpbUVycm9yXyA9IGZ1bmN0aW9uKGUpIHtcbiAgICByZXR1cm4ge1xuICAgICAgbmFtZToge1Blcm1pc3Npb25EZW5pZWRFcnJvcjogJ05vdEFsbG93ZWRFcnJvcid9W2UubmFtZV0gfHwgZS5uYW1lLFxuICAgICAgbWVzc2FnZTogZS5tZXNzYWdlLFxuICAgICAgY29uc3RyYWludDogZS5jb25zdHJhaW50LFxuICAgICAgdG9TdHJpbmc6IGZ1bmN0aW9uKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5uYW1lO1xuICAgICAgfVxuICAgIH07XG4gIH07XG5cbiAgLy8gZ2V0VXNlck1lZGlhIGVycm9yIHNoaW0uXG4gIHZhciBvcmlnR2V0VXNlck1lZGlhID0gbmF2aWdhdG9yLm1lZGlhRGV2aWNlcy5nZXRVc2VyTWVkaWEuXG4gICAgICBiaW5kKG5hdmlnYXRvci5tZWRpYURldmljZXMpO1xuICBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmdldFVzZXJNZWRpYSA9IGZ1bmN0aW9uKGMpIHtcbiAgICByZXR1cm4gb3JpZ0dldFVzZXJNZWRpYShjKS5jYXRjaChmdW5jdGlvbihlKSB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3Qoc2hpbUVycm9yXyhlKSk7XG4gICAgfSk7XG4gIH07XG59O1xuIiwiLypcbiAqICBDb3B5cmlnaHQgKGMpIDIwMTYgVGhlIFdlYlJUQyBwcm9qZWN0IGF1dGhvcnMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKlxuICogIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2VcbiAqICB0aGF0IGNhbiBiZSBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlIGluIHRoZSByb290IG9mIHRoZSBzb3VyY2VcbiAqICB0cmVlLlxuICovXG4gLyogZXNsaW50LWVudiBub2RlICovXG4ndXNlIHN0cmljdCc7XG5cbnZhciB1dGlscyA9IHJlcXVpcmUoJy4uL3V0aWxzJyk7XG5cbnZhciBmaXJlZm94U2hpbSA9IHtcbiAgc2hpbU9uVHJhY2s6IGZ1bmN0aW9uKHdpbmRvdykge1xuICAgIGlmICh0eXBlb2Ygd2luZG93ID09PSAnb2JqZWN0JyAmJiB3aW5kb3cuUlRDUGVlckNvbm5lY3Rpb24gJiYgISgnb250cmFjaycgaW5cbiAgICAgICAgd2luZG93LlJUQ1BlZXJDb25uZWN0aW9uLnByb3RvdHlwZSkpIHtcbiAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh3aW5kb3cuUlRDUGVlckNvbm5lY3Rpb24ucHJvdG90eXBlLCAnb250cmFjaycsIHtcbiAgICAgICAgZ2V0OiBmdW5jdGlvbigpIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy5fb250cmFjaztcbiAgICAgICAgfSxcbiAgICAgICAgc2V0OiBmdW5jdGlvbihmKSB7XG4gICAgICAgICAgaWYgKHRoaXMuX29udHJhY2spIHtcbiAgICAgICAgICAgIHRoaXMucmVtb3ZlRXZlbnRMaXN0ZW5lcigndHJhY2snLCB0aGlzLl9vbnRyYWNrKTtcbiAgICAgICAgICAgIHRoaXMucmVtb3ZlRXZlbnRMaXN0ZW5lcignYWRkc3RyZWFtJywgdGhpcy5fb250cmFja3BvbHkpO1xuICAgICAgICAgIH1cbiAgICAgICAgICB0aGlzLmFkZEV2ZW50TGlzdGVuZXIoJ3RyYWNrJywgdGhpcy5fb250cmFjayA9IGYpO1xuICAgICAgICAgIHRoaXMuYWRkRXZlbnRMaXN0ZW5lcignYWRkc3RyZWFtJywgdGhpcy5fb250cmFja3BvbHkgPSBmdW5jdGlvbihlKSB7XG4gICAgICAgICAgICBlLnN0cmVhbS5nZXRUcmFja3MoKS5mb3JFYWNoKGZ1bmN0aW9uKHRyYWNrKSB7XG4gICAgICAgICAgICAgIHZhciBldmVudCA9IG5ldyBFdmVudCgndHJhY2snKTtcbiAgICAgICAgICAgICAgZXZlbnQudHJhY2sgPSB0cmFjaztcbiAgICAgICAgICAgICAgZXZlbnQucmVjZWl2ZXIgPSB7dHJhY2s6IHRyYWNrfTtcbiAgICAgICAgICAgICAgZXZlbnQudHJhbnNjZWl2ZXIgPSB7cmVjZWl2ZXI6IGV2ZW50LnJlY2VpdmVyfTtcbiAgICAgICAgICAgICAgZXZlbnQuc3RyZWFtcyA9IFtlLnN0cmVhbV07XG4gICAgICAgICAgICAgIHRoaXMuZGlzcGF0Y2hFdmVudChldmVudCk7XG4gICAgICAgICAgICB9LmJpbmQodGhpcykpO1xuICAgICAgICAgIH0uYmluZCh0aGlzKSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cbiAgICBpZiAodHlwZW9mIHdpbmRvdyA9PT0gJ29iamVjdCcgJiYgd2luZG93LlJUQ1RyYWNrRXZlbnQgJiZcbiAgICAgICAgKCdyZWNlaXZlcicgaW4gd2luZG93LlJUQ1RyYWNrRXZlbnQucHJvdG90eXBlKSAmJlxuICAgICAgICAhKCd0cmFuc2NlaXZlcicgaW4gd2luZG93LlJUQ1RyYWNrRXZlbnQucHJvdG90eXBlKSkge1xuICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHdpbmRvdy5SVENUcmFja0V2ZW50LnByb3RvdHlwZSwgJ3RyYW5zY2VpdmVyJywge1xuICAgICAgICBnZXQ6IGZ1bmN0aW9uKCkge1xuICAgICAgICAgIHJldHVybiB7cmVjZWl2ZXI6IHRoaXMucmVjZWl2ZXJ9O1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG4gIH0sXG5cbiAgc2hpbVNvdXJjZU9iamVjdDogZnVuY3Rpb24od2luZG93KSB7XG4gICAgLy8gRmlyZWZveCBoYXMgc3VwcG9ydGVkIG1velNyY09iamVjdCBzaW5jZSBGRjIyLCB1bnByZWZpeGVkIGluIDQyLlxuICAgIGlmICh0eXBlb2Ygd2luZG93ID09PSAnb2JqZWN0Jykge1xuICAgICAgaWYgKHdpbmRvdy5IVE1MTWVkaWFFbGVtZW50ICYmXG4gICAgICAgICEoJ3NyY09iamVjdCcgaW4gd2luZG93LkhUTUxNZWRpYUVsZW1lbnQucHJvdG90eXBlKSkge1xuICAgICAgICAvLyBTaGltIHRoZSBzcmNPYmplY3QgcHJvcGVydHksIG9uY2UsIHdoZW4gSFRNTE1lZGlhRWxlbWVudCBpcyBmb3VuZC5cbiAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHdpbmRvdy5IVE1MTWVkaWFFbGVtZW50LnByb3RvdHlwZSwgJ3NyY09iamVjdCcsIHtcbiAgICAgICAgICBnZXQ6IGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMubW96U3JjT2JqZWN0O1xuICAgICAgICAgIH0sXG4gICAgICAgICAgc2V0OiBmdW5jdGlvbihzdHJlYW0pIHtcbiAgICAgICAgICAgIHRoaXMubW96U3JjT2JqZWN0ID0gc3RyZWFtO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuICB9LFxuXG4gIHNoaW1QZWVyQ29ubmVjdGlvbjogZnVuY3Rpb24od2luZG93KSB7XG4gICAgdmFyIGJyb3dzZXJEZXRhaWxzID0gdXRpbHMuZGV0ZWN0QnJvd3Nlcih3aW5kb3cpO1xuXG4gICAgaWYgKHR5cGVvZiB3aW5kb3cgIT09ICdvYmplY3QnIHx8ICEod2luZG93LlJUQ1BlZXJDb25uZWN0aW9uIHx8XG4gICAgICAgIHdpbmRvdy5tb3pSVENQZWVyQ29ubmVjdGlvbikpIHtcbiAgICAgIHJldHVybjsgLy8gcHJvYmFibHkgbWVkaWEucGVlcmNvbm5lY3Rpb24uZW5hYmxlZD1mYWxzZSBpbiBhYm91dDpjb25maWdcbiAgICB9XG4gICAgLy8gVGhlIFJUQ1BlZXJDb25uZWN0aW9uIG9iamVjdC5cbiAgICBpZiAoIXdpbmRvdy5SVENQZWVyQ29ubmVjdGlvbikge1xuICAgICAgd2luZG93LlJUQ1BlZXJDb25uZWN0aW9uID0gZnVuY3Rpb24ocGNDb25maWcsIHBjQ29uc3RyYWludHMpIHtcbiAgICAgICAgaWYgKGJyb3dzZXJEZXRhaWxzLnZlcnNpb24gPCAzOCkge1xuICAgICAgICAgIC8vIC51cmxzIGlzIG5vdCBzdXBwb3J0ZWQgaW4gRkYgPCAzOC5cbiAgICAgICAgICAvLyBjcmVhdGUgUlRDSWNlU2VydmVycyB3aXRoIGEgc2luZ2xlIHVybC5cbiAgICAgICAgICBpZiAocGNDb25maWcgJiYgcGNDb25maWcuaWNlU2VydmVycykge1xuICAgICAgICAgICAgdmFyIG5ld0ljZVNlcnZlcnMgPSBbXTtcbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcGNDb25maWcuaWNlU2VydmVycy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICB2YXIgc2VydmVyID0gcGNDb25maWcuaWNlU2VydmVyc1tpXTtcbiAgICAgICAgICAgICAgaWYgKHNlcnZlci5oYXNPd25Qcm9wZXJ0eSgndXJscycpKSB7XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBzZXJ2ZXIudXJscy5sZW5ndGg7IGorKykge1xuICAgICAgICAgICAgICAgICAgdmFyIG5ld1NlcnZlciA9IHtcbiAgICAgICAgICAgICAgICAgICAgdXJsOiBzZXJ2ZXIudXJsc1tqXVxuICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgIGlmIChzZXJ2ZXIudXJsc1tqXS5pbmRleE9mKCd0dXJuJykgPT09IDApIHtcbiAgICAgICAgICAgICAgICAgICAgbmV3U2VydmVyLnVzZXJuYW1lID0gc2VydmVyLnVzZXJuYW1lO1xuICAgICAgICAgICAgICAgICAgICBuZXdTZXJ2ZXIuY3JlZGVudGlhbCA9IHNlcnZlci5jcmVkZW50aWFsO1xuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgbmV3SWNlU2VydmVycy5wdXNoKG5ld1NlcnZlcik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIG5ld0ljZVNlcnZlcnMucHVzaChwY0NvbmZpZy5pY2VTZXJ2ZXJzW2ldKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcGNDb25maWcuaWNlU2VydmVycyA9IG5ld0ljZVNlcnZlcnM7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBuZXcgd2luZG93Lm1velJUQ1BlZXJDb25uZWN0aW9uKHBjQ29uZmlnLCBwY0NvbnN0cmFpbnRzKTtcbiAgICAgIH07XG4gICAgICB3aW5kb3cuUlRDUGVlckNvbm5lY3Rpb24ucHJvdG90eXBlID1cbiAgICAgICAgICB3aW5kb3cubW96UlRDUGVlckNvbm5lY3Rpb24ucHJvdG90eXBlO1xuXG4gICAgICAvLyB3cmFwIHN0YXRpYyBtZXRob2RzLiBDdXJyZW50bHkganVzdCBnZW5lcmF0ZUNlcnRpZmljYXRlLlxuICAgICAgaWYgKHdpbmRvdy5tb3pSVENQZWVyQ29ubmVjdGlvbi5nZW5lcmF0ZUNlcnRpZmljYXRlKSB7XG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh3aW5kb3cuUlRDUGVlckNvbm5lY3Rpb24sICdnZW5lcmF0ZUNlcnRpZmljYXRlJywge1xuICAgICAgICAgIGdldDogZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICByZXR1cm4gd2luZG93Lm1velJUQ1BlZXJDb25uZWN0aW9uLmdlbmVyYXRlQ2VydGlmaWNhdGU7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgd2luZG93LlJUQ1Nlc3Npb25EZXNjcmlwdGlvbiA9IHdpbmRvdy5tb3pSVENTZXNzaW9uRGVzY3JpcHRpb247XG4gICAgICB3aW5kb3cuUlRDSWNlQ2FuZGlkYXRlID0gd2luZG93Lm1velJUQ0ljZUNhbmRpZGF0ZTtcbiAgICB9XG5cbiAgICAvLyBzaGltIGF3YXkgbmVlZCBmb3Igb2Jzb2xldGUgUlRDSWNlQ2FuZGlkYXRlL1JUQ1Nlc3Npb25EZXNjcmlwdGlvbi5cbiAgICBbJ3NldExvY2FsRGVzY3JpcHRpb24nLCAnc2V0UmVtb3RlRGVzY3JpcHRpb24nLCAnYWRkSWNlQ2FuZGlkYXRlJ11cbiAgICAgICAgLmZvckVhY2goZnVuY3Rpb24obWV0aG9kKSB7XG4gICAgICAgICAgdmFyIG5hdGl2ZU1ldGhvZCA9IHdpbmRvdy5SVENQZWVyQ29ubmVjdGlvbi5wcm90b3R5cGVbbWV0aG9kXTtcbiAgICAgICAgICB3aW5kb3cuUlRDUGVlckNvbm5lY3Rpb24ucHJvdG90eXBlW21ldGhvZF0gPSBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgIGFyZ3VtZW50c1swXSA9IG5ldyAoKG1ldGhvZCA9PT0gJ2FkZEljZUNhbmRpZGF0ZScpID9cbiAgICAgICAgICAgICAgICB3aW5kb3cuUlRDSWNlQ2FuZGlkYXRlIDpcbiAgICAgICAgICAgICAgICB3aW5kb3cuUlRDU2Vzc2lvbkRlc2NyaXB0aW9uKShhcmd1bWVudHNbMF0pO1xuICAgICAgICAgICAgcmV0dXJuIG5hdGl2ZU1ldGhvZC5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgICAgIH07XG4gICAgICAgIH0pO1xuXG4gICAgLy8gc3VwcG9ydCBmb3IgYWRkSWNlQ2FuZGlkYXRlKG51bGwgb3IgdW5kZWZpbmVkKVxuICAgIHZhciBuYXRpdmVBZGRJY2VDYW5kaWRhdGUgPVxuICAgICAgICB3aW5kb3cuUlRDUGVlckNvbm5lY3Rpb24ucHJvdG90eXBlLmFkZEljZUNhbmRpZGF0ZTtcbiAgICB3aW5kb3cuUlRDUGVlckNvbm5lY3Rpb24ucHJvdG90eXBlLmFkZEljZUNhbmRpZGF0ZSA9IGZ1bmN0aW9uKCkge1xuICAgICAgaWYgKCFhcmd1bWVudHNbMF0pIHtcbiAgICAgICAgaWYgKGFyZ3VtZW50c1sxXSkge1xuICAgICAgICAgIGFyZ3VtZW50c1sxXS5hcHBseShudWxsKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgICB9XG4gICAgICByZXR1cm4gbmF0aXZlQWRkSWNlQ2FuZGlkYXRlLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgfTtcblxuICAgIC8vIHNoaW0gZ2V0U3RhdHMgd2l0aCBtYXBsaWtlIHN1cHBvcnRcbiAgICB2YXIgbWFrZU1hcFN0YXRzID0gZnVuY3Rpb24oc3RhdHMpIHtcbiAgICAgIHZhciBtYXAgPSBuZXcgTWFwKCk7XG4gICAgICBPYmplY3Qua2V5cyhzdGF0cykuZm9yRWFjaChmdW5jdGlvbihrZXkpIHtcbiAgICAgICAgbWFwLnNldChrZXksIHN0YXRzW2tleV0pO1xuICAgICAgICBtYXBba2V5XSA9IHN0YXRzW2tleV07XG4gICAgICB9KTtcbiAgICAgIHJldHVybiBtYXA7XG4gICAgfTtcblxuICAgIHZhciBtb2Rlcm5TdGF0c1R5cGVzID0ge1xuICAgICAgaW5ib3VuZHJ0cDogJ2luYm91bmQtcnRwJyxcbiAgICAgIG91dGJvdW5kcnRwOiAnb3V0Ym91bmQtcnRwJyxcbiAgICAgIGNhbmRpZGF0ZXBhaXI6ICdjYW5kaWRhdGUtcGFpcicsXG4gICAgICBsb2NhbGNhbmRpZGF0ZTogJ2xvY2FsLWNhbmRpZGF0ZScsXG4gICAgICByZW1vdGVjYW5kaWRhdGU6ICdyZW1vdGUtY2FuZGlkYXRlJ1xuICAgIH07XG5cbiAgICB2YXIgbmF0aXZlR2V0U3RhdHMgPSB3aW5kb3cuUlRDUGVlckNvbm5lY3Rpb24ucHJvdG90eXBlLmdldFN0YXRzO1xuICAgIHdpbmRvdy5SVENQZWVyQ29ubmVjdGlvbi5wcm90b3R5cGUuZ2V0U3RhdHMgPSBmdW5jdGlvbihcbiAgICAgIHNlbGVjdG9yLFxuICAgICAgb25TdWNjLFxuICAgICAgb25FcnJcbiAgICApIHtcbiAgICAgIHJldHVybiBuYXRpdmVHZXRTdGF0cy5hcHBseSh0aGlzLCBbc2VsZWN0b3IgfHwgbnVsbF0pXG4gICAgICAgIC50aGVuKGZ1bmN0aW9uKHN0YXRzKSB7XG4gICAgICAgICAgaWYgKGJyb3dzZXJEZXRhaWxzLnZlcnNpb24gPCA0OCkge1xuICAgICAgICAgICAgc3RhdHMgPSBtYWtlTWFwU3RhdHMoc3RhdHMpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoYnJvd3NlckRldGFpbHMudmVyc2lvbiA8IDUzICYmICFvblN1Y2MpIHtcbiAgICAgICAgICAgIC8vIFNoaW0gb25seSBwcm9taXNlIGdldFN0YXRzIHdpdGggc3BlYy1oeXBoZW5zIGluIHR5cGUgbmFtZXNcbiAgICAgICAgICAgIC8vIExlYXZlIGNhbGxiYWNrIHZlcnNpb24gYWxvbmU7IG1pc2Mgb2xkIHVzZXMgb2YgZm9yRWFjaCBiZWZvcmUgTWFwXG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICBzdGF0cy5mb3JFYWNoKGZ1bmN0aW9uKHN0YXQpIHtcbiAgICAgICAgICAgICAgICBzdGF0LnR5cGUgPSBtb2Rlcm5TdGF0c1R5cGVzW3N0YXQudHlwZV0gfHwgc3RhdC50eXBlO1xuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgaWYgKGUubmFtZSAhPT0gJ1R5cGVFcnJvcicpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBlO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIC8vIEF2b2lkIFR5cGVFcnJvcjogXCJ0eXBlXCIgaXMgcmVhZC1vbmx5LCBpbiBvbGQgdmVyc2lvbnMuIDM0LTQzaXNoXG4gICAgICAgICAgICAgIHN0YXRzLmZvckVhY2goZnVuY3Rpb24oc3RhdCwgaSkge1xuICAgICAgICAgICAgICAgIHN0YXRzLnNldChpLCBPYmplY3QuYXNzaWduKHt9LCBzdGF0LCB7XG4gICAgICAgICAgICAgICAgICB0eXBlOiBtb2Rlcm5TdGF0c1R5cGVzW3N0YXQudHlwZV0gfHwgc3RhdC50eXBlXG4gICAgICAgICAgICAgICAgfSkpO1xuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIHN0YXRzO1xuICAgICAgICB9KVxuICAgICAgICAudGhlbihvblN1Y2MsIG9uRXJyKTtcbiAgICB9O1xuICB9XG59O1xuXG4vLyBFeHBvc2UgcHVibGljIG1ldGhvZHMuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgc2hpbU9uVHJhY2s6IGZpcmVmb3hTaGltLnNoaW1PblRyYWNrLFxuICBzaGltU291cmNlT2JqZWN0OiBmaXJlZm94U2hpbS5zaGltU291cmNlT2JqZWN0LFxuICBzaGltUGVlckNvbm5lY3Rpb246IGZpcmVmb3hTaGltLnNoaW1QZWVyQ29ubmVjdGlvbixcbiAgc2hpbUdldFVzZXJNZWRpYTogcmVxdWlyZSgnLi9nZXR1c2VybWVkaWEnKVxufTtcbiIsIi8qXG4gKiAgQ29weXJpZ2h0IChjKSAyMDE2IFRoZSBXZWJSVEMgcHJvamVjdCBhdXRob3JzLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICpcbiAqICBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlXG4gKiAgdGhhdCBjYW4gYmUgZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZSBpbiB0aGUgcm9vdCBvZiB0aGUgc291cmNlXG4gKiAgdHJlZS5cbiAqL1xuIC8qIGVzbGludC1lbnYgbm9kZSAqL1xuJ3VzZSBzdHJpY3QnO1xuXG52YXIgdXRpbHMgPSByZXF1aXJlKCcuLi91dGlscycpO1xudmFyIGxvZ2dpbmcgPSB1dGlscy5sb2c7XG5cbi8vIEV4cG9zZSBwdWJsaWMgbWV0aG9kcy5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24od2luZG93KSB7XG4gIHZhciBicm93c2VyRGV0YWlscyA9IHV0aWxzLmRldGVjdEJyb3dzZXIod2luZG93KTtcbiAgdmFyIG5hdmlnYXRvciA9IHdpbmRvdyAmJiB3aW5kb3cubmF2aWdhdG9yO1xuICB2YXIgTWVkaWFTdHJlYW1UcmFjayA9IHdpbmRvdyAmJiB3aW5kb3cuTWVkaWFTdHJlYW1UcmFjaztcblxuICB2YXIgc2hpbUVycm9yXyA9IGZ1bmN0aW9uKGUpIHtcbiAgICByZXR1cm4ge1xuICAgICAgbmFtZToge1xuICAgICAgICBJbnRlcm5hbEVycm9yOiAnTm90UmVhZGFibGVFcnJvcicsXG4gICAgICAgIE5vdFN1cHBvcnRlZEVycm9yOiAnVHlwZUVycm9yJyxcbiAgICAgICAgUGVybWlzc2lvbkRlbmllZEVycm9yOiAnTm90QWxsb3dlZEVycm9yJyxcbiAgICAgICAgU2VjdXJpdHlFcnJvcjogJ05vdEFsbG93ZWRFcnJvcidcbiAgICAgIH1bZS5uYW1lXSB8fCBlLm5hbWUsXG4gICAgICBtZXNzYWdlOiB7XG4gICAgICAgICdUaGUgb3BlcmF0aW9uIGlzIGluc2VjdXJlLic6ICdUaGUgcmVxdWVzdCBpcyBub3QgYWxsb3dlZCBieSB0aGUgJyArXG4gICAgICAgICd1c2VyIGFnZW50IG9yIHRoZSBwbGF0Zm9ybSBpbiB0aGUgY3VycmVudCBjb250ZXh0LidcbiAgICAgIH1bZS5tZXNzYWdlXSB8fCBlLm1lc3NhZ2UsXG4gICAgICBjb25zdHJhaW50OiBlLmNvbnN0cmFpbnQsXG4gICAgICB0b1N0cmluZzogZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLm5hbWUgKyAodGhpcy5tZXNzYWdlICYmICc6ICcpICsgdGhpcy5tZXNzYWdlO1xuICAgICAgfVxuICAgIH07XG4gIH07XG5cbiAgLy8gZ2V0VXNlck1lZGlhIGNvbnN0cmFpbnRzIHNoaW0uXG4gIHZhciBnZXRVc2VyTWVkaWFfID0gZnVuY3Rpb24oY29uc3RyYWludHMsIG9uU3VjY2Vzcywgb25FcnJvcikge1xuICAgIHZhciBjb25zdHJhaW50c1RvRkYzN18gPSBmdW5jdGlvbihjKSB7XG4gICAgICBpZiAodHlwZW9mIGMgIT09ICdvYmplY3QnIHx8IGMucmVxdWlyZSkge1xuICAgICAgICByZXR1cm4gYztcbiAgICAgIH1cbiAgICAgIHZhciByZXF1aXJlID0gW107XG4gICAgICBPYmplY3Qua2V5cyhjKS5mb3JFYWNoKGZ1bmN0aW9uKGtleSkge1xuICAgICAgICBpZiAoa2V5ID09PSAncmVxdWlyZScgfHwga2V5ID09PSAnYWR2YW5jZWQnIHx8IGtleSA9PT0gJ21lZGlhU291cmNlJykge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB2YXIgciA9IGNba2V5XSA9ICh0eXBlb2YgY1trZXldID09PSAnb2JqZWN0JykgP1xuICAgICAgICAgICAgY1trZXldIDoge2lkZWFsOiBjW2tleV19O1xuICAgICAgICBpZiAoci5taW4gIT09IHVuZGVmaW5lZCB8fFxuICAgICAgICAgICAgci5tYXggIT09IHVuZGVmaW5lZCB8fCByLmV4YWN0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICByZXF1aXJlLnB1c2goa2V5KTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoci5leGFjdCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgaWYgKHR5cGVvZiByLmV4YWN0ID09PSAnbnVtYmVyJykge1xuICAgICAgICAgICAgci4gbWluID0gci5tYXggPSByLmV4YWN0O1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjW2tleV0gPSByLmV4YWN0O1xuICAgICAgICAgIH1cbiAgICAgICAgICBkZWxldGUgci5leGFjdDtcbiAgICAgICAgfVxuICAgICAgICBpZiAoci5pZGVhbCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgYy5hZHZhbmNlZCA9IGMuYWR2YW5jZWQgfHwgW107XG4gICAgICAgICAgdmFyIG9jID0ge307XG4gICAgICAgICAgaWYgKHR5cGVvZiByLmlkZWFsID09PSAnbnVtYmVyJykge1xuICAgICAgICAgICAgb2Nba2V5XSA9IHttaW46IHIuaWRlYWwsIG1heDogci5pZGVhbH07XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIG9jW2tleV0gPSByLmlkZWFsO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjLmFkdmFuY2VkLnB1c2gob2MpO1xuICAgICAgICAgIGRlbGV0ZSByLmlkZWFsO1xuICAgICAgICAgIGlmICghT2JqZWN0LmtleXMocikubGVuZ3RoKSB7XG4gICAgICAgICAgICBkZWxldGUgY1trZXldO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICBpZiAocmVxdWlyZS5sZW5ndGgpIHtcbiAgICAgICAgYy5yZXF1aXJlID0gcmVxdWlyZTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBjO1xuICAgIH07XG4gICAgY29uc3RyYWludHMgPSBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KGNvbnN0cmFpbnRzKSk7XG4gICAgaWYgKGJyb3dzZXJEZXRhaWxzLnZlcnNpb24gPCAzOCkge1xuICAgICAgbG9nZ2luZygnc3BlYzogJyArIEpTT04uc3RyaW5naWZ5KGNvbnN0cmFpbnRzKSk7XG4gICAgICBpZiAoY29uc3RyYWludHMuYXVkaW8pIHtcbiAgICAgICAgY29uc3RyYWludHMuYXVkaW8gPSBjb25zdHJhaW50c1RvRkYzN18oY29uc3RyYWludHMuYXVkaW8pO1xuICAgICAgfVxuICAgICAgaWYgKGNvbnN0cmFpbnRzLnZpZGVvKSB7XG4gICAgICAgIGNvbnN0cmFpbnRzLnZpZGVvID0gY29uc3RyYWludHNUb0ZGMzdfKGNvbnN0cmFpbnRzLnZpZGVvKTtcbiAgICAgIH1cbiAgICAgIGxvZ2dpbmcoJ2ZmMzc6ICcgKyBKU09OLnN0cmluZ2lmeShjb25zdHJhaW50cykpO1xuICAgIH1cbiAgICByZXR1cm4gbmF2aWdhdG9yLm1vekdldFVzZXJNZWRpYShjb25zdHJhaW50cywgb25TdWNjZXNzLCBmdW5jdGlvbihlKSB7XG4gICAgICBvbkVycm9yKHNoaW1FcnJvcl8oZSkpO1xuICAgIH0pO1xuICB9O1xuXG4gIC8vIFJldHVybnMgdGhlIHJlc3VsdCBvZiBnZXRVc2VyTWVkaWEgYXMgYSBQcm9taXNlLlxuICB2YXIgZ2V0VXNlck1lZGlhUHJvbWlzZV8gPSBmdW5jdGlvbihjb25zdHJhaW50cykge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbihyZXNvbHZlLCByZWplY3QpIHtcbiAgICAgIGdldFVzZXJNZWRpYV8oY29uc3RyYWludHMsIHJlc29sdmUsIHJlamVjdCk7XG4gICAgfSk7XG4gIH07XG5cbiAgLy8gU2hpbSBmb3IgbWVkaWFEZXZpY2VzIG9uIG9sZGVyIHZlcnNpb25zLlxuICBpZiAoIW5hdmlnYXRvci5tZWRpYURldmljZXMpIHtcbiAgICBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzID0ge2dldFVzZXJNZWRpYTogZ2V0VXNlck1lZGlhUHJvbWlzZV8sXG4gICAgICBhZGRFdmVudExpc3RlbmVyOiBmdW5jdGlvbigpIHsgfSxcbiAgICAgIHJlbW92ZUV2ZW50TGlzdGVuZXI6IGZ1bmN0aW9uKCkgeyB9XG4gICAgfTtcbiAgfVxuICBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmVudW1lcmF0ZURldmljZXMgPVxuICAgICAgbmF2aWdhdG9yLm1lZGlhRGV2aWNlcy5lbnVtZXJhdGVEZXZpY2VzIHx8IGZ1bmN0aW9uKCkge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24ocmVzb2x2ZSkge1xuICAgICAgICAgIHZhciBpbmZvcyA9IFtcbiAgICAgICAgICAgIHtraW5kOiAnYXVkaW9pbnB1dCcsIGRldmljZUlkOiAnZGVmYXVsdCcsIGxhYmVsOiAnJywgZ3JvdXBJZDogJyd9LFxuICAgICAgICAgICAge2tpbmQ6ICd2aWRlb2lucHV0JywgZGV2aWNlSWQ6ICdkZWZhdWx0JywgbGFiZWw6ICcnLCBncm91cElkOiAnJ31cbiAgICAgICAgICBdO1xuICAgICAgICAgIHJlc29sdmUoaW5mb3MpO1xuICAgICAgICB9KTtcbiAgICAgIH07XG5cbiAgaWYgKGJyb3dzZXJEZXRhaWxzLnZlcnNpb24gPCA0MSkge1xuICAgIC8vIFdvcmsgYXJvdW5kIGh0dHA6Ly9idWd6aWwubGEvMTE2OTY2NVxuICAgIHZhciBvcmdFbnVtZXJhdGVEZXZpY2VzID1cbiAgICAgICAgbmF2aWdhdG9yLm1lZGlhRGV2aWNlcy5lbnVtZXJhdGVEZXZpY2VzLmJpbmQobmF2aWdhdG9yLm1lZGlhRGV2aWNlcyk7XG4gICAgbmF2aWdhdG9yLm1lZGlhRGV2aWNlcy5lbnVtZXJhdGVEZXZpY2VzID0gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gb3JnRW51bWVyYXRlRGV2aWNlcygpLnRoZW4odW5kZWZpbmVkLCBmdW5jdGlvbihlKSB7XG4gICAgICAgIGlmIChlLm5hbWUgPT09ICdOb3RGb3VuZEVycm9yJykge1xuICAgICAgICAgIHJldHVybiBbXTtcbiAgICAgICAgfVxuICAgICAgICB0aHJvdyBlO1xuICAgICAgfSk7XG4gICAgfTtcbiAgfVxuICBpZiAoYnJvd3NlckRldGFpbHMudmVyc2lvbiA8IDQ5KSB7XG4gICAgdmFyIG9yaWdHZXRVc2VyTWVkaWEgPSBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmdldFVzZXJNZWRpYS5cbiAgICAgICAgYmluZChuYXZpZ2F0b3IubWVkaWFEZXZpY2VzKTtcbiAgICBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmdldFVzZXJNZWRpYSA9IGZ1bmN0aW9uKGMpIHtcbiAgICAgIHJldHVybiBvcmlnR2V0VXNlck1lZGlhKGMpLnRoZW4oZnVuY3Rpb24oc3RyZWFtKSB7XG4gICAgICAgIC8vIFdvcmsgYXJvdW5kIGh0dHBzOi8vYnVnemlsLmxhLzgwMjMyNlxuICAgICAgICBpZiAoYy5hdWRpbyAmJiAhc3RyZWFtLmdldEF1ZGlvVHJhY2tzKCkubGVuZ3RoIHx8XG4gICAgICAgICAgICBjLnZpZGVvICYmICFzdHJlYW0uZ2V0VmlkZW9UcmFja3MoKS5sZW5ndGgpIHtcbiAgICAgICAgICBzdHJlYW0uZ2V0VHJhY2tzKCkuZm9yRWFjaChmdW5jdGlvbih0cmFjaykge1xuICAgICAgICAgICAgdHJhY2suc3RvcCgpO1xuICAgICAgICAgIH0pO1xuICAgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oJ1RoZSBvYmplY3QgY2FuIG5vdCBiZSBmb3VuZCBoZXJlLicsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnTm90Rm91bmRFcnJvcicpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBzdHJlYW07XG4gICAgICB9LCBmdW5jdGlvbihlKSB7XG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChzaGltRXJyb3JfKGUpKTtcbiAgICAgIH0pO1xuICAgIH07XG4gIH1cbiAgaWYgKCEoYnJvd3NlckRldGFpbHMudmVyc2lvbiA+IDU1ICYmXG4gICAgICAnYXV0b0dhaW5Db250cm9sJyBpbiBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmdldFN1cHBvcnRlZENvbnN0cmFpbnRzKCkpKSB7XG4gICAgdmFyIHJlbWFwID0gZnVuY3Rpb24ob2JqLCBhLCBiKSB7XG4gICAgICBpZiAoYSBpbiBvYmogJiYgIShiIGluIG9iaikpIHtcbiAgICAgICAgb2JqW2JdID0gb2JqW2FdO1xuICAgICAgICBkZWxldGUgb2JqW2FdO1xuICAgICAgfVxuICAgIH07XG5cbiAgICB2YXIgbmF0aXZlR2V0VXNlck1lZGlhID0gbmF2aWdhdG9yLm1lZGlhRGV2aWNlcy5nZXRVc2VyTWVkaWEuXG4gICAgICAgIGJpbmQobmF2aWdhdG9yLm1lZGlhRGV2aWNlcyk7XG4gICAgbmF2aWdhdG9yLm1lZGlhRGV2aWNlcy5nZXRVc2VyTWVkaWEgPSBmdW5jdGlvbihjKSB7XG4gICAgICBpZiAodHlwZW9mIGMgPT09ICdvYmplY3QnICYmIHR5cGVvZiBjLmF1ZGlvID09PSAnb2JqZWN0Jykge1xuICAgICAgICBjID0gSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeShjKSk7XG4gICAgICAgIHJlbWFwKGMuYXVkaW8sICdhdXRvR2FpbkNvbnRyb2wnLCAnbW96QXV0b0dhaW5Db250cm9sJyk7XG4gICAgICAgIHJlbWFwKGMuYXVkaW8sICdub2lzZVN1cHByZXNzaW9uJywgJ21vek5vaXNlU3VwcHJlc3Npb24nKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBuYXRpdmVHZXRVc2VyTWVkaWEoYyk7XG4gICAgfTtcblxuICAgIGlmIChNZWRpYVN0cmVhbVRyYWNrICYmIE1lZGlhU3RyZWFtVHJhY2sucHJvdG90eXBlLmdldFNldHRpbmdzKSB7XG4gICAgICB2YXIgbmF0aXZlR2V0U2V0dGluZ3MgPSBNZWRpYVN0cmVhbVRyYWNrLnByb3RvdHlwZS5nZXRTZXR0aW5ncztcbiAgICAgIE1lZGlhU3RyZWFtVHJhY2sucHJvdG90eXBlLmdldFNldHRpbmdzID0gZnVuY3Rpb24oKSB7XG4gICAgICAgIHZhciBvYmogPSBuYXRpdmVHZXRTZXR0aW5ncy5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgICByZW1hcChvYmosICdtb3pBdXRvR2FpbkNvbnRyb2wnLCAnYXV0b0dhaW5Db250cm9sJyk7XG4gICAgICAgIHJlbWFwKG9iaiwgJ21vek5vaXNlU3VwcHJlc3Npb24nLCAnbm9pc2VTdXBwcmVzc2lvbicpO1xuICAgICAgICByZXR1cm4gb2JqO1xuICAgICAgfTtcbiAgICB9XG5cbiAgICBpZiAoTWVkaWFTdHJlYW1UcmFjayAmJiBNZWRpYVN0cmVhbVRyYWNrLnByb3RvdHlwZS5hcHBseUNvbnN0cmFpbnRzKSB7XG4gICAgICB2YXIgbmF0aXZlQXBwbHlDb25zdHJhaW50cyA9IE1lZGlhU3RyZWFtVHJhY2sucHJvdG90eXBlLmFwcGx5Q29uc3RyYWludHM7XG4gICAgICBNZWRpYVN0cmVhbVRyYWNrLnByb3RvdHlwZS5hcHBseUNvbnN0cmFpbnRzID0gZnVuY3Rpb24oYykge1xuICAgICAgICBpZiAodGhpcy5raW5kID09PSAnYXVkaW8nICYmIHR5cGVvZiBjID09PSAnb2JqZWN0Jykge1xuICAgICAgICAgIGMgPSBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KGMpKTtcbiAgICAgICAgICByZW1hcChjLCAnYXV0b0dhaW5Db250cm9sJywgJ21vekF1dG9HYWluQ29udHJvbCcpO1xuICAgICAgICAgIHJlbWFwKGMsICdub2lzZVN1cHByZXNzaW9uJywgJ21vek5vaXNlU3VwcHJlc3Npb24nKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbmF0aXZlQXBwbHlDb25zdHJhaW50cy5hcHBseSh0aGlzLCBbY10pO1xuICAgICAgfTtcbiAgICB9XG4gIH1cbiAgbmF2aWdhdG9yLmdldFVzZXJNZWRpYSA9IGZ1bmN0aW9uKGNvbnN0cmFpbnRzLCBvblN1Y2Nlc3MsIG9uRXJyb3IpIHtcbiAgICBpZiAoYnJvd3NlckRldGFpbHMudmVyc2lvbiA8IDQ0KSB7XG4gICAgICByZXR1cm4gZ2V0VXNlck1lZGlhXyhjb25zdHJhaW50cywgb25TdWNjZXNzLCBvbkVycm9yKTtcbiAgICB9XG4gICAgLy8gUmVwbGFjZSBGaXJlZm94IDQ0KydzIGRlcHJlY2F0aW9uIHdhcm5pbmcgd2l0aCB1bnByZWZpeGVkIHZlcnNpb24uXG4gICAgdXRpbHMuZGVwcmVjYXRlZCgnbmF2aWdhdG9yLmdldFVzZXJNZWRpYScsXG4gICAgICAgICduYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmdldFVzZXJNZWRpYScpO1xuICAgIG5hdmlnYXRvci5tZWRpYURldmljZXMuZ2V0VXNlck1lZGlhKGNvbnN0cmFpbnRzKS50aGVuKG9uU3VjY2Vzcywgb25FcnJvcik7XG4gIH07XG59O1xuIiwiLypcbiAqICBDb3B5cmlnaHQgKGMpIDIwMTYgVGhlIFdlYlJUQyBwcm9qZWN0IGF1dGhvcnMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKlxuICogIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2VcbiAqICB0aGF0IGNhbiBiZSBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlIGluIHRoZSByb290IG9mIHRoZSBzb3VyY2VcbiAqICB0cmVlLlxuICovXG4ndXNlIHN0cmljdCc7XG52YXIgdXRpbHMgPSByZXF1aXJlKCcuLi91dGlscycpO1xuXG52YXIgc2FmYXJpU2hpbSA9IHtcbiAgLy8gVE9ETzogRHJBbGV4LCBzaG91bGQgYmUgaGVyZSwgZG91YmxlIGNoZWNrIGFnYWluc3QgTGF5b3V0VGVzdHNcblxuICAvLyBUT0RPOiBvbmNlIHRoZSBiYWNrLWVuZCBmb3IgdGhlIG1hYyBwb3J0IGlzIGRvbmUsIGFkZC5cbiAgLy8gVE9ETzogY2hlY2sgZm9yIHdlYmtpdEdUSytcbiAgLy8gc2hpbVBlZXJDb25uZWN0aW9uOiBmdW5jdGlvbigpIHsgfSxcblxuICBzaGltTG9jYWxTdHJlYW1zQVBJOiBmdW5jdGlvbih3aW5kb3cpIHtcbiAgICBpZiAodHlwZW9mIHdpbmRvdyAhPT0gJ29iamVjdCcgfHwgIXdpbmRvdy5SVENQZWVyQ29ubmVjdGlvbikge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoISgnZ2V0TG9jYWxTdHJlYW1zJyBpbiB3aW5kb3cuUlRDUGVlckNvbm5lY3Rpb24ucHJvdG90eXBlKSkge1xuICAgICAgd2luZG93LlJUQ1BlZXJDb25uZWN0aW9uLnByb3RvdHlwZS5nZXRMb2NhbFN0cmVhbXMgPSBmdW5jdGlvbigpIHtcbiAgICAgICAgaWYgKCF0aGlzLl9sb2NhbFN0cmVhbXMpIHtcbiAgICAgICAgICB0aGlzLl9sb2NhbFN0cmVhbXMgPSBbXTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5fbG9jYWxTdHJlYW1zO1xuICAgICAgfTtcbiAgICB9XG4gICAgaWYgKCEoJ2dldFN0cmVhbUJ5SWQnIGluIHdpbmRvdy5SVENQZWVyQ29ubmVjdGlvbi5wcm90b3R5cGUpKSB7XG4gICAgICB3aW5kb3cuUlRDUGVlckNvbm5lY3Rpb24ucHJvdG90eXBlLmdldFN0cmVhbUJ5SWQgPSBmdW5jdGlvbihpZCkge1xuICAgICAgICB2YXIgcmVzdWx0ID0gbnVsbDtcbiAgICAgICAgaWYgKHRoaXMuX2xvY2FsU3RyZWFtcykge1xuICAgICAgICAgIHRoaXMuX2xvY2FsU3RyZWFtcy5mb3JFYWNoKGZ1bmN0aW9uKHN0cmVhbSkge1xuICAgICAgICAgICAgaWYgKHN0cmVhbS5pZCA9PT0gaWQpIHtcbiAgICAgICAgICAgICAgcmVzdWx0ID0gc3RyZWFtO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLl9yZW1vdGVTdHJlYW1zKSB7XG4gICAgICAgICAgdGhpcy5fcmVtb3RlU3RyZWFtcy5mb3JFYWNoKGZ1bmN0aW9uKHN0cmVhbSkge1xuICAgICAgICAgICAgaWYgKHN0cmVhbS5pZCA9PT0gaWQpIHtcbiAgICAgICAgICAgICAgcmVzdWx0ID0gc3RyZWFtO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9O1xuICAgIH1cbiAgICBpZiAoISgnYWRkU3RyZWFtJyBpbiB3aW5kb3cuUlRDUGVlckNvbm5lY3Rpb24ucHJvdG90eXBlKSkge1xuICAgICAgdmFyIF9hZGRUcmFjayA9IHdpbmRvdy5SVENQZWVyQ29ubmVjdGlvbi5wcm90b3R5cGUuYWRkVHJhY2s7XG4gICAgICB3aW5kb3cuUlRDUGVlckNvbm5lY3Rpb24ucHJvdG90eXBlLmFkZFN0cmVhbSA9IGZ1bmN0aW9uKHN0cmVhbSkge1xuICAgICAgICBpZiAoIXRoaXMuX2xvY2FsU3RyZWFtcykge1xuICAgICAgICAgIHRoaXMuX2xvY2FsU3RyZWFtcyA9IFtdO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLl9sb2NhbFN0cmVhbXMuaW5kZXhPZihzdHJlYW0pID09PSAtMSkge1xuICAgICAgICAgIHRoaXMuX2xvY2FsU3RyZWFtcy5wdXNoKHN0cmVhbSk7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIHNlbGYgPSB0aGlzO1xuICAgICAgICBzdHJlYW0uZ2V0VHJhY2tzKCkuZm9yRWFjaChmdW5jdGlvbih0cmFjaykge1xuICAgICAgICAgIF9hZGRUcmFjay5jYWxsKHNlbGYsIHRyYWNrLCBzdHJlYW0pO1xuICAgICAgICB9KTtcbiAgICAgIH07XG5cbiAgICAgIHdpbmRvdy5SVENQZWVyQ29ubmVjdGlvbi5wcm90b3R5cGUuYWRkVHJhY2sgPSBmdW5jdGlvbih0cmFjaywgc3RyZWFtKSB7XG4gICAgICAgIGlmIChzdHJlYW0pIHtcbiAgICAgICAgICBpZiAoIXRoaXMuX2xvY2FsU3RyZWFtcykge1xuICAgICAgICAgICAgdGhpcy5fbG9jYWxTdHJlYW1zID0gW3N0cmVhbV07XG4gICAgICAgICAgfSBlbHNlIGlmICh0aGlzLl9sb2NhbFN0cmVhbXMuaW5kZXhPZihzdHJlYW0pID09PSAtMSkge1xuICAgICAgICAgICAgdGhpcy5fbG9jYWxTdHJlYW1zLnB1c2goc3RyZWFtKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgX2FkZFRyYWNrLmNhbGwodGhpcywgdHJhY2ssIHN0cmVhbSk7XG4gICAgICB9O1xuICAgIH1cbiAgICBpZiAoISgncmVtb3ZlU3RyZWFtJyBpbiB3aW5kb3cuUlRDUGVlckNvbm5lY3Rpb24ucHJvdG90eXBlKSkge1xuICAgICAgd2luZG93LlJUQ1BlZXJDb25uZWN0aW9uLnByb3RvdHlwZS5yZW1vdmVTdHJlYW0gPSBmdW5jdGlvbihzdHJlYW0pIHtcbiAgICAgICAgaWYgKCF0aGlzLl9sb2NhbFN0cmVhbXMpIHtcbiAgICAgICAgICB0aGlzLl9sb2NhbFN0cmVhbXMgPSBbXTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgaW5kZXggPSB0aGlzLl9sb2NhbFN0cmVhbXMuaW5kZXhPZihzdHJlYW0pO1xuICAgICAgICBpZiAoaW5kZXggPT09IC0xKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX2xvY2FsU3RyZWFtcy5zcGxpY2UoaW5kZXgsIDEpO1xuICAgICAgICB2YXIgc2VsZiA9IHRoaXM7XG4gICAgICAgIHZhciB0cmFja3MgPSBzdHJlYW0uZ2V0VHJhY2tzKCk7XG4gICAgICAgIHRoaXMuZ2V0U2VuZGVycygpLmZvckVhY2goZnVuY3Rpb24oc2VuZGVyKSB7XG4gICAgICAgICAgaWYgKHRyYWNrcy5pbmRleE9mKHNlbmRlci50cmFjaykgIT09IC0xKSB7XG4gICAgICAgICAgICBzZWxmLnJlbW92ZVRyYWNrKHNlbmRlcik7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH07XG4gICAgfVxuICB9LFxuICBzaGltUmVtb3RlU3RyZWFtc0FQSTogZnVuY3Rpb24od2luZG93KSB7XG4gICAgaWYgKHR5cGVvZiB3aW5kb3cgIT09ICdvYmplY3QnIHx8ICF3aW5kb3cuUlRDUGVlckNvbm5lY3Rpb24pIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKCEoJ2dldFJlbW90ZVN0cmVhbXMnIGluIHdpbmRvdy5SVENQZWVyQ29ubmVjdGlvbi5wcm90b3R5cGUpKSB7XG4gICAgICB3aW5kb3cuUlRDUGVlckNvbm5lY3Rpb24ucHJvdG90eXBlLmdldFJlbW90ZVN0cmVhbXMgPSBmdW5jdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3JlbW90ZVN0cmVhbXMgPyB0aGlzLl9yZW1vdGVTdHJlYW1zIDogW107XG4gICAgICB9O1xuICAgIH1cbiAgICBpZiAoISgnb25hZGRzdHJlYW0nIGluIHdpbmRvdy5SVENQZWVyQ29ubmVjdGlvbi5wcm90b3R5cGUpKSB7XG4gICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkod2luZG93LlJUQ1BlZXJDb25uZWN0aW9uLnByb3RvdHlwZSwgJ29uYWRkc3RyZWFtJywge1xuICAgICAgICBnZXQ6IGZ1bmN0aW9uKCkge1xuICAgICAgICAgIHJldHVybiB0aGlzLl9vbmFkZHN0cmVhbTtcbiAgICAgICAgfSxcbiAgICAgICAgc2V0OiBmdW5jdGlvbihmKSB7XG4gICAgICAgICAgaWYgKHRoaXMuX29uYWRkc3RyZWFtKSB7XG4gICAgICAgICAgICB0aGlzLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2FkZHN0cmVhbScsIHRoaXMuX29uYWRkc3RyZWFtKTtcbiAgICAgICAgICAgIHRoaXMucmVtb3ZlRXZlbnRMaXN0ZW5lcigndHJhY2snLCB0aGlzLl9vbmFkZHN0cmVhbXBvbHkpO1xuICAgICAgICAgIH1cbiAgICAgICAgICB0aGlzLmFkZEV2ZW50TGlzdGVuZXIoJ2FkZHN0cmVhbScsIHRoaXMuX29uYWRkc3RyZWFtID0gZik7XG4gICAgICAgICAgdGhpcy5hZGRFdmVudExpc3RlbmVyKCd0cmFjaycsIHRoaXMuX29uYWRkc3RyZWFtcG9seSA9IGZ1bmN0aW9uKGUpIHtcbiAgICAgICAgICAgIHZhciBzdHJlYW0gPSBlLnN0cmVhbXNbMF07XG4gICAgICAgICAgICBpZiAoIXRoaXMuX3JlbW90ZVN0cmVhbXMpIHtcbiAgICAgICAgICAgICAgdGhpcy5fcmVtb3RlU3RyZWFtcyA9IFtdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHRoaXMuX3JlbW90ZVN0cmVhbXMuaW5kZXhPZihzdHJlYW0pID49IDApIHtcbiAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5fcmVtb3RlU3RyZWFtcy5wdXNoKHN0cmVhbSk7XG4gICAgICAgICAgICB2YXIgZXZlbnQgPSBuZXcgRXZlbnQoJ2FkZHN0cmVhbScpO1xuICAgICAgICAgICAgZXZlbnQuc3RyZWFtID0gZS5zdHJlYW1zWzBdO1xuICAgICAgICAgICAgdGhpcy5kaXNwYXRjaEV2ZW50KGV2ZW50KTtcbiAgICAgICAgICB9LmJpbmQodGhpcykpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG4gIH0sXG4gIHNoaW1DYWxsYmFja3NBUEk6IGZ1bmN0aW9uKHdpbmRvdykge1xuICAgIGlmICh0eXBlb2Ygd2luZG93ICE9PSAnb2JqZWN0JyB8fCAhd2luZG93LlJUQ1BlZXJDb25uZWN0aW9uKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHZhciBwcm90b3R5cGUgPSB3aW5kb3cuUlRDUGVlckNvbm5lY3Rpb24ucHJvdG90eXBlO1xuICAgIHZhciBjcmVhdGVPZmZlciA9IHByb3RvdHlwZS5jcmVhdGVPZmZlcjtcbiAgICB2YXIgY3JlYXRlQW5zd2VyID0gcHJvdG90eXBlLmNyZWF0ZUFuc3dlcjtcbiAgICB2YXIgc2V0TG9jYWxEZXNjcmlwdGlvbiA9IHByb3RvdHlwZS5zZXRMb2NhbERlc2NyaXB0aW9uO1xuICAgIHZhciBzZXRSZW1vdGVEZXNjcmlwdGlvbiA9IHByb3RvdHlwZS5zZXRSZW1vdGVEZXNjcmlwdGlvbjtcbiAgICB2YXIgYWRkSWNlQ2FuZGlkYXRlID0gcHJvdG90eXBlLmFkZEljZUNhbmRpZGF0ZTtcblxuICAgIHByb3RvdHlwZS5jcmVhdGVPZmZlciA9IGZ1bmN0aW9uKHN1Y2Nlc3NDYWxsYmFjaywgZmFpbHVyZUNhbGxiYWNrKSB7XG4gICAgICB2YXIgb3B0aW9ucyA9IChhcmd1bWVudHMubGVuZ3RoID49IDIpID8gYXJndW1lbnRzWzJdIDogYXJndW1lbnRzWzBdO1xuICAgICAgdmFyIHByb21pc2UgPSBjcmVhdGVPZmZlci5hcHBseSh0aGlzLCBbb3B0aW9uc10pO1xuICAgICAgaWYgKCFmYWlsdXJlQ2FsbGJhY2spIHtcbiAgICAgICAgcmV0dXJuIHByb21pc2U7XG4gICAgICB9XG4gICAgICBwcm9taXNlLnRoZW4oc3VjY2Vzc0NhbGxiYWNrLCBmYWlsdXJlQ2FsbGJhY2spO1xuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICAgIH07XG5cbiAgICBwcm90b3R5cGUuY3JlYXRlQW5zd2VyID0gZnVuY3Rpb24oc3VjY2Vzc0NhbGxiYWNrLCBmYWlsdXJlQ2FsbGJhY2spIHtcbiAgICAgIHZhciBvcHRpb25zID0gKGFyZ3VtZW50cy5sZW5ndGggPj0gMikgPyBhcmd1bWVudHNbMl0gOiBhcmd1bWVudHNbMF07XG4gICAgICB2YXIgcHJvbWlzZSA9IGNyZWF0ZUFuc3dlci5hcHBseSh0aGlzLCBbb3B0aW9uc10pO1xuICAgICAgaWYgKCFmYWlsdXJlQ2FsbGJhY2spIHtcbiAgICAgICAgcmV0dXJuIHByb21pc2U7XG4gICAgICB9XG4gICAgICBwcm9taXNlLnRoZW4oc3VjY2Vzc0NhbGxiYWNrLCBmYWlsdXJlQ2FsbGJhY2spO1xuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICAgIH07XG5cbiAgICB2YXIgd2l0aENhbGxiYWNrID0gZnVuY3Rpb24oZGVzY3JpcHRpb24sIHN1Y2Nlc3NDYWxsYmFjaywgZmFpbHVyZUNhbGxiYWNrKSB7XG4gICAgICB2YXIgcHJvbWlzZSA9IHNldExvY2FsRGVzY3JpcHRpb24uYXBwbHkodGhpcywgW2Rlc2NyaXB0aW9uXSk7XG4gICAgICBpZiAoIWZhaWx1cmVDYWxsYmFjaykge1xuICAgICAgICByZXR1cm4gcHJvbWlzZTtcbiAgICAgIH1cbiAgICAgIHByb21pc2UudGhlbihzdWNjZXNzQ2FsbGJhY2ssIGZhaWx1cmVDYWxsYmFjayk7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgfTtcbiAgICBwcm90b3R5cGUuc2V0TG9jYWxEZXNjcmlwdGlvbiA9IHdpdGhDYWxsYmFjaztcblxuICAgIHdpdGhDYWxsYmFjayA9IGZ1bmN0aW9uKGRlc2NyaXB0aW9uLCBzdWNjZXNzQ2FsbGJhY2ssIGZhaWx1cmVDYWxsYmFjaykge1xuICAgICAgdmFyIHByb21pc2UgPSBzZXRSZW1vdGVEZXNjcmlwdGlvbi5hcHBseSh0aGlzLCBbZGVzY3JpcHRpb25dKTtcbiAgICAgIGlmICghZmFpbHVyZUNhbGxiYWNrKSB7XG4gICAgICAgIHJldHVybiBwcm9taXNlO1xuICAgICAgfVxuICAgICAgcHJvbWlzZS50aGVuKHN1Y2Nlc3NDYWxsYmFjaywgZmFpbHVyZUNhbGxiYWNrKTtcbiAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgICB9O1xuICAgIHByb3RvdHlwZS5zZXRSZW1vdGVEZXNjcmlwdGlvbiA9IHdpdGhDYWxsYmFjaztcblxuICAgIHdpdGhDYWxsYmFjayA9IGZ1bmN0aW9uKGNhbmRpZGF0ZSwgc3VjY2Vzc0NhbGxiYWNrLCBmYWlsdXJlQ2FsbGJhY2spIHtcbiAgICAgIHZhciBwcm9taXNlID0gYWRkSWNlQ2FuZGlkYXRlLmFwcGx5KHRoaXMsIFtjYW5kaWRhdGVdKTtcbiAgICAgIGlmICghZmFpbHVyZUNhbGxiYWNrKSB7XG4gICAgICAgIHJldHVybiBwcm9taXNlO1xuICAgICAgfVxuICAgICAgcHJvbWlzZS50aGVuKHN1Y2Nlc3NDYWxsYmFjaywgZmFpbHVyZUNhbGxiYWNrKTtcbiAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgICB9O1xuICAgIHByb3RvdHlwZS5hZGRJY2VDYW5kaWRhdGUgPSB3aXRoQ2FsbGJhY2s7XG4gIH0sXG4gIHNoaW1HZXRVc2VyTWVkaWE6IGZ1bmN0aW9uKHdpbmRvdykge1xuICAgIHZhciBuYXZpZ2F0b3IgPSB3aW5kb3cgJiYgd2luZG93Lm5hdmlnYXRvcjtcblxuICAgIGlmICghbmF2aWdhdG9yLmdldFVzZXJNZWRpYSkge1xuICAgICAgaWYgKG5hdmlnYXRvci53ZWJraXRHZXRVc2VyTWVkaWEpIHtcbiAgICAgICAgbmF2aWdhdG9yLmdldFVzZXJNZWRpYSA9IG5hdmlnYXRvci53ZWJraXRHZXRVc2VyTWVkaWEuYmluZChuYXZpZ2F0b3IpO1xuICAgICAgfSBlbHNlIGlmIChuYXZpZ2F0b3IubWVkaWFEZXZpY2VzICYmXG4gICAgICAgICAgbmF2aWdhdG9yLm1lZGlhRGV2aWNlcy5nZXRVc2VyTWVkaWEpIHtcbiAgICAgICAgbmF2aWdhdG9yLmdldFVzZXJNZWRpYSA9IGZ1bmN0aW9uKGNvbnN0cmFpbnRzLCBjYiwgZXJyY2IpIHtcbiAgICAgICAgICBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmdldFVzZXJNZWRpYShjb25zdHJhaW50cylcbiAgICAgICAgICAudGhlbihjYiwgZXJyY2IpO1xuICAgICAgICB9LmJpbmQobmF2aWdhdG9yKTtcbiAgICAgIH1cbiAgICB9XG4gIH0sXG4gIHNoaW1SVENJY2VTZXJ2ZXJVcmxzOiBmdW5jdGlvbih3aW5kb3cpIHtcbiAgICAvLyBtaWdyYXRlIGZyb20gbm9uLXNwZWMgUlRDSWNlU2VydmVyLnVybCB0byBSVENJY2VTZXJ2ZXIudXJsc1xuICAgIHZhciBPcmlnUGVlckNvbm5lY3Rpb24gPSB3aW5kb3cuUlRDUGVlckNvbm5lY3Rpb247XG4gICAgd2luZG93LlJUQ1BlZXJDb25uZWN0aW9uID0gZnVuY3Rpb24ocGNDb25maWcsIHBjQ29uc3RyYWludHMpIHtcbiAgICAgIGlmIChwY0NvbmZpZyAmJiBwY0NvbmZpZy5pY2VTZXJ2ZXJzKSB7XG4gICAgICAgIHZhciBuZXdJY2VTZXJ2ZXJzID0gW107XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcGNDb25maWcuaWNlU2VydmVycy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgIHZhciBzZXJ2ZXIgPSBwY0NvbmZpZy5pY2VTZXJ2ZXJzW2ldO1xuICAgICAgICAgIGlmICghc2VydmVyLmhhc093blByb3BlcnR5KCd1cmxzJykgJiZcbiAgICAgICAgICAgICAgc2VydmVyLmhhc093blByb3BlcnR5KCd1cmwnKSkge1xuICAgICAgICAgICAgdXRpbHMuZGVwcmVjYXRlZCgnUlRDSWNlU2VydmVyLnVybCcsICdSVENJY2VTZXJ2ZXIudXJscycpO1xuICAgICAgICAgICAgc2VydmVyID0gSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeShzZXJ2ZXIpKTtcbiAgICAgICAgICAgIHNlcnZlci51cmxzID0gc2VydmVyLnVybDtcbiAgICAgICAgICAgIGRlbGV0ZSBzZXJ2ZXIudXJsO1xuICAgICAgICAgICAgbmV3SWNlU2VydmVycy5wdXNoKHNlcnZlcik7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIG5ld0ljZVNlcnZlcnMucHVzaChwY0NvbmZpZy5pY2VTZXJ2ZXJzW2ldKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcGNDb25maWcuaWNlU2VydmVycyA9IG5ld0ljZVNlcnZlcnM7XG4gICAgICB9XG4gICAgICByZXR1cm4gbmV3IE9yaWdQZWVyQ29ubmVjdGlvbihwY0NvbmZpZywgcGNDb25zdHJhaW50cyk7XG4gICAgfTtcbiAgICB3aW5kb3cuUlRDUGVlckNvbm5lY3Rpb24ucHJvdG90eXBlID0gT3JpZ1BlZXJDb25uZWN0aW9uLnByb3RvdHlwZTtcbiAgICAvLyB3cmFwIHN0YXRpYyBtZXRob2RzLiBDdXJyZW50bHkganVzdCBnZW5lcmF0ZUNlcnRpZmljYXRlLlxuICAgIGlmICgnZ2VuZXJhdGVDZXJ0aWZpY2F0ZScgaW4gd2luZG93LlJUQ1BlZXJDb25uZWN0aW9uKSB7XG4gICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkod2luZG93LlJUQ1BlZXJDb25uZWN0aW9uLCAnZ2VuZXJhdGVDZXJ0aWZpY2F0ZScsIHtcbiAgICAgICAgZ2V0OiBmdW5jdGlvbigpIHtcbiAgICAgICAgICByZXR1cm4gT3JpZ1BlZXJDb25uZWN0aW9uLmdlbmVyYXRlQ2VydGlmaWNhdGU7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cbiAgfSxcbiAgc2hpbVRyYWNrRXZlbnRUcmFuc2NlaXZlcjogZnVuY3Rpb24od2luZG93KSB7XG4gICAgLy8gQWRkIGV2ZW50LnRyYW5zY2VpdmVyIG1lbWJlciBvdmVyIGRlcHJlY2F0ZWQgZXZlbnQucmVjZWl2ZXJcbiAgICBpZiAodHlwZW9mIHdpbmRvdyA9PT0gJ29iamVjdCcgJiYgd2luZG93LlJUQ1BlZXJDb25uZWN0aW9uICYmXG4gICAgICAgICgncmVjZWl2ZXInIGluIHdpbmRvdy5SVENUcmFja0V2ZW50LnByb3RvdHlwZSkgJiZcbiAgICAgICAgLy8gY2FuJ3QgY2hlY2sgJ3RyYW5zY2VpdmVyJyBpbiB3aW5kb3cuUlRDVHJhY2tFdmVudC5wcm90b3R5cGUsIGFzIGl0IGlzXG4gICAgICAgIC8vIGRlZmluZWQgZm9yIHNvbWUgcmVhc29uIGV2ZW4gd2hlbiB3aW5kb3cuUlRDVHJhbnNjZWl2ZXIgaXMgbm90LlxuICAgICAgICAhd2luZG93LlJUQ1RyYW5zY2VpdmVyKSB7XG4gICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkod2luZG93LlJUQ1RyYWNrRXZlbnQucHJvdG90eXBlLCAndHJhbnNjZWl2ZXInLCB7XG4gICAgICAgIGdldDogZnVuY3Rpb24oKSB7XG4gICAgICAgICAgcmV0dXJuIHtyZWNlaXZlcjogdGhpcy5yZWNlaXZlcn07XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cbiAgfVxufTtcblxuLy8gRXhwb3NlIHB1YmxpYyBtZXRob2RzLlxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIHNoaW1DYWxsYmFja3NBUEk6IHNhZmFyaVNoaW0uc2hpbUNhbGxiYWNrc0FQSSxcbiAgc2hpbUxvY2FsU3RyZWFtc0FQSTogc2FmYXJpU2hpbS5zaGltTG9jYWxTdHJlYW1zQVBJLFxuICBzaGltUmVtb3RlU3RyZWFtc0FQSTogc2FmYXJpU2hpbS5zaGltUmVtb3RlU3RyZWFtc0FQSSxcbiAgc2hpbUdldFVzZXJNZWRpYTogc2FmYXJpU2hpbS5zaGltR2V0VXNlck1lZGlhLFxuICBzaGltUlRDSWNlU2VydmVyVXJsczogc2FmYXJpU2hpbS5zaGltUlRDSWNlU2VydmVyVXJscyxcbiAgc2hpbVRyYWNrRXZlbnRUcmFuc2NlaXZlcjogc2FmYXJpU2hpbS5zaGltVHJhY2tFdmVudFRyYW5zY2VpdmVyXG4gIC8vIFRPRE9cbiAgLy8gc2hpbVBlZXJDb25uZWN0aW9uOiBzYWZhcmlTaGltLnNoaW1QZWVyQ29ubmVjdGlvblxufTtcbiIsIi8qXG4gKiAgQ29weXJpZ2h0IChjKSAyMDE2IFRoZSBXZWJSVEMgcHJvamVjdCBhdXRob3JzLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICpcbiAqICBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlXG4gKiAgdGhhdCBjYW4gYmUgZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZSBpbiB0aGUgcm9vdCBvZiB0aGUgc291cmNlXG4gKiAgdHJlZS5cbiAqL1xuIC8qIGVzbGludC1lbnYgbm9kZSAqL1xuJ3VzZSBzdHJpY3QnO1xuXG52YXIgbG9nRGlzYWJsZWRfID0gdHJ1ZTtcbnZhciBkZXByZWNhdGlvbldhcm5pbmdzXyA9IHRydWU7XG5cbi8vIFV0aWxpdHkgbWV0aG9kcy5cbnZhciB1dGlscyA9IHtcbiAgZGlzYWJsZUxvZzogZnVuY3Rpb24oYm9vbCkge1xuICAgIGlmICh0eXBlb2YgYm9vbCAhPT0gJ2Jvb2xlYW4nKSB7XG4gICAgICByZXR1cm4gbmV3IEVycm9yKCdBcmd1bWVudCB0eXBlOiAnICsgdHlwZW9mIGJvb2wgK1xuICAgICAgICAgICcuIFBsZWFzZSB1c2UgYSBib29sZWFuLicpO1xuICAgIH1cbiAgICBsb2dEaXNhYmxlZF8gPSBib29sO1xuICAgIHJldHVybiAoYm9vbCkgPyAnYWRhcHRlci5qcyBsb2dnaW5nIGRpc2FibGVkJyA6XG4gICAgICAgICdhZGFwdGVyLmpzIGxvZ2dpbmcgZW5hYmxlZCc7XG4gIH0sXG5cbiAgLyoqXG4gICAqIERpc2FibGUgb3IgZW5hYmxlIGRlcHJlY2F0aW9uIHdhcm5pbmdzXG4gICAqIEBwYXJhbSB7IWJvb2xlYW59IGJvb2wgc2V0IHRvIHRydWUgdG8gZGlzYWJsZSB3YXJuaW5ncy5cbiAgICovXG4gIGRpc2FibGVXYXJuaW5nczogZnVuY3Rpb24oYm9vbCkge1xuICAgIGlmICh0eXBlb2YgYm9vbCAhPT0gJ2Jvb2xlYW4nKSB7XG4gICAgICByZXR1cm4gbmV3IEVycm9yKCdBcmd1bWVudCB0eXBlOiAnICsgdHlwZW9mIGJvb2wgK1xuICAgICAgICAgICcuIFBsZWFzZSB1c2UgYSBib29sZWFuLicpO1xuICAgIH1cbiAgICBkZXByZWNhdGlvbldhcm5pbmdzXyA9ICFib29sO1xuICAgIHJldHVybiAnYWRhcHRlci5qcyBkZXByZWNhdGlvbiB3YXJuaW5ncyAnICsgKGJvb2wgPyAnZGlzYWJsZWQnIDogJ2VuYWJsZWQnKTtcbiAgfSxcblxuICBsb2c6IGZ1bmN0aW9uKCkge1xuICAgIGlmICh0eXBlb2Ygd2luZG93ID09PSAnb2JqZWN0Jykge1xuICAgICAgaWYgKGxvZ0Rpc2FibGVkXykge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBpZiAodHlwZW9mIGNvbnNvbGUgIT09ICd1bmRlZmluZWQnICYmIHR5cGVvZiBjb25zb2xlLmxvZyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICBjb25zb2xlLmxvZy5hcHBseShjb25zb2xlLCBhcmd1bWVudHMpO1xuICAgICAgfVxuICAgIH1cbiAgfSxcblxuICAvKipcbiAgICogU2hvd3MgYSBkZXByZWNhdGlvbiB3YXJuaW5nIHN1Z2dlc3RpbmcgdGhlIG1vZGVybiBhbmQgc3BlYy1jb21wYXRpYmxlIEFQSS5cbiAgICovXG4gIGRlcHJlY2F0ZWQ6IGZ1bmN0aW9uKG9sZE1ldGhvZCwgbmV3TWV0aG9kKSB7XG4gICAgaWYgKCFkZXByZWNhdGlvbldhcm5pbmdzXykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zb2xlLndhcm4ob2xkTWV0aG9kICsgJyBpcyBkZXByZWNhdGVkLCBwbGVhc2UgdXNlICcgKyBuZXdNZXRob2QgK1xuICAgICAgICAnIGluc3RlYWQuJyk7XG4gIH0sXG5cbiAgLyoqXG4gICAqIEV4dHJhY3QgYnJvd3NlciB2ZXJzaW9uIG91dCBvZiB0aGUgcHJvdmlkZWQgdXNlciBhZ2VudCBzdHJpbmcuXG4gICAqXG4gICAqIEBwYXJhbSB7IXN0cmluZ30gdWFzdHJpbmcgdXNlckFnZW50IHN0cmluZy5cbiAgICogQHBhcmFtIHshc3RyaW5nfSBleHByIFJlZ3VsYXIgZXhwcmVzc2lvbiB1c2VkIGFzIG1hdGNoIGNyaXRlcmlhLlxuICAgKiBAcGFyYW0geyFudW1iZXJ9IHBvcyBwb3NpdGlvbiBpbiB0aGUgdmVyc2lvbiBzdHJpbmcgdG8gYmUgcmV0dXJuZWQuXG4gICAqIEByZXR1cm4geyFudW1iZXJ9IGJyb3dzZXIgdmVyc2lvbi5cbiAgICovXG4gIGV4dHJhY3RWZXJzaW9uOiBmdW5jdGlvbih1YXN0cmluZywgZXhwciwgcG9zKSB7XG4gICAgdmFyIG1hdGNoID0gdWFzdHJpbmcubWF0Y2goZXhwcik7XG4gICAgcmV0dXJuIG1hdGNoICYmIG1hdGNoLmxlbmd0aCA+PSBwb3MgJiYgcGFyc2VJbnQobWF0Y2hbcG9zXSwgMTApO1xuICB9LFxuXG4gIC8qKlxuICAgKiBCcm93c2VyIGRldGVjdG9yLlxuICAgKlxuICAgKiBAcmV0dXJuIHtvYmplY3R9IHJlc3VsdCBjb250YWluaW5nIGJyb3dzZXIgYW5kIHZlcnNpb25cbiAgICogICAgIHByb3BlcnRpZXMuXG4gICAqL1xuICBkZXRlY3RCcm93c2VyOiBmdW5jdGlvbih3aW5kb3cpIHtcbiAgICB2YXIgbmF2aWdhdG9yID0gd2luZG93ICYmIHdpbmRvdy5uYXZpZ2F0b3I7XG5cbiAgICAvLyBSZXR1cm5lZCByZXN1bHQgb2JqZWN0LlxuICAgIHZhciByZXN1bHQgPSB7fTtcbiAgICByZXN1bHQuYnJvd3NlciA9IG51bGw7XG4gICAgcmVzdWx0LnZlcnNpb24gPSBudWxsO1xuXG4gICAgLy8gRmFpbCBlYXJseSBpZiBpdCdzIG5vdCBhIGJyb3dzZXJcbiAgICBpZiAodHlwZW9mIHdpbmRvdyA9PT0gJ3VuZGVmaW5lZCcgfHwgIXdpbmRvdy5uYXZpZ2F0b3IpIHtcbiAgICAgIHJlc3VsdC5icm93c2VyID0gJ05vdCBhIGJyb3dzZXIuJztcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLy8gRmlyZWZveC5cbiAgICBpZiAobmF2aWdhdG9yLm1vekdldFVzZXJNZWRpYSkge1xuICAgICAgcmVzdWx0LmJyb3dzZXIgPSAnZmlyZWZveCc7XG4gICAgICByZXN1bHQudmVyc2lvbiA9IHRoaXMuZXh0cmFjdFZlcnNpb24obmF2aWdhdG9yLnVzZXJBZ2VudCxcbiAgICAgICAgICAvRmlyZWZveFxcLyhcXGQrKVxcLi8sIDEpO1xuICAgIH0gZWxzZSBpZiAobmF2aWdhdG9yLndlYmtpdEdldFVzZXJNZWRpYSkge1xuICAgICAgLy8gQ2hyb21lLCBDaHJvbWl1bSwgV2VidmlldywgT3BlcmEsIGFsbCB1c2UgdGhlIGNocm9tZSBzaGltIGZvciBub3dcbiAgICAgIGlmICh3aW5kb3cud2Via2l0UlRDUGVlckNvbm5lY3Rpb24pIHtcbiAgICAgICAgcmVzdWx0LmJyb3dzZXIgPSAnY2hyb21lJztcbiAgICAgICAgcmVzdWx0LnZlcnNpb24gPSB0aGlzLmV4dHJhY3RWZXJzaW9uKG5hdmlnYXRvci51c2VyQWdlbnQsXG4gICAgICAgICAgL0Nocm9tKGV8aXVtKVxcLyhcXGQrKVxcLi8sIDIpO1xuICAgICAgfSBlbHNlIHsgLy8gU2FmYXJpIChpbiBhbiB1bnB1Ymxpc2hlZCB2ZXJzaW9uKSBvciB1bmtub3duIHdlYmtpdC1iYXNlZC5cbiAgICAgICAgaWYgKG5hdmlnYXRvci51c2VyQWdlbnQubWF0Y2goL1ZlcnNpb25cXC8oXFxkKykuKFxcZCspLykpIHtcbiAgICAgICAgICByZXN1bHQuYnJvd3NlciA9ICdzYWZhcmknO1xuICAgICAgICAgIHJlc3VsdC52ZXJzaW9uID0gdGhpcy5leHRyYWN0VmVyc2lvbihuYXZpZ2F0b3IudXNlckFnZW50LFxuICAgICAgICAgICAgL0FwcGxlV2ViS2l0XFwvKFxcZCspXFwuLywgMSk7XG4gICAgICAgIH0gZWxzZSB7IC8vIHVua25vd24gd2Via2l0LWJhc2VkIGJyb3dzZXIuXG4gICAgICAgICAgcmVzdWx0LmJyb3dzZXIgPSAnVW5zdXBwb3J0ZWQgd2Via2l0LWJhc2VkIGJyb3dzZXIgJyArXG4gICAgICAgICAgICAgICd3aXRoIEdVTSBzdXBwb3J0IGJ1dCBubyBXZWJSVEMgc3VwcG9ydC4nO1xuICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKG5hdmlnYXRvci5tZWRpYURldmljZXMgJiZcbiAgICAgICAgbmF2aWdhdG9yLnVzZXJBZ2VudC5tYXRjaCgvRWRnZVxcLyhcXGQrKS4oXFxkKykkLykpIHsgLy8gRWRnZS5cbiAgICAgIHJlc3VsdC5icm93c2VyID0gJ2VkZ2UnO1xuICAgICAgcmVzdWx0LnZlcnNpb24gPSB0aGlzLmV4dHJhY3RWZXJzaW9uKG5hdmlnYXRvci51c2VyQWdlbnQsXG4gICAgICAgICAgL0VkZ2VcXC8oXFxkKykuKFxcZCspJC8sIDIpO1xuICAgIH0gZWxzZSBpZiAobmF2aWdhdG9yLm1lZGlhRGV2aWNlcyAmJlxuICAgICAgICBuYXZpZ2F0b3IudXNlckFnZW50Lm1hdGNoKC9BcHBsZVdlYktpdFxcLyhcXGQrKVxcLi8pKSB7XG4gICAgICAgIC8vIFNhZmFyaSwgd2l0aCB3ZWJraXRHZXRVc2VyTWVkaWEgcmVtb3ZlZC5cbiAgICAgIHJlc3VsdC5icm93c2VyID0gJ3NhZmFyaSc7XG4gICAgICByZXN1bHQudmVyc2lvbiA9IHRoaXMuZXh0cmFjdFZlcnNpb24obmF2aWdhdG9yLnVzZXJBZ2VudCxcbiAgICAgICAgICAvQXBwbGVXZWJLaXRcXC8oXFxkKylcXC4vLCAxKTtcbiAgICB9IGVsc2UgeyAvLyBEZWZhdWx0IGZhbGx0aHJvdWdoOiBub3Qgc3VwcG9ydGVkLlxuICAgICAgcmVzdWx0LmJyb3dzZXIgPSAnTm90IGEgc3VwcG9ydGVkIGJyb3dzZXIuJztcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfSxcblxufTtcblxuLy8gRXhwb3J0LlxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIGxvZzogdXRpbHMubG9nLFxuICBkZXByZWNhdGVkOiB1dGlscy5kZXByZWNhdGVkLFxuICBkaXNhYmxlTG9nOiB1dGlscy5kaXNhYmxlTG9nLFxuICBkaXNhYmxlV2FybmluZ3M6IHV0aWxzLmRpc2FibGVXYXJuaW5ncyxcbiAgZXh0cmFjdFZlcnNpb246IHV0aWxzLmV4dHJhY3RWZXJzaW9uLFxuICBzaGltQ3JlYXRlT2JqZWN0VVJMOiB1dGlscy5zaGltQ3JlYXRlT2JqZWN0VVJMLFxuICBkZXRlY3RCcm93c2VyOiB1dGlscy5kZXRlY3RCcm93c2VyLmJpbmQodXRpbHMpXG59O1xuIiwiLypcclxuV2lsZEVtaXR0ZXIuanMgaXMgYSBzbGltIGxpdHRsZSBldmVudCBlbWl0dGVyIGJ5IEBoZW5yaWtqb3JldGVnIGxhcmdlbHkgYmFzZWRcclxub24gQHZpc2lvbm1lZGlhJ3MgRW1pdHRlciBmcm9tIFVJIEtpdC5cclxuXHJcbldoeT8gSSB3YW50ZWQgaXQgc3RhbmRhbG9uZS5cclxuXHJcbkkgYWxzbyB3YW50ZWQgc3VwcG9ydCBmb3Igd2lsZGNhcmQgZW1pdHRlcnMgbGlrZSB0aGlzOlxyXG5cclxuZW1pdHRlci5vbignKicsIGZ1bmN0aW9uIChldmVudE5hbWUsIG90aGVyLCBldmVudCwgcGF5bG9hZHMpIHtcclxuXHJcbn0pO1xyXG5cclxuZW1pdHRlci5vbignc29tZW5hbWVzcGFjZSonLCBmdW5jdGlvbiAoZXZlbnROYW1lLCBwYXlsb2Fkcykge1xyXG5cclxufSk7XHJcblxyXG5QbGVhc2Ugbm90ZSB0aGF0IGNhbGxiYWNrcyB0cmlnZ2VyZWQgYnkgd2lsZGNhcmQgcmVnaXN0ZXJlZCBldmVudHMgYWxzbyBnZXRcclxudGhlIGV2ZW50IG5hbWUgYXMgdGhlIGZpcnN0IGFyZ3VtZW50LlxyXG4qL1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBXaWxkRW1pdHRlcjtcclxuXHJcbmZ1bmN0aW9uIFdpbGRFbWl0dGVyKCkgeyB9XHJcblxyXG5XaWxkRW1pdHRlci5taXhpbiA9IGZ1bmN0aW9uIChjb25zdHJ1Y3Rvcikge1xyXG4gICAgdmFyIHByb3RvdHlwZSA9IGNvbnN0cnVjdG9yLnByb3RvdHlwZSB8fCBjb25zdHJ1Y3RvcjtcclxuXHJcbiAgICBwcm90b3R5cGUuaXNXaWxkRW1pdHRlcj0gdHJ1ZTtcclxuXHJcbiAgICAvLyBMaXN0ZW4gb24gdGhlIGdpdmVuIGBldmVudGAgd2l0aCBgZm5gLiBTdG9yZSBhIGdyb3VwIG5hbWUgaWYgcHJlc2VudC5cclxuICAgIHByb3RvdHlwZS5vbiA9IGZ1bmN0aW9uIChldmVudCwgZ3JvdXBOYW1lLCBmbikge1xyXG4gICAgICAgIHRoaXMuY2FsbGJhY2tzID0gdGhpcy5jYWxsYmFja3MgfHwge307XHJcbiAgICAgICAgdmFyIGhhc0dyb3VwID0gKGFyZ3VtZW50cy5sZW5ndGggPT09IDMpLFxyXG4gICAgICAgICAgICBncm91cCA9IGhhc0dyb3VwID8gYXJndW1lbnRzWzFdIDogdW5kZWZpbmVkLFxyXG4gICAgICAgICAgICBmdW5jID0gaGFzR3JvdXAgPyBhcmd1bWVudHNbMl0gOiBhcmd1bWVudHNbMV07XHJcbiAgICAgICAgZnVuYy5fZ3JvdXBOYW1lID0gZ3JvdXA7XHJcbiAgICAgICAgKHRoaXMuY2FsbGJhY2tzW2V2ZW50XSA9IHRoaXMuY2FsbGJhY2tzW2V2ZW50XSB8fCBbXSkucHVzaChmdW5jKTtcclxuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH07XHJcblxyXG4gICAgLy8gQWRkcyBhbiBgZXZlbnRgIGxpc3RlbmVyIHRoYXQgd2lsbCBiZSBpbnZva2VkIGEgc2luZ2xlXHJcbiAgICAvLyB0aW1lIHRoZW4gYXV0b21hdGljYWxseSByZW1vdmVkLlxyXG4gICAgcHJvdG90eXBlLm9uY2UgPSBmdW5jdGlvbiAoZXZlbnQsIGdyb3VwTmFtZSwgZm4pIHtcclxuICAgICAgICB2YXIgc2VsZiA9IHRoaXMsXHJcbiAgICAgICAgICAgIGhhc0dyb3VwID0gKGFyZ3VtZW50cy5sZW5ndGggPT09IDMpLFxyXG4gICAgICAgICAgICBncm91cCA9IGhhc0dyb3VwID8gYXJndW1lbnRzWzFdIDogdW5kZWZpbmVkLFxyXG4gICAgICAgICAgICBmdW5jID0gaGFzR3JvdXAgPyBhcmd1bWVudHNbMl0gOiBhcmd1bWVudHNbMV07XHJcbiAgICAgICAgZnVuY3Rpb24gb24oKSB7XHJcbiAgICAgICAgICAgIHNlbGYub2ZmKGV2ZW50LCBvbik7XHJcbiAgICAgICAgICAgIGZ1bmMuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy5vbihldmVudCwgZ3JvdXAsIG9uKTtcclxuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH07XHJcblxyXG4gICAgLy8gVW5iaW5kcyBhbiBlbnRpcmUgZ3JvdXBcclxuICAgIHByb3RvdHlwZS5yZWxlYXNlR3JvdXAgPSBmdW5jdGlvbiAoZ3JvdXBOYW1lKSB7XHJcbiAgICAgICAgdGhpcy5jYWxsYmFja3MgPSB0aGlzLmNhbGxiYWNrcyB8fCB7fTtcclxuICAgICAgICB2YXIgaXRlbSwgaSwgbGVuLCBoYW5kbGVycztcclxuICAgICAgICBmb3IgKGl0ZW0gaW4gdGhpcy5jYWxsYmFja3MpIHtcclxuICAgICAgICAgICAgaGFuZGxlcnMgPSB0aGlzLmNhbGxiYWNrc1tpdGVtXTtcclxuICAgICAgICAgICAgZm9yIChpID0gMCwgbGVuID0gaGFuZGxlcnMubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcclxuICAgICAgICAgICAgICAgIGlmIChoYW5kbGVyc1tpXS5fZ3JvdXBOYW1lID09PSBncm91cE5hbWUpIHtcclxuICAgICAgICAgICAgICAgICAgICAvL2NvbnNvbGUubG9nKCdyZW1vdmluZycpO1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIHJlbW92ZSBpdCBhbmQgc2hvcnRlbiB0aGUgYXJyYXkgd2UncmUgbG9vcGluZyB0aHJvdWdoXHJcbiAgICAgICAgICAgICAgICAgICAgaGFuZGxlcnMuc3BsaWNlKGksIDEpO1xyXG4gICAgICAgICAgICAgICAgICAgIGktLTtcclxuICAgICAgICAgICAgICAgICAgICBsZW4tLTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH07XHJcblxyXG4gICAgLy8gUmVtb3ZlIHRoZSBnaXZlbiBjYWxsYmFjayBmb3IgYGV2ZW50YCBvciBhbGxcclxuICAgIC8vIHJlZ2lzdGVyZWQgY2FsbGJhY2tzLlxyXG4gICAgcHJvdG90eXBlLm9mZiA9IGZ1bmN0aW9uIChldmVudCwgZm4pIHtcclxuICAgICAgICB0aGlzLmNhbGxiYWNrcyA9IHRoaXMuY2FsbGJhY2tzIHx8IHt9O1xyXG4gICAgICAgIHZhciBjYWxsYmFja3MgPSB0aGlzLmNhbGxiYWNrc1tldmVudF0sXHJcbiAgICAgICAgICAgIGk7XHJcblxyXG4gICAgICAgIGlmICghY2FsbGJhY2tzKSByZXR1cm4gdGhpcztcclxuXHJcbiAgICAgICAgLy8gcmVtb3ZlIGFsbCBoYW5kbGVyc1xyXG4gICAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAxKSB7XHJcbiAgICAgICAgICAgIGRlbGV0ZSB0aGlzLmNhbGxiYWNrc1tldmVudF07XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gcmVtb3ZlIHNwZWNpZmljIGhhbmRsZXJcclxuICAgICAgICBpID0gY2FsbGJhY2tzLmluZGV4T2YoZm4pO1xyXG4gICAgICAgIGNhbGxiYWNrcy5zcGxpY2UoaSwgMSk7XHJcbiAgICAgICAgaWYgKGNhbGxiYWNrcy5sZW5ndGggPT09IDApIHtcclxuICAgICAgICAgICAgZGVsZXRlIHRoaXMuY2FsbGJhY2tzW2V2ZW50XTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICB9O1xyXG5cclxuICAgIC8vLyBFbWl0IGBldmVudGAgd2l0aCB0aGUgZ2l2ZW4gYXJncy5cclxuICAgIC8vIGFsc28gY2FsbHMgYW55IGAqYCBoYW5kbGVyc1xyXG4gICAgcHJvdG90eXBlLmVtaXQgPSBmdW5jdGlvbiAoZXZlbnQpIHtcclxuICAgICAgICB0aGlzLmNhbGxiYWNrcyA9IHRoaXMuY2FsbGJhY2tzIHx8IHt9O1xyXG4gICAgICAgIHZhciBhcmdzID0gW10uc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpLFxyXG4gICAgICAgICAgICBjYWxsYmFja3MgPSB0aGlzLmNhbGxiYWNrc1tldmVudF0sXHJcbiAgICAgICAgICAgIHNwZWNpYWxDYWxsYmFja3MgPSB0aGlzLmdldFdpbGRjYXJkQ2FsbGJhY2tzKGV2ZW50KSxcclxuICAgICAgICAgICAgaSxcclxuICAgICAgICAgICAgbGVuLFxyXG4gICAgICAgICAgICBpdGVtLFxyXG4gICAgICAgICAgICBsaXN0ZW5lcnM7XHJcblxyXG4gICAgICAgIGlmIChjYWxsYmFja3MpIHtcclxuICAgICAgICAgICAgbGlzdGVuZXJzID0gY2FsbGJhY2tzLnNsaWNlKCk7XHJcbiAgICAgICAgICAgIGZvciAoaSA9IDAsIGxlbiA9IGxpc3RlbmVycy5sZW5ndGg7IGkgPCBsZW47ICsraSkge1xyXG4gICAgICAgICAgICAgICAgaWYgKCFsaXN0ZW5lcnNbaV0pIHtcclxuICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGxpc3RlbmVyc1tpXS5hcHBseSh0aGlzLCBhcmdzKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKHNwZWNpYWxDYWxsYmFja3MpIHtcclxuICAgICAgICAgICAgbGVuID0gc3BlY2lhbENhbGxiYWNrcy5sZW5ndGg7XHJcbiAgICAgICAgICAgIGxpc3RlbmVycyA9IHNwZWNpYWxDYWxsYmFja3Muc2xpY2UoKTtcclxuICAgICAgICAgICAgZm9yIChpID0gMCwgbGVuID0gbGlzdGVuZXJzLmxlbmd0aDsgaSA8IGxlbjsgKytpKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoIWxpc3RlbmVyc1tpXSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgbGlzdGVuZXJzW2ldLmFwcGx5KHRoaXMsIFtldmVudF0uY29uY2F0KGFyZ3MpKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICB9O1xyXG5cclxuICAgIC8vIEhlbHBlciBmb3IgZm9yIGZpbmRpbmcgc3BlY2lhbCB3aWxkY2FyZCBldmVudCBoYW5kbGVycyB0aGF0IG1hdGNoIHRoZSBldmVudFxyXG4gICAgcHJvdG90eXBlLmdldFdpbGRjYXJkQ2FsbGJhY2tzID0gZnVuY3Rpb24gKGV2ZW50TmFtZSkge1xyXG4gICAgICAgIHRoaXMuY2FsbGJhY2tzID0gdGhpcy5jYWxsYmFja3MgfHwge307XHJcbiAgICAgICAgdmFyIGl0ZW0sXHJcbiAgICAgICAgICAgIHNwbGl0LFxyXG4gICAgICAgICAgICByZXN1bHQgPSBbXTtcclxuXHJcbiAgICAgICAgZm9yIChpdGVtIGluIHRoaXMuY2FsbGJhY2tzKSB7XHJcbiAgICAgICAgICAgIHNwbGl0ID0gaXRlbS5zcGxpdCgnKicpO1xyXG4gICAgICAgICAgICBpZiAoaXRlbSA9PT0gJyonIHx8IChzcGxpdC5sZW5ndGggPT09IDIgJiYgZXZlbnROYW1lLnNsaWNlKDAsIHNwbGl0WzBdLmxlbmd0aCkgPT09IHNwbGl0WzBdKSkge1xyXG4gICAgICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0LmNvbmNhdCh0aGlzLmNhbGxiYWNrc1tpdGVtXSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcclxuICAgIH07XHJcblxyXG59O1xyXG5cclxuV2lsZEVtaXR0ZXIubWl4aW4oV2lsZEVtaXR0ZXIpO1xyXG4iLCIvKiFcbiAqIEV2ZW50RW1pdHRlciB2NC4yLjkgLSBnaXQuaW8vZWVcbiAqIE9saXZlciBDYWxkd2VsbFxuICogTUlUIGxpY2Vuc2VcbiAqIEBwcmVzZXJ2ZVxuICovXG5cbihmdW5jdGlvbiAoKSB7XG4gICAgJ3VzZSBzdHJpY3QnO1xuXG4gICAgLyoqXG4gICAgICogQ2xhc3MgZm9yIG1hbmFnaW5nIGV2ZW50cy5cbiAgICAgKiBDYW4gYmUgZXh0ZW5kZWQgdG8gcHJvdmlkZSBldmVudCBmdW5jdGlvbmFsaXR5IGluIG90aGVyIGNsYXNzZXMuXG4gICAgICpcbiAgICAgKiBAY2xhc3MgRXZlbnRFbWl0dGVyIE1hbmFnZXMgZXZlbnQgcmVnaXN0ZXJpbmcgYW5kIGVtaXR0aW5nLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIEV2ZW50RW1pdHRlcigpIHt9XG5cbiAgICAvLyBTaG9ydGN1dHMgdG8gaW1wcm92ZSBzcGVlZCBhbmQgc2l6ZVxuICAgIHZhciBwcm90byA9IEV2ZW50RW1pdHRlci5wcm90b3R5cGU7XG4gICAgdmFyIGV4cG9ydHMgPSB0aGlzO1xuICAgIHZhciBvcmlnaW5hbEdsb2JhbFZhbHVlID0gZXhwb3J0cy5FdmVudEVtaXR0ZXI7XG5cbiAgICAvKipcbiAgICAgKiBGaW5kcyB0aGUgaW5kZXggb2YgdGhlIGxpc3RlbmVyIGZvciB0aGUgZXZlbnQgaW4gaXRzIHN0b3JhZ2UgYXJyYXkuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9uW119IGxpc3RlbmVycyBBcnJheSBvZiBsaXN0ZW5lcnMgdG8gc2VhcmNoIHRocm91Z2guXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gbGlzdGVuZXIgTWV0aG9kIHRvIGxvb2sgZm9yLlxuICAgICAqIEByZXR1cm4ge051bWJlcn0gSW5kZXggb2YgdGhlIHNwZWNpZmllZCBsaXN0ZW5lciwgLTEgaWYgbm90IGZvdW5kXG4gICAgICogQGFwaSBwcml2YXRlXG4gICAgICovXG4gICAgZnVuY3Rpb24gaW5kZXhPZkxpc3RlbmVyKGxpc3RlbmVycywgbGlzdGVuZXIpIHtcbiAgICAgICAgdmFyIGkgPSBsaXN0ZW5lcnMubGVuZ3RoO1xuICAgICAgICB3aGlsZSAoaS0tKSB7XG4gICAgICAgICAgICBpZiAobGlzdGVuZXJzW2ldLmxpc3RlbmVyID09PSBsaXN0ZW5lcikge1xuICAgICAgICAgICAgICAgIHJldHVybiBpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIC0xO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEFsaWFzIGEgbWV0aG9kIHdoaWxlIGtlZXBpbmcgdGhlIGNvbnRleHQgY29ycmVjdCwgdG8gYWxsb3cgZm9yIG92ZXJ3cml0aW5nIG9mIHRhcmdldCBtZXRob2QuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gbmFtZSBUaGUgbmFtZSBvZiB0aGUgdGFyZ2V0IG1ldGhvZC5cbiAgICAgKiBAcmV0dXJuIHtGdW5jdGlvbn0gVGhlIGFsaWFzZWQgbWV0aG9kXG4gICAgICogQGFwaSBwcml2YXRlXG4gICAgICovXG4gICAgZnVuY3Rpb24gYWxpYXMobmFtZSkge1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24gYWxpYXNDbG9zdXJlKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXNbbmFtZV0uYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBsaXN0ZW5lciBhcnJheSBmb3IgdGhlIHNwZWNpZmllZCBldmVudC5cbiAgICAgKiBXaWxsIGluaXRpYWxpc2UgdGhlIGV2ZW50IG9iamVjdCBhbmQgbGlzdGVuZXIgYXJyYXlzIGlmIHJlcXVpcmVkLlxuICAgICAqIFdpbGwgcmV0dXJuIGFuIG9iamVjdCBpZiB5b3UgdXNlIGEgcmVnZXggc2VhcmNoLiBUaGUgb2JqZWN0IGNvbnRhaW5zIGtleXMgZm9yIGVhY2ggbWF0Y2hlZCBldmVudC4gU28gL2JhW3J6XS8gbWlnaHQgcmV0dXJuIGFuIG9iamVjdCBjb250YWluaW5nIGJhciBhbmQgYmF6LiBCdXQgb25seSBpZiB5b3UgaGF2ZSBlaXRoZXIgZGVmaW5lZCB0aGVtIHdpdGggZGVmaW5lRXZlbnQgb3IgYWRkZWQgc29tZSBsaXN0ZW5lcnMgdG8gdGhlbS5cbiAgICAgKiBFYWNoIHByb3BlcnR5IGluIHRoZSBvYmplY3QgcmVzcG9uc2UgaXMgYW4gYXJyYXkgb2YgbGlzdGVuZXIgZnVuY3Rpb25zLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtTdHJpbmd8UmVnRXhwfSBldnQgTmFtZSBvZiB0aGUgZXZlbnQgdG8gcmV0dXJuIHRoZSBsaXN0ZW5lcnMgZnJvbS5cbiAgICAgKiBAcmV0dXJuIHtGdW5jdGlvbltdfE9iamVjdH0gQWxsIGxpc3RlbmVyIGZ1bmN0aW9ucyBmb3IgdGhlIGV2ZW50LlxuICAgICAqL1xuICAgIHByb3RvLmdldExpc3RlbmVycyA9IGZ1bmN0aW9uIGdldExpc3RlbmVycyhldnQpIHtcbiAgICAgICAgdmFyIGV2ZW50cyA9IHRoaXMuX2dldEV2ZW50cygpO1xuICAgICAgICB2YXIgcmVzcG9uc2U7XG4gICAgICAgIHZhciBrZXk7XG5cbiAgICAgICAgLy8gUmV0dXJuIGEgY29uY2F0ZW5hdGVkIGFycmF5IG9mIGFsbCBtYXRjaGluZyBldmVudHMgaWZcbiAgICAgICAgLy8gdGhlIHNlbGVjdG9yIGlzIGEgcmVndWxhciBleHByZXNzaW9uLlxuICAgICAgICBpZiAoZXZ0IGluc3RhbmNlb2YgUmVnRXhwKSB7XG4gICAgICAgICAgICByZXNwb25zZSA9IHt9O1xuICAgICAgICAgICAgZm9yIChrZXkgaW4gZXZlbnRzKSB7XG4gICAgICAgICAgICAgICAgaWYgKGV2ZW50cy5oYXNPd25Qcm9wZXJ0eShrZXkpICYmIGV2dC50ZXN0KGtleSkpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVzcG9uc2Vba2V5XSA9IGV2ZW50c1trZXldO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJlc3BvbnNlID0gZXZlbnRzW2V2dF0gfHwgKGV2ZW50c1tldnRdID0gW10pO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHJlc3BvbnNlO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBUYWtlcyBhIGxpc3Qgb2YgbGlzdGVuZXIgb2JqZWN0cyBhbmQgZmxhdHRlbnMgaXQgaW50byBhIGxpc3Qgb2YgbGlzdGVuZXIgZnVuY3Rpb25zLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtPYmplY3RbXX0gbGlzdGVuZXJzIFJhdyBsaXN0ZW5lciBvYmplY3RzLlxuICAgICAqIEByZXR1cm4ge0Z1bmN0aW9uW119IEp1c3QgdGhlIGxpc3RlbmVyIGZ1bmN0aW9ucy5cbiAgICAgKi9cbiAgICBwcm90by5mbGF0dGVuTGlzdGVuZXJzID0gZnVuY3Rpb24gZmxhdHRlbkxpc3RlbmVycyhsaXN0ZW5lcnMpIHtcbiAgICAgICAgdmFyIGZsYXRMaXN0ZW5lcnMgPSBbXTtcbiAgICAgICAgdmFyIGk7XG5cbiAgICAgICAgZm9yIChpID0gMDsgaSA8IGxpc3RlbmVycy5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICAgICAgZmxhdExpc3RlbmVycy5wdXNoKGxpc3RlbmVyc1tpXS5saXN0ZW5lcik7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gZmxhdExpc3RlbmVycztcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogRmV0Y2hlcyB0aGUgcmVxdWVzdGVkIGxpc3RlbmVycyB2aWEgZ2V0TGlzdGVuZXJzIGJ1dCB3aWxsIGFsd2F5cyByZXR1cm4gdGhlIHJlc3VsdHMgaW5zaWRlIGFuIG9iamVjdC4gVGhpcyBpcyBtYWlubHkgZm9yIGludGVybmFsIHVzZSBidXQgb3RoZXJzIG1heSBmaW5kIGl0IHVzZWZ1bC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfFJlZ0V4cH0gZXZ0IE5hbWUgb2YgdGhlIGV2ZW50IHRvIHJldHVybiB0aGUgbGlzdGVuZXJzIGZyb20uXG4gICAgICogQHJldHVybiB7T2JqZWN0fSBBbGwgbGlzdGVuZXIgZnVuY3Rpb25zIGZvciBhbiBldmVudCBpbiBhbiBvYmplY3QuXG4gICAgICovXG4gICAgcHJvdG8uZ2V0TGlzdGVuZXJzQXNPYmplY3QgPSBmdW5jdGlvbiBnZXRMaXN0ZW5lcnNBc09iamVjdChldnQpIHtcbiAgICAgICAgdmFyIGxpc3RlbmVycyA9IHRoaXMuZ2V0TGlzdGVuZXJzKGV2dCk7XG4gICAgICAgIHZhciByZXNwb25zZTtcblxuICAgICAgICBpZiAobGlzdGVuZXJzIGluc3RhbmNlb2YgQXJyYXkpIHtcbiAgICAgICAgICAgIHJlc3BvbnNlID0ge307XG4gICAgICAgICAgICByZXNwb25zZVtldnRdID0gbGlzdGVuZXJzO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHJlc3BvbnNlIHx8IGxpc3RlbmVycztcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQWRkcyBhIGxpc3RlbmVyIGZ1bmN0aW9uIHRvIHRoZSBzcGVjaWZpZWQgZXZlbnQuXG4gICAgICogVGhlIGxpc3RlbmVyIHdpbGwgbm90IGJlIGFkZGVkIGlmIGl0IGlzIGEgZHVwbGljYXRlLlxuICAgICAqIElmIHRoZSBsaXN0ZW5lciByZXR1cm5zIHRydWUgdGhlbiBpdCB3aWxsIGJlIHJlbW92ZWQgYWZ0ZXIgaXQgaXMgY2FsbGVkLlxuICAgICAqIElmIHlvdSBwYXNzIGEgcmVndWxhciBleHByZXNzaW9uIGFzIHRoZSBldmVudCBuYW1lIHRoZW4gdGhlIGxpc3RlbmVyIHdpbGwgYmUgYWRkZWQgdG8gYWxsIGV2ZW50cyB0aGF0IG1hdGNoIGl0LlxuICAgICAqXG4gICAgICogQHBhcmFtIHtTdHJpbmd8UmVnRXhwfSBldnQgTmFtZSBvZiB0aGUgZXZlbnQgdG8gYXR0YWNoIHRoZSBsaXN0ZW5lciB0by5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBsaXN0ZW5lciBNZXRob2QgdG8gYmUgY2FsbGVkIHdoZW4gdGhlIGV2ZW50IGlzIGVtaXR0ZWQuIElmIHRoZSBmdW5jdGlvbiByZXR1cm5zIHRydWUgdGhlbiBpdCB3aWxsIGJlIHJlbW92ZWQgYWZ0ZXIgY2FsbGluZy5cbiAgICAgKiBAcmV0dXJuIHtPYmplY3R9IEN1cnJlbnQgaW5zdGFuY2Ugb2YgRXZlbnRFbWl0dGVyIGZvciBjaGFpbmluZy5cbiAgICAgKi9cbiAgICBwcm90by5hZGRMaXN0ZW5lciA9IGZ1bmN0aW9uIGFkZExpc3RlbmVyKGV2dCwgbGlzdGVuZXIpIHtcbiAgICAgICAgdmFyIGxpc3RlbmVycyA9IHRoaXMuZ2V0TGlzdGVuZXJzQXNPYmplY3QoZXZ0KTtcbiAgICAgICAgdmFyIGxpc3RlbmVySXNXcmFwcGVkID0gdHlwZW9mIGxpc3RlbmVyID09PSAnb2JqZWN0JztcbiAgICAgICAgdmFyIGtleTtcblxuICAgICAgICBmb3IgKGtleSBpbiBsaXN0ZW5lcnMpIHtcbiAgICAgICAgICAgIGlmIChsaXN0ZW5lcnMuaGFzT3duUHJvcGVydHkoa2V5KSAmJiBpbmRleE9mTGlzdGVuZXIobGlzdGVuZXJzW2tleV0sIGxpc3RlbmVyKSA9PT0gLTEpIHtcbiAgICAgICAgICAgICAgICBsaXN0ZW5lcnNba2V5XS5wdXNoKGxpc3RlbmVySXNXcmFwcGVkID8gbGlzdGVuZXIgOiB7XG4gICAgICAgICAgICAgICAgICAgIGxpc3RlbmVyOiBsaXN0ZW5lcixcbiAgICAgICAgICAgICAgICAgICAgb25jZTogZmFsc2VcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBBbGlhcyBvZiBhZGRMaXN0ZW5lclxuICAgICAqL1xuICAgIHByb3RvLm9uID0gYWxpYXMoJ2FkZExpc3RlbmVyJyk7XG5cbiAgICAvKipcbiAgICAgKiBTZW1pLWFsaWFzIG9mIGFkZExpc3RlbmVyLiBJdCB3aWxsIGFkZCBhIGxpc3RlbmVyIHRoYXQgd2lsbCBiZVxuICAgICAqIGF1dG9tYXRpY2FsbHkgcmVtb3ZlZCBhZnRlciBpdHMgZmlyc3QgZXhlY3V0aW9uLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtTdHJpbmd8UmVnRXhwfSBldnQgTmFtZSBvZiB0aGUgZXZlbnQgdG8gYXR0YWNoIHRoZSBsaXN0ZW5lciB0by5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBsaXN0ZW5lciBNZXRob2QgdG8gYmUgY2FsbGVkIHdoZW4gdGhlIGV2ZW50IGlzIGVtaXR0ZWQuIElmIHRoZSBmdW5jdGlvbiByZXR1cm5zIHRydWUgdGhlbiBpdCB3aWxsIGJlIHJlbW92ZWQgYWZ0ZXIgY2FsbGluZy5cbiAgICAgKiBAcmV0dXJuIHtPYmplY3R9IEN1cnJlbnQgaW5zdGFuY2Ugb2YgRXZlbnRFbWl0dGVyIGZvciBjaGFpbmluZy5cbiAgICAgKi9cbiAgICBwcm90by5hZGRPbmNlTGlzdGVuZXIgPSBmdW5jdGlvbiBhZGRPbmNlTGlzdGVuZXIoZXZ0LCBsaXN0ZW5lcikge1xuICAgICAgICByZXR1cm4gdGhpcy5hZGRMaXN0ZW5lcihldnQsIHtcbiAgICAgICAgICAgIGxpc3RlbmVyOiBsaXN0ZW5lcixcbiAgICAgICAgICAgIG9uY2U6IHRydWVcbiAgICAgICAgfSk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEFsaWFzIG9mIGFkZE9uY2VMaXN0ZW5lci5cbiAgICAgKi9cbiAgICBwcm90by5vbmNlID0gYWxpYXMoJ2FkZE9uY2VMaXN0ZW5lcicpO1xuXG4gICAgLyoqXG4gICAgICogRGVmaW5lcyBhbiBldmVudCBuYW1lLiBUaGlzIGlzIHJlcXVpcmVkIGlmIHlvdSB3YW50IHRvIHVzZSBhIHJlZ2V4IHRvIGFkZCBhIGxpc3RlbmVyIHRvIG11bHRpcGxlIGV2ZW50cyBhdCBvbmNlLiBJZiB5b3UgZG9uJ3QgZG8gdGhpcyB0aGVuIGhvdyBkbyB5b3UgZXhwZWN0IGl0IHRvIGtub3cgd2hhdCBldmVudCB0byBhZGQgdG8/IFNob3VsZCBpdCBqdXN0IGFkZCB0byBldmVyeSBwb3NzaWJsZSBtYXRjaCBmb3IgYSByZWdleD8gTm8uIFRoYXQgaXMgc2NhcnkgYW5kIGJhZC5cbiAgICAgKiBZb3UgbmVlZCB0byB0ZWxsIGl0IHdoYXQgZXZlbnQgbmFtZXMgc2hvdWxkIGJlIG1hdGNoZWQgYnkgYSByZWdleC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBldnQgTmFtZSBvZiB0aGUgZXZlbnQgdG8gY3JlYXRlLlxuICAgICAqIEByZXR1cm4ge09iamVjdH0gQ3VycmVudCBpbnN0YW5jZSBvZiBFdmVudEVtaXR0ZXIgZm9yIGNoYWluaW5nLlxuICAgICAqL1xuICAgIHByb3RvLmRlZmluZUV2ZW50ID0gZnVuY3Rpb24gZGVmaW5lRXZlbnQoZXZ0KSB7XG4gICAgICAgIHRoaXMuZ2V0TGlzdGVuZXJzKGV2dCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBVc2VzIGRlZmluZUV2ZW50IHRvIGRlZmluZSBtdWx0aXBsZSBldmVudHMuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge1N0cmluZ1tdfSBldnRzIEFuIGFycmF5IG9mIGV2ZW50IG5hbWVzIHRvIGRlZmluZS5cbiAgICAgKiBAcmV0dXJuIHtPYmplY3R9IEN1cnJlbnQgaW5zdGFuY2Ugb2YgRXZlbnRFbWl0dGVyIGZvciBjaGFpbmluZy5cbiAgICAgKi9cbiAgICBwcm90by5kZWZpbmVFdmVudHMgPSBmdW5jdGlvbiBkZWZpbmVFdmVudHMoZXZ0cykge1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGV2dHMubGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgICAgICAgIHRoaXMuZGVmaW5lRXZlbnQoZXZ0c1tpXSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIFJlbW92ZXMgYSBsaXN0ZW5lciBmdW5jdGlvbiBmcm9tIHRoZSBzcGVjaWZpZWQgZXZlbnQuXG4gICAgICogV2hlbiBwYXNzZWQgYSByZWd1bGFyIGV4cHJlc3Npb24gYXMgdGhlIGV2ZW50IG5hbWUsIGl0IHdpbGwgcmVtb3ZlIHRoZSBsaXN0ZW5lciBmcm9tIGFsbCBldmVudHMgdGhhdCBtYXRjaCBpdC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfFJlZ0V4cH0gZXZ0IE5hbWUgb2YgdGhlIGV2ZW50IHRvIHJlbW92ZSB0aGUgbGlzdGVuZXIgZnJvbS5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBsaXN0ZW5lciBNZXRob2QgdG8gcmVtb3ZlIGZyb20gdGhlIGV2ZW50LlxuICAgICAqIEByZXR1cm4ge09iamVjdH0gQ3VycmVudCBpbnN0YW5jZSBvZiBFdmVudEVtaXR0ZXIgZm9yIGNoYWluaW5nLlxuICAgICAqL1xuICAgIHByb3RvLnJlbW92ZUxpc3RlbmVyID0gZnVuY3Rpb24gcmVtb3ZlTGlzdGVuZXIoZXZ0LCBsaXN0ZW5lcikge1xuICAgICAgICB2YXIgbGlzdGVuZXJzID0gdGhpcy5nZXRMaXN0ZW5lcnNBc09iamVjdChldnQpO1xuICAgICAgICB2YXIgaW5kZXg7XG4gICAgICAgIHZhciBrZXk7XG5cbiAgICAgICAgZm9yIChrZXkgaW4gbGlzdGVuZXJzKSB7XG4gICAgICAgICAgICBpZiAobGlzdGVuZXJzLmhhc093blByb3BlcnR5KGtleSkpIHtcbiAgICAgICAgICAgICAgICBpbmRleCA9IGluZGV4T2ZMaXN0ZW5lcihsaXN0ZW5lcnNba2V5XSwgbGlzdGVuZXIpO1xuXG4gICAgICAgICAgICAgICAgaWYgKGluZGV4ICE9PSAtMSkge1xuICAgICAgICAgICAgICAgICAgICBsaXN0ZW5lcnNba2V5XS5zcGxpY2UoaW5kZXgsIDEpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBBbGlhcyBvZiByZW1vdmVMaXN0ZW5lclxuICAgICAqL1xuICAgIHByb3RvLm9mZiA9IGFsaWFzKCdyZW1vdmVMaXN0ZW5lcicpO1xuXG4gICAgLyoqXG4gICAgICogQWRkcyBsaXN0ZW5lcnMgaW4gYnVsayB1c2luZyB0aGUgbWFuaXB1bGF0ZUxpc3RlbmVycyBtZXRob2QuXG4gICAgICogSWYgeW91IHBhc3MgYW4gb2JqZWN0IGFzIHRoZSBzZWNvbmQgYXJndW1lbnQgeW91IGNhbiBhZGQgdG8gbXVsdGlwbGUgZXZlbnRzIGF0IG9uY2UuIFRoZSBvYmplY3Qgc2hvdWxkIGNvbnRhaW4ga2V5IHZhbHVlIHBhaXJzIG9mIGV2ZW50cyBhbmQgbGlzdGVuZXJzIG9yIGxpc3RlbmVyIGFycmF5cy4gWW91IGNhbiBhbHNvIHBhc3MgaXQgYW4gZXZlbnQgbmFtZSBhbmQgYW4gYXJyYXkgb2YgbGlzdGVuZXJzIHRvIGJlIGFkZGVkLlxuICAgICAqIFlvdSBjYW4gYWxzbyBwYXNzIGl0IGEgcmVndWxhciBleHByZXNzaW9uIHRvIGFkZCB0aGUgYXJyYXkgb2YgbGlzdGVuZXJzIHRvIGFsbCBldmVudHMgdGhhdCBtYXRjaCBpdC5cbiAgICAgKiBZZWFoLCB0aGlzIGZ1bmN0aW9uIGRvZXMgcXVpdGUgYSBiaXQuIFRoYXQncyBwcm9iYWJseSBhIGJhZCB0aGluZy5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfE9iamVjdHxSZWdFeHB9IGV2dCBBbiBldmVudCBuYW1lIGlmIHlvdSB3aWxsIHBhc3MgYW4gYXJyYXkgb2YgbGlzdGVuZXJzIG5leHQuIEFuIG9iamVjdCBpZiB5b3Ugd2lzaCB0byBhZGQgdG8gbXVsdGlwbGUgZXZlbnRzIGF0IG9uY2UuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbltdfSBbbGlzdGVuZXJzXSBBbiBvcHRpb25hbCBhcnJheSBvZiBsaXN0ZW5lciBmdW5jdGlvbnMgdG8gYWRkLlxuICAgICAqIEByZXR1cm4ge09iamVjdH0gQ3VycmVudCBpbnN0YW5jZSBvZiBFdmVudEVtaXR0ZXIgZm9yIGNoYWluaW5nLlxuICAgICAqL1xuICAgIHByb3RvLmFkZExpc3RlbmVycyA9IGZ1bmN0aW9uIGFkZExpc3RlbmVycyhldnQsIGxpc3RlbmVycykge1xuICAgICAgICAvLyBQYXNzIHRocm91Z2ggdG8gbWFuaXB1bGF0ZUxpc3RlbmVyc1xuICAgICAgICByZXR1cm4gdGhpcy5tYW5pcHVsYXRlTGlzdGVuZXJzKGZhbHNlLCBldnQsIGxpc3RlbmVycyk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIFJlbW92ZXMgbGlzdGVuZXJzIGluIGJ1bGsgdXNpbmcgdGhlIG1hbmlwdWxhdGVMaXN0ZW5lcnMgbWV0aG9kLlxuICAgICAqIElmIHlvdSBwYXNzIGFuIG9iamVjdCBhcyB0aGUgc2Vjb25kIGFyZ3VtZW50IHlvdSBjYW4gcmVtb3ZlIGZyb20gbXVsdGlwbGUgZXZlbnRzIGF0IG9uY2UuIFRoZSBvYmplY3Qgc2hvdWxkIGNvbnRhaW4ga2V5IHZhbHVlIHBhaXJzIG9mIGV2ZW50cyBhbmQgbGlzdGVuZXJzIG9yIGxpc3RlbmVyIGFycmF5cy5cbiAgICAgKiBZb3UgY2FuIGFsc28gcGFzcyBpdCBhbiBldmVudCBuYW1lIGFuZCBhbiBhcnJheSBvZiBsaXN0ZW5lcnMgdG8gYmUgcmVtb3ZlZC5cbiAgICAgKiBZb3UgY2FuIGFsc28gcGFzcyBpdCBhIHJlZ3VsYXIgZXhwcmVzc2lvbiB0byByZW1vdmUgdGhlIGxpc3RlbmVycyBmcm9tIGFsbCBldmVudHMgdGhhdCBtYXRjaCBpdC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfE9iamVjdHxSZWdFeHB9IGV2dCBBbiBldmVudCBuYW1lIGlmIHlvdSB3aWxsIHBhc3MgYW4gYXJyYXkgb2YgbGlzdGVuZXJzIG5leHQuIEFuIG9iamVjdCBpZiB5b3Ugd2lzaCB0byByZW1vdmUgZnJvbSBtdWx0aXBsZSBldmVudHMgYXQgb25jZS5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9uW119IFtsaXN0ZW5lcnNdIEFuIG9wdGlvbmFsIGFycmF5IG9mIGxpc3RlbmVyIGZ1bmN0aW9ucyB0byByZW1vdmUuXG4gICAgICogQHJldHVybiB7T2JqZWN0fSBDdXJyZW50IGluc3RhbmNlIG9mIEV2ZW50RW1pdHRlciBmb3IgY2hhaW5pbmcuXG4gICAgICovXG4gICAgcHJvdG8ucmVtb3ZlTGlzdGVuZXJzID0gZnVuY3Rpb24gcmVtb3ZlTGlzdGVuZXJzKGV2dCwgbGlzdGVuZXJzKSB7XG4gICAgICAgIC8vIFBhc3MgdGhyb3VnaCB0byBtYW5pcHVsYXRlTGlzdGVuZXJzXG4gICAgICAgIHJldHVybiB0aGlzLm1hbmlwdWxhdGVMaXN0ZW5lcnModHJ1ZSwgZXZ0LCBsaXN0ZW5lcnMpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBFZGl0cyBsaXN0ZW5lcnMgaW4gYnVsay4gVGhlIGFkZExpc3RlbmVycyBhbmQgcmVtb3ZlTGlzdGVuZXJzIG1ldGhvZHMgYm90aCB1c2UgdGhpcyB0byBkbyB0aGVpciBqb2IuIFlvdSBzaG91bGQgcmVhbGx5IHVzZSB0aG9zZSBpbnN0ZWFkLCB0aGlzIGlzIGEgbGl0dGxlIGxvd2VyIGxldmVsLlxuICAgICAqIFRoZSBmaXJzdCBhcmd1bWVudCB3aWxsIGRldGVybWluZSBpZiB0aGUgbGlzdGVuZXJzIGFyZSByZW1vdmVkICh0cnVlKSBvciBhZGRlZCAoZmFsc2UpLlxuICAgICAqIElmIHlvdSBwYXNzIGFuIG9iamVjdCBhcyB0aGUgc2Vjb25kIGFyZ3VtZW50IHlvdSBjYW4gYWRkL3JlbW92ZSBmcm9tIG11bHRpcGxlIGV2ZW50cyBhdCBvbmNlLiBUaGUgb2JqZWN0IHNob3VsZCBjb250YWluIGtleSB2YWx1ZSBwYWlycyBvZiBldmVudHMgYW5kIGxpc3RlbmVycyBvciBsaXN0ZW5lciBhcnJheXMuXG4gICAgICogWW91IGNhbiBhbHNvIHBhc3MgaXQgYW4gZXZlbnQgbmFtZSBhbmQgYW4gYXJyYXkgb2YgbGlzdGVuZXJzIHRvIGJlIGFkZGVkL3JlbW92ZWQuXG4gICAgICogWW91IGNhbiBhbHNvIHBhc3MgaXQgYSByZWd1bGFyIGV4cHJlc3Npb24gdG8gbWFuaXB1bGF0ZSB0aGUgbGlzdGVuZXJzIG9mIGFsbCBldmVudHMgdGhhdCBtYXRjaCBpdC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gcmVtb3ZlIFRydWUgaWYgeW91IHdhbnQgdG8gcmVtb3ZlIGxpc3RlbmVycywgZmFsc2UgaWYgeW91IHdhbnQgdG8gYWRkLlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfE9iamVjdHxSZWdFeHB9IGV2dCBBbiBldmVudCBuYW1lIGlmIHlvdSB3aWxsIHBhc3MgYW4gYXJyYXkgb2YgbGlzdGVuZXJzIG5leHQuIEFuIG9iamVjdCBpZiB5b3Ugd2lzaCB0byBhZGQvcmVtb3ZlIGZyb20gbXVsdGlwbGUgZXZlbnRzIGF0IG9uY2UuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbltdfSBbbGlzdGVuZXJzXSBBbiBvcHRpb25hbCBhcnJheSBvZiBsaXN0ZW5lciBmdW5jdGlvbnMgdG8gYWRkL3JlbW92ZS5cbiAgICAgKiBAcmV0dXJuIHtPYmplY3R9IEN1cnJlbnQgaW5zdGFuY2Ugb2YgRXZlbnRFbWl0dGVyIGZvciBjaGFpbmluZy5cbiAgICAgKi9cbiAgICBwcm90by5tYW5pcHVsYXRlTGlzdGVuZXJzID0gZnVuY3Rpb24gbWFuaXB1bGF0ZUxpc3RlbmVycyhyZW1vdmUsIGV2dCwgbGlzdGVuZXJzKSB7XG4gICAgICAgIHZhciBpO1xuICAgICAgICB2YXIgdmFsdWU7XG4gICAgICAgIHZhciBzaW5nbGUgPSByZW1vdmUgPyB0aGlzLnJlbW92ZUxpc3RlbmVyIDogdGhpcy5hZGRMaXN0ZW5lcjtcbiAgICAgICAgdmFyIG11bHRpcGxlID0gcmVtb3ZlID8gdGhpcy5yZW1vdmVMaXN0ZW5lcnMgOiB0aGlzLmFkZExpc3RlbmVycztcblxuICAgICAgICAvLyBJZiBldnQgaXMgYW4gb2JqZWN0IHRoZW4gcGFzcyBlYWNoIG9mIGl0cyBwcm9wZXJ0aWVzIHRvIHRoaXMgbWV0aG9kXG4gICAgICAgIGlmICh0eXBlb2YgZXZ0ID09PSAnb2JqZWN0JyAmJiAhKGV2dCBpbnN0YW5jZW9mIFJlZ0V4cCkpIHtcbiAgICAgICAgICAgIGZvciAoaSBpbiBldnQpIHtcbiAgICAgICAgICAgICAgICBpZiAoZXZ0Lmhhc093blByb3BlcnR5KGkpICYmICh2YWx1ZSA9IGV2dFtpXSkpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gUGFzcyB0aGUgc2luZ2xlIGxpc3RlbmVyIHN0cmFpZ2h0IHRocm91Z2ggdG8gdGhlIHNpbmd1bGFyIG1ldGhvZFxuICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzaW5nbGUuY2FsbCh0aGlzLCBpLCB2YWx1ZSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBPdGhlcndpc2UgcGFzcyBiYWNrIHRvIHRoZSBtdWx0aXBsZSBmdW5jdGlvblxuICAgICAgICAgICAgICAgICAgICAgICAgbXVsdGlwbGUuY2FsbCh0aGlzLCBpLCB2YWx1ZSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAvLyBTbyBldnQgbXVzdCBiZSBhIHN0cmluZ1xuICAgICAgICAgICAgLy8gQW5kIGxpc3RlbmVycyBtdXN0IGJlIGFuIGFycmF5IG9mIGxpc3RlbmVyc1xuICAgICAgICAgICAgLy8gTG9vcCBvdmVyIGl0IGFuZCBwYXNzIGVhY2ggb25lIHRvIHRoZSBtdWx0aXBsZSBtZXRob2RcbiAgICAgICAgICAgIGkgPSBsaXN0ZW5lcnMubGVuZ3RoO1xuICAgICAgICAgICAgd2hpbGUgKGktLSkge1xuICAgICAgICAgICAgICAgIHNpbmdsZS5jYWxsKHRoaXMsIGV2dCwgbGlzdGVuZXJzW2ldKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBSZW1vdmVzIGFsbCBsaXN0ZW5lcnMgZnJvbSBhIHNwZWNpZmllZCBldmVudC5cbiAgICAgKiBJZiB5b3UgZG8gbm90IHNwZWNpZnkgYW4gZXZlbnQgdGhlbiBhbGwgbGlzdGVuZXJzIHdpbGwgYmUgcmVtb3ZlZC5cbiAgICAgKiBUaGF0IG1lYW5zIGV2ZXJ5IGV2ZW50IHdpbGwgYmUgZW1wdGllZC5cbiAgICAgKiBZb3UgY2FuIGFsc28gcGFzcyBhIHJlZ2V4IHRvIHJlbW92ZSBhbGwgZXZlbnRzIHRoYXQgbWF0Y2ggaXQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge1N0cmluZ3xSZWdFeHB9IFtldnRdIE9wdGlvbmFsIG5hbWUgb2YgdGhlIGV2ZW50IHRvIHJlbW92ZSBhbGwgbGlzdGVuZXJzIGZvci4gV2lsbCByZW1vdmUgZnJvbSBldmVyeSBldmVudCBpZiBub3QgcGFzc2VkLlxuICAgICAqIEByZXR1cm4ge09iamVjdH0gQ3VycmVudCBpbnN0YW5jZSBvZiBFdmVudEVtaXR0ZXIgZm9yIGNoYWluaW5nLlxuICAgICAqL1xuICAgIHByb3RvLnJlbW92ZUV2ZW50ID0gZnVuY3Rpb24gcmVtb3ZlRXZlbnQoZXZ0KSB7XG4gICAgICAgIHZhciB0eXBlID0gdHlwZW9mIGV2dDtcbiAgICAgICAgdmFyIGV2ZW50cyA9IHRoaXMuX2dldEV2ZW50cygpO1xuICAgICAgICB2YXIga2V5O1xuXG4gICAgICAgIC8vIFJlbW92ZSBkaWZmZXJlbnQgdGhpbmdzIGRlcGVuZGluZyBvbiB0aGUgc3RhdGUgb2YgZXZ0XG4gICAgICAgIGlmICh0eXBlID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgLy8gUmVtb3ZlIGFsbCBsaXN0ZW5lcnMgZm9yIHRoZSBzcGVjaWZpZWQgZXZlbnRcbiAgICAgICAgICAgIGRlbGV0ZSBldmVudHNbZXZ0XTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChldnQgaW5zdGFuY2VvZiBSZWdFeHApIHtcbiAgICAgICAgICAgIC8vIFJlbW92ZSBhbGwgZXZlbnRzIG1hdGNoaW5nIHRoZSByZWdleC5cbiAgICAgICAgICAgIGZvciAoa2V5IGluIGV2ZW50cykge1xuICAgICAgICAgICAgICAgIGlmIChldmVudHMuaGFzT3duUHJvcGVydHkoa2V5KSAmJiBldnQudGVzdChrZXkpKSB7XG4gICAgICAgICAgICAgICAgICAgIGRlbGV0ZSBldmVudHNba2V5XTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAvLyBSZW1vdmUgYWxsIGxpc3RlbmVycyBpbiBhbGwgZXZlbnRzXG4gICAgICAgICAgICBkZWxldGUgdGhpcy5fZXZlbnRzO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEFsaWFzIG9mIHJlbW92ZUV2ZW50LlxuICAgICAqXG4gICAgICogQWRkZWQgdG8gbWlycm9yIHRoZSBub2RlIEFQSS5cbiAgICAgKi9cbiAgICBwcm90by5yZW1vdmVBbGxMaXN0ZW5lcnMgPSBhbGlhcygncmVtb3ZlRXZlbnQnKTtcblxuICAgIC8qKlxuICAgICAqIEVtaXRzIGFuIGV2ZW50IG9mIHlvdXIgY2hvaWNlLlxuICAgICAqIFdoZW4gZW1pdHRlZCwgZXZlcnkgbGlzdGVuZXIgYXR0YWNoZWQgdG8gdGhhdCBldmVudCB3aWxsIGJlIGV4ZWN1dGVkLlxuICAgICAqIElmIHlvdSBwYXNzIHRoZSBvcHRpb25hbCBhcmd1bWVudCBhcnJheSB0aGVuIHRob3NlIGFyZ3VtZW50cyB3aWxsIGJlIHBhc3NlZCB0byBldmVyeSBsaXN0ZW5lciB1cG9uIGV4ZWN1dGlvbi5cbiAgICAgKiBCZWNhdXNlIGl0IHVzZXMgYGFwcGx5YCwgeW91ciBhcnJheSBvZiBhcmd1bWVudHMgd2lsbCBiZSBwYXNzZWQgYXMgaWYgeW91IHdyb3RlIHRoZW0gb3V0IHNlcGFyYXRlbHkuXG4gICAgICogU28gdGhleSB3aWxsIG5vdCBhcnJpdmUgd2l0aGluIHRoZSBhcnJheSBvbiB0aGUgb3RoZXIgc2lkZSwgdGhleSB3aWxsIGJlIHNlcGFyYXRlLlxuICAgICAqIFlvdSBjYW4gYWxzbyBwYXNzIGEgcmVndWxhciBleHByZXNzaW9uIHRvIGVtaXQgdG8gYWxsIGV2ZW50cyB0aGF0IG1hdGNoIGl0LlxuICAgICAqXG4gICAgICogQHBhcmFtIHtTdHJpbmd8UmVnRXhwfSBldnQgTmFtZSBvZiB0aGUgZXZlbnQgdG8gZW1pdCBhbmQgZXhlY3V0ZSBsaXN0ZW5lcnMgZm9yLlxuICAgICAqIEBwYXJhbSB7QXJyYXl9IFthcmdzXSBPcHRpb25hbCBhcnJheSBvZiBhcmd1bWVudHMgdG8gYmUgcGFzc2VkIHRvIGVhY2ggbGlzdGVuZXIuXG4gICAgICogQHJldHVybiB7T2JqZWN0fSBDdXJyZW50IGluc3RhbmNlIG9mIEV2ZW50RW1pdHRlciBmb3IgY2hhaW5pbmcuXG4gICAgICovXG4gICAgcHJvdG8uZW1pdEV2ZW50ID0gZnVuY3Rpb24gZW1pdEV2ZW50KGV2dCwgYXJncykge1xuICAgICAgICB2YXIgbGlzdGVuZXJzID0gdGhpcy5nZXRMaXN0ZW5lcnNBc09iamVjdChldnQpO1xuICAgICAgICB2YXIgbGlzdGVuZXI7XG4gICAgICAgIHZhciBpO1xuICAgICAgICB2YXIga2V5O1xuICAgICAgICB2YXIgcmVzcG9uc2U7XG5cbiAgICAgICAgZm9yIChrZXkgaW4gbGlzdGVuZXJzKSB7XG4gICAgICAgICAgICBpZiAobGlzdGVuZXJzLmhhc093blByb3BlcnR5KGtleSkpIHtcbiAgICAgICAgICAgICAgICBpID0gbGlzdGVuZXJzW2tleV0ubGVuZ3RoO1xuXG4gICAgICAgICAgICAgICAgd2hpbGUgKGktLSkge1xuICAgICAgICAgICAgICAgICAgICAvLyBJZiB0aGUgbGlzdGVuZXIgcmV0dXJucyB0cnVlIHRoZW4gaXQgc2hhbGwgYmUgcmVtb3ZlZCBmcm9tIHRoZSBldmVudFxuICAgICAgICAgICAgICAgICAgICAvLyBUaGUgZnVuY3Rpb24gaXMgZXhlY3V0ZWQgZWl0aGVyIHdpdGggYSBiYXNpYyBjYWxsIG9yIGFuIGFwcGx5IGlmIHRoZXJlIGlzIGFuIGFyZ3MgYXJyYXlcbiAgICAgICAgICAgICAgICAgICAgbGlzdGVuZXIgPSBsaXN0ZW5lcnNba2V5XVtpXTtcblxuICAgICAgICAgICAgICAgICAgICBpZiAobGlzdGVuZXIub25jZSA9PT0gdHJ1ZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5yZW1vdmVMaXN0ZW5lcihldnQsIGxpc3RlbmVyLmxpc3RlbmVyKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIHJlc3BvbnNlID0gbGlzdGVuZXIubGlzdGVuZXIuYXBwbHkodGhpcywgYXJncyB8fCBbXSk7XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKHJlc3BvbnNlID09PSB0aGlzLl9nZXRPbmNlUmV0dXJuVmFsdWUoKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5yZW1vdmVMaXN0ZW5lcihldnQsIGxpc3RlbmVyLmxpc3RlbmVyKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBBbGlhcyBvZiBlbWl0RXZlbnRcbiAgICAgKi9cbiAgICBwcm90by50cmlnZ2VyID0gYWxpYXMoJ2VtaXRFdmVudCcpO1xuXG4gICAgLyoqXG4gICAgICogU3VidGx5IGRpZmZlcmVudCBmcm9tIGVtaXRFdmVudCBpbiB0aGF0IGl0IHdpbGwgcGFzcyBpdHMgYXJndW1lbnRzIG9uIHRvIHRoZSBsaXN0ZW5lcnMsIGFzIG9wcG9zZWQgdG8gdGFraW5nIGEgc2luZ2xlIGFycmF5IG9mIGFyZ3VtZW50cyB0byBwYXNzIG9uLlxuICAgICAqIEFzIHdpdGggZW1pdEV2ZW50LCB5b3UgY2FuIHBhc3MgYSByZWdleCBpbiBwbGFjZSBvZiB0aGUgZXZlbnQgbmFtZSB0byBlbWl0IHRvIGFsbCBldmVudHMgdGhhdCBtYXRjaCBpdC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfFJlZ0V4cH0gZXZ0IE5hbWUgb2YgdGhlIGV2ZW50IHRvIGVtaXQgYW5kIGV4ZWN1dGUgbGlzdGVuZXJzIGZvci5cbiAgICAgKiBAcGFyYW0gey4uLip9IE9wdGlvbmFsIGFkZGl0aW9uYWwgYXJndW1lbnRzIHRvIGJlIHBhc3NlZCB0byBlYWNoIGxpc3RlbmVyLlxuICAgICAqIEByZXR1cm4ge09iamVjdH0gQ3VycmVudCBpbnN0YW5jZSBvZiBFdmVudEVtaXR0ZXIgZm9yIGNoYWluaW5nLlxuICAgICAqL1xuICAgIHByb3RvLmVtaXQgPSBmdW5jdGlvbiBlbWl0KGV2dCkge1xuICAgICAgICB2YXIgYXJncyA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMSk7XG4gICAgICAgIHJldHVybiB0aGlzLmVtaXRFdmVudChldnQsIGFyZ3MpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBTZXRzIHRoZSBjdXJyZW50IHZhbHVlIHRvIGNoZWNrIGFnYWluc3Qgd2hlbiBleGVjdXRpbmcgbGlzdGVuZXJzLiBJZiBhXG4gICAgICogbGlzdGVuZXJzIHJldHVybiB2YWx1ZSBtYXRjaGVzIHRoZSBvbmUgc2V0IGhlcmUgdGhlbiBpdCB3aWxsIGJlIHJlbW92ZWRcbiAgICAgKiBhZnRlciBleGVjdXRpb24uIFRoaXMgdmFsdWUgZGVmYXVsdHMgdG8gdHJ1ZS5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIG5ldyB2YWx1ZSB0byBjaGVjayBmb3Igd2hlbiBleGVjdXRpbmcgbGlzdGVuZXJzLlxuICAgICAqIEByZXR1cm4ge09iamVjdH0gQ3VycmVudCBpbnN0YW5jZSBvZiBFdmVudEVtaXR0ZXIgZm9yIGNoYWluaW5nLlxuICAgICAqL1xuICAgIHByb3RvLnNldE9uY2VSZXR1cm5WYWx1ZSA9IGZ1bmN0aW9uIHNldE9uY2VSZXR1cm5WYWx1ZSh2YWx1ZSkge1xuICAgICAgICB0aGlzLl9vbmNlUmV0dXJuVmFsdWUgPSB2YWx1ZTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEZldGNoZXMgdGhlIGN1cnJlbnQgdmFsdWUgdG8gY2hlY2sgYWdhaW5zdCB3aGVuIGV4ZWN1dGluZyBsaXN0ZW5lcnMuIElmXG4gICAgICogdGhlIGxpc3RlbmVycyByZXR1cm4gdmFsdWUgbWF0Y2hlcyB0aGlzIG9uZSB0aGVuIGl0IHNob3VsZCBiZSByZW1vdmVkXG4gICAgICogYXV0b21hdGljYWxseS4gSXQgd2lsbCByZXR1cm4gdHJ1ZSBieSBkZWZhdWx0LlxuICAgICAqXG4gICAgICogQHJldHVybiB7KnxCb29sZWFufSBUaGUgY3VycmVudCB2YWx1ZSB0byBjaGVjayBmb3Igb3IgdGhlIGRlZmF1bHQsIHRydWUuXG4gICAgICogQGFwaSBwcml2YXRlXG4gICAgICovXG4gICAgcHJvdG8uX2dldE9uY2VSZXR1cm5WYWx1ZSA9IGZ1bmN0aW9uIF9nZXRPbmNlUmV0dXJuVmFsdWUoKSB7XG4gICAgICAgIGlmICh0aGlzLmhhc093blByb3BlcnR5KCdfb25jZVJldHVyblZhbHVlJykpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9vbmNlUmV0dXJuVmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBGZXRjaGVzIHRoZSBldmVudHMgb2JqZWN0IGFuZCBjcmVhdGVzIG9uZSBpZiByZXF1aXJlZC5cbiAgICAgKlxuICAgICAqIEByZXR1cm4ge09iamVjdH0gVGhlIGV2ZW50cyBzdG9yYWdlIG9iamVjdC5cbiAgICAgKiBAYXBpIHByaXZhdGVcbiAgICAgKi9cbiAgICBwcm90by5fZ2V0RXZlbnRzID0gZnVuY3Rpb24gX2dldEV2ZW50cygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2V2ZW50cyB8fCAodGhpcy5fZXZlbnRzID0ge30pO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBSZXZlcnRzIHRoZSBnbG9iYWwge0BsaW5rIEV2ZW50RW1pdHRlcn0gdG8gaXRzIHByZXZpb3VzIHZhbHVlIGFuZCByZXR1cm5zIGEgcmVmZXJlbmNlIHRvIHRoaXMgdmVyc2lvbi5cbiAgICAgKlxuICAgICAqIEByZXR1cm4ge0Z1bmN0aW9ufSBOb24gY29uZmxpY3RpbmcgRXZlbnRFbWl0dGVyIGNsYXNzLlxuICAgICAqL1xuICAgIEV2ZW50RW1pdHRlci5ub0NvbmZsaWN0ID0gZnVuY3Rpb24gbm9Db25mbGljdCgpIHtcbiAgICAgICAgZXhwb3J0cy5FdmVudEVtaXR0ZXIgPSBvcmlnaW5hbEdsb2JhbFZhbHVlO1xuICAgICAgICByZXR1cm4gRXZlbnRFbWl0dGVyO1xuICAgIH07XG5cbiAgICAvLyBFeHBvc2UgdGhlIGNsYXNzIGVpdGhlciB2aWEgQU1ELCBDb21tb25KUyBvciB0aGUgZ2xvYmFsIG9iamVjdFxuICAgIGlmICh0eXBlb2YgZGVmaW5lID09PSAnZnVuY3Rpb24nICYmIGRlZmluZS5hbWQpIHtcbiAgICAgICAgZGVmaW5lKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHJldHVybiBFdmVudEVtaXR0ZXI7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBlbHNlIGlmICh0eXBlb2YgbW9kdWxlID09PSAnb2JqZWN0JyAmJiBtb2R1bGUuZXhwb3J0cyl7XG4gICAgICAgIG1vZHVsZS5leHBvcnRzID0gRXZlbnRFbWl0dGVyO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgZXhwb3J0cy5FdmVudEVtaXR0ZXIgPSBFdmVudEVtaXR0ZXI7XG4gICAgfVxufS5jYWxsKHRoaXMpKTtcbiIsImZ1bmN0aW9uIE1hcHBlcigpXG57XG4gIHZhciBzb3VyY2VzID0ge307XG5cblxuICB0aGlzLmZvckVhY2ggPSBmdW5jdGlvbihjYWxsYmFjaylcbiAge1xuICAgIGZvcih2YXIga2V5IGluIHNvdXJjZXMpXG4gICAge1xuICAgICAgdmFyIHNvdXJjZSA9IHNvdXJjZXNba2V5XTtcblxuICAgICAgZm9yKHZhciBrZXkyIGluIHNvdXJjZSlcbiAgICAgICAgY2FsbGJhY2soc291cmNlW2tleTJdKTtcbiAgICB9O1xuICB9O1xuXG4gIHRoaXMuZ2V0ID0gZnVuY3Rpb24oaWQsIHNvdXJjZSlcbiAge1xuICAgIHZhciBpZHMgPSBzb3VyY2VzW3NvdXJjZV07XG4gICAgaWYoaWRzID09IHVuZGVmaW5lZClcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG5cbiAgICByZXR1cm4gaWRzW2lkXTtcbiAgfTtcblxuICB0aGlzLnJlbW92ZSA9IGZ1bmN0aW9uKGlkLCBzb3VyY2UpXG4gIHtcbiAgICB2YXIgaWRzID0gc291cmNlc1tzb3VyY2VdO1xuICAgIGlmKGlkcyA9PSB1bmRlZmluZWQpXG4gICAgICByZXR1cm47XG5cbiAgICBkZWxldGUgaWRzW2lkXTtcblxuICAgIC8vIENoZWNrIGl0J3MgZW1wdHlcbiAgICBmb3IodmFyIGkgaW4gaWRzKXtyZXR1cm4gZmFsc2V9XG5cbiAgICBkZWxldGUgc291cmNlc1tzb3VyY2VdO1xuICB9O1xuXG4gIHRoaXMuc2V0ID0gZnVuY3Rpb24odmFsdWUsIGlkLCBzb3VyY2UpXG4gIHtcbiAgICBpZih2YWx1ZSA9PSB1bmRlZmluZWQpXG4gICAgICByZXR1cm4gdGhpcy5yZW1vdmUoaWQsIHNvdXJjZSk7XG5cbiAgICB2YXIgaWRzID0gc291cmNlc1tzb3VyY2VdO1xuICAgIGlmKGlkcyA9PSB1bmRlZmluZWQpXG4gICAgICBzb3VyY2VzW3NvdXJjZV0gPSBpZHMgPSB7fTtcblxuICAgIGlkc1tpZF0gPSB2YWx1ZTtcbiAgfTtcbn07XG5cblxuTWFwcGVyLnByb3RvdHlwZS5wb3AgPSBmdW5jdGlvbihpZCwgc291cmNlKVxue1xuICB2YXIgdmFsdWUgPSB0aGlzLmdldChpZCwgc291cmNlKTtcbiAgaWYodmFsdWUgPT0gdW5kZWZpbmVkKVxuICAgIHJldHVybiB1bmRlZmluZWQ7XG5cbiAgdGhpcy5yZW1vdmUoaWQsIHNvdXJjZSk7XG5cbiAgcmV0dXJuIHZhbHVlO1xufTtcblxuXG5tb2R1bGUuZXhwb3J0cyA9IE1hcHBlcjtcbiIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTQgS3VyZW50byAoaHR0cDovL2t1cmVudG8ub3JnLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG52YXIgSnNvblJwY0NsaWVudCAgPSByZXF1aXJlKCcuL2pzb25ycGNjbGllbnQnKTtcblxuXG5leHBvcnRzLkpzb25ScGNDbGllbnQgID0gSnNvblJwY0NsaWVudDsiLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE0IEt1cmVudG8gKGh0dHA6Ly9rdXJlbnRvLm9yZy8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxudmFyIFJwY0J1aWxkZXIgPSByZXF1aXJlKCcuLi8nKTtcbnZhciBXZWJTb2NrZXRXaXRoUmVjb25uZWN0aW9uID0gcmVxdWlyZSgnLi90cmFuc3BvcnRzL3dlYlNvY2tldFdpdGhSZWNvbm5lY3Rpb24nKTtcblxuRGF0ZS5ub3cgPSBEYXRlLm5vdyB8fCBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gK25ldyBEYXRlO1xufTtcblxudmFyIFBJTkdfSU5URVJWQUwgPSA1MDAwO1xuXG52YXIgUkVDT05ORUNUSU5HID0gJ1JFQ09OTkVDVElORyc7XG52YXIgQ09OTkVDVEVEID0gJ0NPTk5FQ1RFRCc7XG52YXIgRElTQ09OTkVDVEVEID0gJ0RJU0NPTk5FQ1RFRCc7XG5cbnZhciBMb2dnZXIgPSBjb25zb2xlO1xuXG4vKipcbiAqXG4gKiBoZWFydGJlYXQ6IGludGVydmFsIGluIG1zIGZvciBlYWNoIGhlYXJ0YmVhdCBtZXNzYWdlLFxuICogc2VuZENsb3NlTWVzc2FnZSA6IHRydWUgLyBmYWxzZSwgYmVmb3JlIGNsb3NpbmcgdGhlIGNvbm5lY3Rpb24sIGl0IHNlbmRzIGEgY2xvc2VTZXNzaW9uIG1lc3NhZ2VcbiAqIDxwcmU+XG4gKiB3cyA6IHtcbiAqIFx0dXJpIDogVVJJIHRvIGNvbm50ZWN0IHRvLFxuICogIHVzZVNvY2tKUyA6IHRydWUgKHVzZSBTb2NrSlMpIC8gZmFsc2UgKHVzZSBXZWJTb2NrZXQpIGJ5IGRlZmF1bHQsXG4gKiBcdG9uY29ubmVjdGVkIDogY2FsbGJhY2sgbWV0aG9kIHRvIGludm9rZSB3aGVuIGNvbm5lY3Rpb24gaXMgc3VjY2Vzc2Z1bCxcbiAqIFx0b25kaXNjb25uZWN0IDogY2FsbGJhY2sgbWV0aG9kIHRvIGludm9rZSB3aGVuIHRoZSBjb25uZWN0aW9uIGlzIGxvc3QsXG4gKiBcdG9ucmVjb25uZWN0aW5nIDogY2FsbGJhY2sgbWV0aG9kIHRvIGludm9rZSB3aGVuIHRoZSBjbGllbnQgaXMgcmVjb25uZWN0aW5nLFxuICogXHRvbnJlY29ubmVjdGVkIDogY2FsbGJhY2sgbWV0aG9kIHRvIGludm9rZSB3aGVuIHRoZSBjbGllbnQgc3VjY2VzZnVsbHkgcmVjb25uZWN0cyxcbiAqIFx0b25lcnJvciA6IGNhbGxiYWNrIG1ldGhvZCB0byBpbnZva2Ugd2hlbiB0aGVyZSBpcyBhbiBlcnJvclxuICogfSxcbiAqIHJwYyA6IHtcbiAqIFx0cmVxdWVzdFRpbWVvdXQgOiB0aW1lb3V0IGZvciBhIHJlcXVlc3QsXG4gKiBcdHNlc3Npb25TdGF0dXNDaGFuZ2VkOiBjYWxsYmFjayBtZXRob2QgZm9yIGNoYW5nZXMgaW4gc2Vzc2lvbiBzdGF0dXMsXG4gKiBcdG1lZGlhUmVuZWdvdGlhdGlvbjogbWVkaWFSZW5lZ290aWF0aW9uXG4gKiB9XG4gKiA8L3ByZT5cbiAqL1xuZnVuY3Rpb24gSnNvblJwY0NsaWVudChjb25maWd1cmF0aW9uKSB7XG5cbiAgICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgICB2YXIgd3NDb25maWcgPSBjb25maWd1cmF0aW9uLndzO1xuXG4gICAgdmFyIG5vdFJlY29ubmVjdElmTnVtTGVzc1RoYW4gPSAtMTtcblxuICAgIHZhciBwaW5nTmV4dE51bSA9IDA7XG4gICAgdmFyIGVuYWJsZWRQaW5ncyA9IHRydWU7XG4gICAgdmFyIHBpbmdQb25nU3RhcnRlZCA9IGZhbHNlO1xuICAgIHZhciBwaW5nSW50ZXJ2YWw7XG5cbiAgICB2YXIgc3RhdHVzID0gRElTQ09OTkVDVEVEO1xuXG4gICAgdmFyIG9ucmVjb25uZWN0aW5nID0gd3NDb25maWcub25yZWNvbm5lY3Rpbmc7XG4gICAgdmFyIG9ucmVjb25uZWN0ZWQgPSB3c0NvbmZpZy5vbnJlY29ubmVjdGVkO1xuICAgIHZhciBvbmNvbm5lY3RlZCA9IHdzQ29uZmlnLm9uY29ubmVjdGVkO1xuICAgIHZhciBvbmVycm9yID0gd3NDb25maWcub25lcnJvcjtcblxuICAgIGNvbmZpZ3VyYXRpb24ucnBjLnB1bGwgPSBmdW5jdGlvbihwYXJhbXMsIHJlcXVlc3QpIHtcbiAgICAgICAgcmVxdWVzdC5yZXBseShudWxsLCBcInB1c2hcIik7XG4gICAgfVxuXG4gICAgd3NDb25maWcub25yZWNvbm5lY3RpbmcgPSBmdW5jdGlvbigpIHtcbiAgICAgICAgTG9nZ2VyLmRlYnVnKFwiLS0tLS0tLS0tIE9OUkVDT05ORUNUSU5HIC0tLS0tLS0tLS0tXCIpO1xuICAgICAgICBpZiAoc3RhdHVzID09PSBSRUNPTk5FQ1RJTkcpIHtcbiAgICAgICAgICAgIExvZ2dlci5lcnJvcihcIldlYnNvY2tldCBhbHJlYWR5IGluIFJFQ09OTkVDVElORyBzdGF0ZSB3aGVuIHJlY2VpdmluZyBhIG5ldyBPTlJFQ09OTkVDVElORyBtZXNzYWdlLiBJZ25vcmluZyBpdFwiKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHN0YXR1cyA9IFJFQ09OTkVDVElORztcbiAgICAgICAgaWYgKG9ucmVjb25uZWN0aW5nKSB7XG4gICAgICAgICAgICBvbnJlY29ubmVjdGluZygpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgd3NDb25maWcub25yZWNvbm5lY3RlZCA9IGZ1bmN0aW9uKCkge1xuICAgICAgICBMb2dnZXIuZGVidWcoXCItLS0tLS0tLS0gT05SRUNPTk5FQ1RFRCAtLS0tLS0tLS0tLVwiKTtcbiAgICAgICAgaWYgKHN0YXR1cyA9PT0gQ09OTkVDVEVEKSB7XG4gICAgICAgICAgICBMb2dnZXIuZXJyb3IoXCJXZWJzb2NrZXQgYWxyZWFkeSBpbiBDT05ORUNURUQgc3RhdGUgd2hlbiByZWNlaXZpbmcgYSBuZXcgT05SRUNPTk5FQ1RFRCBtZXNzYWdlLiBJZ25vcmluZyBpdFwiKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBzdGF0dXMgPSBDT05ORUNURUQ7XG5cbiAgICAgICAgZW5hYmxlZFBpbmdzID0gdHJ1ZTtcbiAgICAgICAgdXBkYXRlTm90UmVjb25uZWN0SWZMZXNzVGhhbigpO1xuICAgICAgICB1c2VQaW5nKCk7XG5cbiAgICAgICAgaWYgKG9ucmVjb25uZWN0ZWQpIHtcbiAgICAgICAgICAgIG9ucmVjb25uZWN0ZWQoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHdzQ29uZmlnLm9uY29ubmVjdGVkID0gZnVuY3Rpb24oKSB7XG4gICAgICAgIExvZ2dlci5kZWJ1ZyhcIi0tLS0tLS0tLSBPTkNPTk5FQ1RFRCAtLS0tLS0tLS0tLVwiKTtcbiAgICAgICAgaWYgKHN0YXR1cyA9PT0gQ09OTkVDVEVEKSB7XG4gICAgICAgICAgICBMb2dnZXIuZXJyb3IoXCJXZWJzb2NrZXQgYWxyZWFkeSBpbiBDT05ORUNURUQgc3RhdGUgd2hlbiByZWNlaXZpbmcgYSBuZXcgT05DT05ORUNURUQgbWVzc2FnZS4gSWdub3JpbmcgaXRcIik7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgc3RhdHVzID0gQ09OTkVDVEVEO1xuXG4gICAgICAgIGVuYWJsZWRQaW5ncyA9IHRydWU7XG4gICAgICAgIHVzZVBpbmcoKTtcblxuICAgICAgICBpZiAob25jb25uZWN0ZWQpIHtcbiAgICAgICAgICAgIG9uY29ubmVjdGVkKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICB3c0NvbmZpZy5vbmVycm9yID0gZnVuY3Rpb24oZXJyb3IpIHtcbiAgICAgICAgTG9nZ2VyLmRlYnVnKFwiLS0tLS0tLS0tIE9ORVJST1IgLS0tLS0tLS0tLS1cIik7XG5cbiAgICAgICAgc3RhdHVzID0gRElTQ09OTkVDVEVEO1xuXG4gICAgICAgIGlmIChvbmVycm9yKSB7XG4gICAgICAgICAgICBvbmVycm9yKGVycm9yKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHZhciB3cyA9IG5ldyBXZWJTb2NrZXRXaXRoUmVjb25uZWN0aW9uKHdzQ29uZmlnKTtcblxuICAgIExvZ2dlci5kZWJ1ZygnQ29ubmVjdGluZyB3ZWJzb2NrZXQgdG8gVVJJOiAnICsgd3NDb25maWcudXJpKTtcblxuICAgIHZhciBycGNCdWlsZGVyT3B0aW9ucyA9IHtcbiAgICAgICAgcmVxdWVzdF90aW1lb3V0OiBjb25maWd1cmF0aW9uLnJwYy5yZXF1ZXN0VGltZW91dCxcbiAgICAgICAgcGluZ19yZXF1ZXN0X3RpbWVvdXQ6IGNvbmZpZ3VyYXRpb24ucnBjLmhlYXJ0YmVhdFJlcXVlc3RUaW1lb3V0XG4gICAgfTtcblxuICAgIHZhciBycGMgPSBuZXcgUnBjQnVpbGRlcihScGNCdWlsZGVyLnBhY2tlcnMuSnNvblJQQywgcnBjQnVpbGRlck9wdGlvbnMsIHdzLFxuICAgICAgICBmdW5jdGlvbihyZXF1ZXN0KSB7XG5cbiAgICAgICAgICAgIExvZ2dlci5kZWJ1ZygnUmVjZWl2ZWQgcmVxdWVzdDogJyArIEpTT04uc3RyaW5naWZ5KHJlcXVlc3QpKTtcblxuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICB2YXIgZnVuYyA9IGNvbmZpZ3VyYXRpb24ucnBjW3JlcXVlc3QubWV0aG9kXTtcblxuICAgICAgICAgICAgICAgIGlmIChmdW5jID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgTG9nZ2VyLmVycm9yKFwiTWV0aG9kIFwiICsgcmVxdWVzdC5tZXRob2QgKyBcIiBub3QgcmVnaXN0ZXJlZCBpbiBjbGllbnRcIik7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgZnVuYyhyZXF1ZXN0LnBhcmFtcywgcmVxdWVzdCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICAgICAgTG9nZ2VyLmVycm9yKCdFeGNlcHRpb24gcHJvY2Vzc2luZyByZXF1ZXN0OiAnICsgSlNPTi5zdHJpbmdpZnkocmVxdWVzdCkpO1xuICAgICAgICAgICAgICAgIExvZ2dlci5lcnJvcihlcnIpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgIHRoaXMuc2VuZCA9IGZ1bmN0aW9uKG1ldGhvZCwgcGFyYW1zLCBjYWxsYmFjaykge1xuICAgICAgICBpZiAobWV0aG9kICE9PSAncGluZycpIHtcbiAgICAgICAgICAgIExvZ2dlci5kZWJ1ZygnUmVxdWVzdDogbWV0aG9kOicgKyBtZXRob2QgKyBcIiBwYXJhbXM6XCIgKyBKU09OLnN0cmluZ2lmeShwYXJhbXMpKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciByZXF1ZXN0VGltZSA9IERhdGUubm93KCk7XG5cbiAgICAgICAgcnBjLmVuY29kZShtZXRob2QsIHBhcmFtcywgZnVuY3Rpb24oZXJyb3IsIHJlc3VsdCkge1xuICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgTG9nZ2VyLmVycm9yKFwiRVJST1I6XCIgKyBlcnJvci5tZXNzYWdlICsgXCIgaW4gUmVxdWVzdDogbWV0aG9kOlwiICtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1ldGhvZCArIFwiIHBhcmFtczpcIiArIEpTT04uc3RyaW5naWZ5KHBhcmFtcykgKyBcIiByZXF1ZXN0OlwiICtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yLnJlcXVlc3QpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IuZGF0YSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgTG9nZ2VyLmVycm9yKFwiRVJST1IgREFUQTpcIiArIEpTT04uc3RyaW5naWZ5KGVycm9yLmRhdGEpKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHt9XG4gICAgICAgICAgICAgICAgZXJyb3IucmVxdWVzdFRpbWUgPSByZXF1ZXN0VGltZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChjYWxsYmFjaykge1xuICAgICAgICAgICAgICAgIGlmIChyZXN1bHQgIT0gdW5kZWZpbmVkICYmIHJlc3VsdC52YWx1ZSAhPT0gJ3BvbmcnKSB7XG4gICAgICAgICAgICAgICAgICAgIExvZ2dlci5kZWJ1ZygnUmVzcG9uc2U6ICcgKyBKU09OLnN0cmluZ2lmeShyZXN1bHQpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY2FsbGJhY2soZXJyb3IsIHJlc3VsdCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHVwZGF0ZU5vdFJlY29ubmVjdElmTGVzc1RoYW4oKSB7XG4gICAgICAgIExvZ2dlci5kZWJ1ZyhcIm5vdFJlY29ubmVjdElmTnVtTGVzc1RoYW4gPSBcIiArIHBpbmdOZXh0TnVtICsgJyAob2xkPScgK1xuICAgICAgICAgICAgbm90UmVjb25uZWN0SWZOdW1MZXNzVGhhbiArICcpJyk7XG4gICAgICAgIG5vdFJlY29ubmVjdElmTnVtTGVzc1RoYW4gPSBwaW5nTmV4dE51bTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBzZW5kUGluZygpIHtcbiAgICAgICAgaWYgKGVuYWJsZWRQaW5ncykge1xuICAgICAgICAgICAgdmFyIHBhcmFtcyA9IG51bGw7XG4gICAgICAgICAgICBpZiAocGluZ05leHROdW0gPT0gMCB8fCBwaW5nTmV4dE51bSA9PSBub3RSZWNvbm5lY3RJZk51bUxlc3NUaGFuKSB7XG4gICAgICAgICAgICAgICAgcGFyYW1zID0ge1xuICAgICAgICAgICAgICAgICAgICBpbnRlcnZhbDogY29uZmlndXJhdGlvbi5oZWFydGJlYXQgfHwgUElOR19JTlRFUlZBTFxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBwaW5nTmV4dE51bSsrO1xuXG4gICAgICAgICAgICBzZWxmLnNlbmQoJ3BpbmcnLCBwYXJhbXMsIChmdW5jdGlvbihwaW5nTnVtKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKGVycm9yLCByZXN1bHQpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBMb2dnZXIuZGVidWcoXCJFcnJvciBpbiBwaW5nIHJlcXVlc3QgI1wiICsgcGluZ051bSArIFwiIChcIiArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3IubWVzc2FnZSArIFwiKVwiKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwaW5nTnVtID4gbm90UmVjb25uZWN0SWZOdW1MZXNzVGhhbikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVuYWJsZWRQaW5ncyA9IGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVwZGF0ZU5vdFJlY29ubmVjdElmTGVzc1RoYW4oKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBMb2dnZXIuZGVidWcoXCJTZXJ2ZXIgZGlkIG5vdCByZXNwb25kIHRvIHBpbmcgbWVzc2FnZSAjXCIgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwaW5nTnVtICsgXCIuIFJlY29ubmVjdGluZy4uLiBcIik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgd3MucmVjb25uZWN0V3MoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pKHBpbmdOZXh0TnVtKSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBMb2dnZXIuZGVidWcoXCJUcnlpbmcgdG8gc2VuZCBwaW5nLCBidXQgcGluZyBpcyBub3QgZW5hYmxlZFwiKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qXG4gICAgKiBJZiBjb25maWd1cmF0aW9uLmhlYXJiZWF0IGhhcyBhbnkgdmFsdWUsIHRoZSBwaW5nLXBvbmcgd2lsbCB3b3JrIHdpdGggdGhlIGludGVydmFsXG4gICAgKiBvZiBjb25maWd1cmF0aW9uLmhlYXJiZWF0XG4gICAgKi9cbiAgICBmdW5jdGlvbiB1c2VQaW5nKCkge1xuICAgICAgICBpZiAoIXBpbmdQb25nU3RhcnRlZCkge1xuICAgICAgICAgICAgTG9nZ2VyLmRlYnVnKFwiU3RhcnRpbmcgcGluZyAoaWYgY29uZmlndXJlZClcIilcbiAgICAgICAgICAgIHBpbmdQb25nU3RhcnRlZCA9IHRydWU7XG5cbiAgICAgICAgICAgIGlmIChjb25maWd1cmF0aW9uLmhlYXJ0YmVhdCAhPSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICBwaW5nSW50ZXJ2YWwgPSBzZXRJbnRlcnZhbChzZW5kUGluZywgY29uZmlndXJhdGlvbi5oZWFydGJlYXQpO1xuICAgICAgICAgICAgICAgIHNlbmRQaW5nKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICB0aGlzLmNsb3NlID0gZnVuY3Rpb24oKSB7XG4gICAgICAgIExvZ2dlci5kZWJ1ZyhcIkNsb3NpbmcganNvblJwY0NsaWVudCBleHBsaWNpdGx5IGJ5IGNsaWVudFwiKTtcblxuICAgICAgICBpZiAocGluZ0ludGVydmFsICE9IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgTG9nZ2VyLmRlYnVnKFwiQ2xlYXJpbmcgcGluZyBpbnRlcnZhbFwiKTtcbiAgICAgICAgICAgIGNsZWFySW50ZXJ2YWwocGluZ0ludGVydmFsKTtcbiAgICAgICAgfVxuICAgICAgICBwaW5nUG9uZ1N0YXJ0ZWQgPSBmYWxzZTtcbiAgICAgICAgZW5hYmxlZFBpbmdzID0gZmFsc2U7XG5cbiAgICAgICAgaWYgKGNvbmZpZ3VyYXRpb24uc2VuZENsb3NlTWVzc2FnZSkge1xuICAgICAgICAgICAgTG9nZ2VyLmRlYnVnKFwiU2VuZGluZyBjbG9zZSBtZXNzYWdlXCIpXG4gICAgICAgICAgICB0aGlzLnNlbmQoJ2Nsb3NlU2Vzc2lvbicsIG51bGwsIGZ1bmN0aW9uKGVycm9yLCByZXN1bHQpIHtcbiAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgTG9nZ2VyLmVycm9yKFwiRXJyb3Igc2VuZGluZyBjbG9zZSBtZXNzYWdlOiBcIiArIEpTT04uc3RyaW5naWZ5KGVycm9yKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHdzLmNsb3NlKCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIHtcblx0XHRcdHdzLmNsb3NlKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBUaGlzIG1ldGhvZCBpcyBvbmx5IGZvciB0ZXN0aW5nXG4gICAgdGhpcy5mb3JjZUNsb3NlID0gZnVuY3Rpb24obWlsbGlzKSB7XG4gICAgICAgIHdzLmZvcmNlQ2xvc2UobWlsbGlzKTtcbiAgICB9XG5cbiAgICB0aGlzLnJlY29ubmVjdCA9IGZ1bmN0aW9uKCkge1xuICAgICAgICB3cy5yZWNvbm5lY3RXcygpO1xuICAgIH1cbn1cblxuXG5tb2R1bGUuZXhwb3J0cyA9IEpzb25ScGNDbGllbnQ7XG4iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE0IEt1cmVudG8gKGh0dHA6Ly9rdXJlbnRvLm9yZy8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxudmFyIFdlYlNvY2tldFdpdGhSZWNvbm5lY3Rpb24gID0gcmVxdWlyZSgnLi93ZWJTb2NrZXRXaXRoUmVjb25uZWN0aW9uJyk7XG5cblxuZXhwb3J0cy5XZWJTb2NrZXRXaXRoUmVjb25uZWN0aW9uICA9IFdlYlNvY2tldFdpdGhSZWNvbm5lY3Rpb247IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxMy0yMDE1IEt1cmVudG8gKGh0dHA6Ly9rdXJlbnRvLm9yZy8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqL1xuXG5cInVzZSBzdHJpY3RcIjtcblxudmFyIEJyb3dzZXJXZWJTb2NrZXQgPSBnbG9iYWwuV2ViU29ja2V0IHx8IGdsb2JhbC5Nb3pXZWJTb2NrZXQ7XG5cbnZhciBMb2dnZXIgPSBjb25zb2xlO1xuXG4vKipcbiAqIEdldCBlaXRoZXIgdGhlIGBXZWJTb2NrZXRgIG9yIGBNb3pXZWJTb2NrZXRgIGdsb2JhbHNcbiAqIGluIHRoZSBicm93c2VyIG9yIHRyeSB0byByZXNvbHZlIFdlYlNvY2tldC1jb21wYXRpYmxlXG4gKiBpbnRlcmZhY2UgZXhwb3NlZCBieSBgd3NgIGZvciBOb2RlLWxpa2UgZW52aXJvbm1lbnQuXG4gKi9cblxuLyp2YXIgV2ViU29ja2V0ID0gQnJvd3NlcldlYlNvY2tldDtcbmlmICghV2ViU29ja2V0ICYmIHR5cGVvZiB3aW5kb3cgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgdHJ5IHtcbiAgICAgICAgV2ViU29ja2V0ID0gcmVxdWlyZSgnd3MnKTtcbiAgICB9IGNhdGNoIChlKSB7IH1cbn0qL1xuXG4vL3ZhciBTb2NrSlMgPSByZXF1aXJlKCdzb2NranMtY2xpZW50Jyk7XG5cbnZhciBNQVhfUkVUUklFUyA9IDIwMDA7IC8vIEZvcmV2ZXIuLi5cbnZhciBSRVRSWV9USU1FX01TID0gMzAwMDsgLy8gRklYTUU6IEltcGxlbWVudCBleHBvbmVudGlhbCB3YWl0IHRpbWVzLi4uXG5cbnZhciBDT05ORUNUSU5HID0gMDtcbnZhciBPUEVOID0gMTtcbnZhciBDTE9TSU5HID0gMjtcbnZhciBDTE9TRUQgPSAzO1xuXG4vKlxuY29uZmlnID0ge1xuXHRcdHVyaSA6IHdzVXJpLFxuXHRcdHVzZVNvY2tKUyA6IHRydWUgKHVzZSBTb2NrSlMpIC8gZmFsc2UgKHVzZSBXZWJTb2NrZXQpIGJ5IGRlZmF1bHQsXG5cdFx0b25jb25uZWN0ZWQgOiBjYWxsYmFjayBtZXRob2QgdG8gaW52b2tlIHdoZW4gY29ubmVjdGlvbiBpcyBzdWNjZXNzZnVsLFxuXHRcdG9uZGlzY29ubmVjdCA6IGNhbGxiYWNrIG1ldGhvZCB0byBpbnZva2Ugd2hlbiB0aGUgY29ubmVjdGlvbiBpcyBsb3N0LFxuXHRcdG9ucmVjb25uZWN0aW5nIDogY2FsbGJhY2sgbWV0aG9kIHRvIGludm9rZSB3aGVuIHRoZSBjbGllbnQgaXMgcmVjb25uZWN0aW5nLFxuXHRcdG9ucmVjb25uZWN0ZWQgOiBjYWxsYmFjayBtZXRob2QgdG8gaW52b2tlIHdoZW4gdGhlIGNsaWVudCBzdWNjZXNmdWxseSByZWNvbm5lY3RzLFxuXHR9O1xuKi9cbmZ1bmN0aW9uIFdlYlNvY2tldFdpdGhSZWNvbm5lY3Rpb24oY29uZmlnKSB7XG5cbiAgICB2YXIgY2xvc2luZyA9IGZhbHNlO1xuICAgIHZhciByZWdpc3Rlck1lc3NhZ2VIYW5kbGVyO1xuICAgIHZhciB3c1VyaSA9IGNvbmZpZy51cmk7XG4gICAgdmFyIHVzZVNvY2tKUyA9IGNvbmZpZy51c2VTb2NrSlM7XG4gICAgdmFyIHJlY29ubmVjdGluZyA9IGZhbHNlO1xuXG4gICAgdmFyIGZvcmNpbmdEaXNjb25uZWN0aW9uID0gZmFsc2U7XG5cbiAgICB2YXIgd3M7XG5cbiAgICBpZiAodXNlU29ja0pTKSB7XG4gICAgICAgIHdzID0gbmV3IFNvY2tKUyh3c1VyaSk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgd3MgPSBuZXcgV2ViU29ja2V0KHdzVXJpKTtcbiAgICB9XG5cbiAgICB3cy5vbm9wZW4gPSBmdW5jdGlvbigpIHtcbiAgICAgICAgbG9nQ29ubmVjdGVkKHdzLCB3c1VyaSk7XG4gICAgICAgIGlmIChjb25maWcub25jb25uZWN0ZWQpIHtcbiAgICAgICAgICAgIGNvbmZpZy5vbmNvbm5lY3RlZCgpO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIHdzLm9uZXJyb3IgPSBmdW5jdGlvbihlcnJvcikge1xuICAgICAgICBMb2dnZXIuZXJyb3IoXCJDb3VsZCBub3QgY29ubmVjdCB0byBcIiArIHdzVXJpICsgXCIgKGludm9raW5nIG9uZXJyb3IgaWYgZGVmaW5lZClcIiwgZXJyb3IpO1xuICAgICAgICBpZiAoY29uZmlnLm9uZXJyb3IpIHtcbiAgICAgICAgICAgIGNvbmZpZy5vbmVycm9yKGVycm9yKTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICBmdW5jdGlvbiBsb2dDb25uZWN0ZWQod3MsIHdzVXJpKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBMb2dnZXIuZGVidWcoXCJXZWJTb2NrZXQgY29ubmVjdGVkIHRvIFwiICsgd3NVcmkpO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICBMb2dnZXIuZXJyb3IoZSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICB2YXIgcmVjb25uZWN0aW9uT25DbG9zZSA9IGZ1bmN0aW9uKCkge1xuICAgICAgICBpZiAod3MucmVhZHlTdGF0ZSA9PT0gQ0xPU0VEKSB7XG4gICAgICAgICAgICBpZiAoY2xvc2luZykge1xuICAgICAgICAgICAgICAgIExvZ2dlci5kZWJ1ZyhcIkNvbm5lY3Rpb24gY2xvc2VkIGJ5IHVzZXJcIik7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIExvZ2dlci5kZWJ1ZyhcIkNvbm5lY3Rpb24gY2xvc2VkIHVuZXhwZWN0ZWNseS4gUmVjb25uZWN0aW5nLi4uXCIpO1xuICAgICAgICAgICAgICAgIHJlY29ubmVjdFRvU2FtZVVyaShNQVhfUkVUUklFUywgMSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBMb2dnZXIuZGVidWcoXCJDbG9zZSBjYWxsYmFjayBmcm9tIHByZXZpb3VzIHdlYnNvY2tldC4gSWdub3JpbmcgaXRcIik7XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgd3Mub25jbG9zZSA9IHJlY29ubmVjdGlvbk9uQ2xvc2U7XG5cbiAgICBmdW5jdGlvbiByZWNvbm5lY3RUb1NhbWVVcmkobWF4UmV0cmllcywgbnVtUmV0cmllcykge1xuICAgICAgICBMb2dnZXIuZGVidWcoXCJyZWNvbm5lY3RUb1NhbWVVcmkgKGF0dGVtcHQgI1wiICsgbnVtUmV0cmllcyArIFwiLCBtYXg9XCIgKyBtYXhSZXRyaWVzICsgXCIpXCIpO1xuXG4gICAgICAgIGlmIChudW1SZXRyaWVzID09PSAxKSB7XG4gICAgICAgICAgICBpZiAocmVjb25uZWN0aW5nKSB7XG4gICAgICAgICAgICAgICAgTG9nZ2VyLndhcm4oXCJUcnlpbmcgdG8gcmVjb25uZWN0VG9OZXdVcmkgd2hlbiByZWNvbm5lY3RpbmcuLi4gSWdub3JpbmcgdGhpcyByZWNvbm5lY3Rpb24uXCIpXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZWNvbm5lY3RpbmcgPSB0cnVlO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoY29uZmlnLm9ucmVjb25uZWN0aW5nKSB7XG4gICAgICAgICAgICAgICAgY29uZmlnLm9ucmVjb25uZWN0aW5nKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoZm9yY2luZ0Rpc2Nvbm5lY3Rpb24pIHtcbiAgICAgICAgICAgIHJlY29ubmVjdFRvTmV3VXJpKG1heFJldHJpZXMsIG51bVJldHJpZXMsIHdzVXJpKTtcblxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaWYgKGNvbmZpZy5uZXdXc1VyaU9uUmVjb25uZWN0aW9uKSB7XG4gICAgICAgICAgICAgICAgY29uZmlnLm5ld1dzVXJpT25SZWNvbm5lY3Rpb24oZnVuY3Rpb24oZXJyb3IsIG5ld1dzVXJpKSB7XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBMb2dnZXIuZGVidWcoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbigpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWNvbm5lY3RUb1NhbWVVcmkobWF4UmV0cmllcywgbnVtUmV0cmllcyArIDEpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSwgUkVUUllfVElNRV9NUyk7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZWNvbm5lY3RUb05ld1VyaShtYXhSZXRyaWVzLCBudW1SZXRyaWVzLCBuZXdXc1VyaSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZWNvbm5lY3RUb05ld1VyaShtYXhSZXRyaWVzLCBudW1SZXRyaWVzLCB3c1VyaSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBUT0RPIFRlc3QgcmV0cmllcy4gSG93IHRvIGZvcmNlIG5vdCBjb25uZWN0aW9uP1xuICAgIGZ1bmN0aW9uIHJlY29ubmVjdFRvTmV3VXJpKG1heFJldHJpZXMsIG51bVJldHJpZXMsIHJlY29ubmVjdFdzVXJpKSB7XG4gICAgICAgIExvZ2dlci5kZWJ1ZyhcIlJlY29ubmVjdGlvbiBhdHRlbXB0ICNcIiArIG51bVJldHJpZXMpO1xuXG4gICAgICAgIHdzLmNsb3NlKCk7XG5cbiAgICAgICAgd3NVcmkgPSByZWNvbm5lY3RXc1VyaSB8fCB3c1VyaTtcblxuICAgICAgICB2YXIgbmV3V3M7XG4gICAgICAgIGlmICh1c2VTb2NrSlMpIHtcbiAgICAgICAgICAgIG5ld1dzID0gbmV3IFNvY2tKUyh3c1VyaSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBuZXdXcyA9IG5ldyBXZWJTb2NrZXQod3NVcmkpO1xuICAgICAgICB9XG5cbiAgICAgICAgbmV3V3Mub25vcGVuID0gZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICBMb2dnZXIuZGVidWcoXCJSZWNvbm5lY3RlZCBhZnRlciBcIiArIG51bVJldHJpZXMgKyBcIiBhdHRlbXB0cy4uLlwiKTtcbiAgICAgICAgICAgIGxvZ0Nvbm5lY3RlZChuZXdXcywgd3NVcmkpO1xuICAgICAgICAgICAgcmVjb25uZWN0aW5nID0gZmFsc2U7XG4gICAgICAgICAgICByZWdpc3Rlck1lc3NhZ2VIYW5kbGVyKCk7XG4gICAgICAgICAgICBpZiAoY29uZmlnLm9ucmVjb25uZWN0ZWQoKSkge1xuICAgICAgICAgICAgICAgIGNvbmZpZy5vbnJlY29ubmVjdGVkKCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIG5ld1dzLm9uY2xvc2UgPSByZWNvbm5lY3Rpb25PbkNsb3NlO1xuICAgICAgICB9O1xuXG4gICAgICAgIHZhciBvbkVycm9yT3JDbG9zZSA9IGZ1bmN0aW9uKGVycm9yKSB7XG4gICAgICAgICAgICBMb2dnZXIud2FybihcIlJlY29ubmVjdGlvbiBlcnJvcjogXCIsIGVycm9yKTtcblxuICAgICAgICAgICAgaWYgKG51bVJldHJpZXMgPT09IG1heFJldHJpZXMpIHtcbiAgICAgICAgICAgICAgICBpZiAoY29uZmlnLm9uZGlzY29ubmVjdCkge1xuICAgICAgICAgICAgICAgICAgICBjb25maWcub25kaXNjb25uZWN0KCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgICAgICAgICByZWNvbm5lY3RUb1NhbWVVcmkobWF4UmV0cmllcywgbnVtUmV0cmllcyArIDEpO1xuICAgICAgICAgICAgICAgIH0sIFJFVFJZX1RJTUVfTVMpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuXG4gICAgICAgIG5ld1dzLm9uZXJyb3IgPSBvbkVycm9yT3JDbG9zZTtcblxuICAgICAgICB3cyA9IG5ld1dzO1xuICAgIH1cblxuICAgIHRoaXMuY2xvc2UgPSBmdW5jdGlvbigpIHtcbiAgICAgICAgY2xvc2luZyA9IHRydWU7XG4gICAgICAgIHdzLmNsb3NlKCk7XG4gICAgfTtcblxuXG4gICAgLy8gVGhpcyBtZXRob2QgaXMgb25seSBmb3IgdGVzdGluZ1xuICAgIHRoaXMuZm9yY2VDbG9zZSA9IGZ1bmN0aW9uKG1pbGxpcykge1xuICAgICAgICBMb2dnZXIuZGVidWcoXCJUZXN0aW5nOiBGb3JjZSBXZWJTb2NrZXQgY2xvc2VcIik7XG5cbiAgICAgICAgaWYgKG1pbGxpcykge1xuICAgICAgICAgICAgTG9nZ2VyLmRlYnVnKFwiVGVzdGluZzogQ2hhbmdlIHdzVXJpIGZvciBcIiArIG1pbGxpcyArIFwiIG1pbGxpcyB0byBzaW11bGF0ZSBuZXQgZmFpbHVyZVwiKTtcbiAgICAgICAgICAgIHZhciBnb29kV3NVcmkgPSB3c1VyaTtcbiAgICAgICAgICAgIHdzVXJpID0gXCJ3c3M6Ly8yMS4yMzQuMTIuMzQuNDo0NDMvXCI7XG5cbiAgICAgICAgICAgIGZvcmNpbmdEaXNjb25uZWN0aW9uID0gdHJ1ZTtcblxuICAgICAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbigpIHtcbiAgICAgICAgICAgICAgICBMb2dnZXIuZGVidWcoXCJUZXN0aW5nOiBSZWNvdmVyIGdvb2Qgd3NVcmkgXCIgKyBnb29kV3NVcmkpO1xuICAgICAgICAgICAgICAgIHdzVXJpID0gZ29vZFdzVXJpO1xuXG4gICAgICAgICAgICAgICAgZm9yY2luZ0Rpc2Nvbm5lY3Rpb24gPSBmYWxzZTtcblxuICAgICAgICAgICAgfSwgbWlsbGlzKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHdzLmNsb3NlKCk7XG4gICAgfTtcblxuICAgIHRoaXMucmVjb25uZWN0V3MgPSBmdW5jdGlvbigpIHtcbiAgICAgICAgTG9nZ2VyLmRlYnVnKFwicmVjb25uZWN0V3NcIik7XG4gICAgICAgIHJlY29ubmVjdFRvU2FtZVVyaShNQVhfUkVUUklFUywgMSwgd3NVcmkpO1xuICAgIH07XG5cbiAgICB0aGlzLnNlbmQgPSBmdW5jdGlvbihtZXNzYWdlKSB7XG4gICAgICAgIHdzLnNlbmQobWVzc2FnZSk7XG4gICAgfTtcblxuICAgIHRoaXMuYWRkRXZlbnRMaXN0ZW5lciA9IGZ1bmN0aW9uKHR5cGUsIGNhbGxiYWNrKSB7XG4gICAgICAgIHJlZ2lzdGVyTWVzc2FnZUhhbmRsZXIgPSBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgIHdzLmFkZEV2ZW50TGlzdGVuZXIodHlwZSwgY2FsbGJhY2spO1xuICAgICAgICB9O1xuXG4gICAgICAgIHJlZ2lzdGVyTWVzc2FnZUhhbmRsZXIoKTtcbiAgICB9O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IFdlYlNvY2tldFdpdGhSZWNvbm5lY3Rpb247XG4iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE0IEt1cmVudG8gKGh0dHA6Ly9rdXJlbnRvLm9yZy8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuXG52YXIgZGVmaW5lUHJvcGVydHlfSUU4ID0gZmFsc2VcbmlmKE9iamVjdC5kZWZpbmVQcm9wZXJ0eSlcbntcbiAgdHJ5XG4gIHtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoe30sIFwieFwiLCB7fSk7XG4gIH1cbiAgY2F0Y2goZSlcbiAge1xuICAgIGRlZmluZVByb3BlcnR5X0lFOCA9IHRydWVcbiAgfVxufVxuXG4vLyBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9KYXZhU2NyaXB0L1JlZmVyZW5jZS9HbG9iYWxfT2JqZWN0cy9GdW5jdGlvbi9iaW5kXG5pZiAoIUZ1bmN0aW9uLnByb3RvdHlwZS5iaW5kKSB7XG4gIEZ1bmN0aW9uLnByb3RvdHlwZS5iaW5kID0gZnVuY3Rpb24ob1RoaXMpIHtcbiAgICBpZiAodHlwZW9mIHRoaXMgIT09ICdmdW5jdGlvbicpIHtcbiAgICAgIC8vIGNsb3Nlc3QgdGhpbmcgcG9zc2libGUgdG8gdGhlIEVDTUFTY3JpcHQgNVxuICAgICAgLy8gaW50ZXJuYWwgSXNDYWxsYWJsZSBmdW5jdGlvblxuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignRnVuY3Rpb24ucHJvdG90eXBlLmJpbmQgLSB3aGF0IGlzIHRyeWluZyB0byBiZSBib3VuZCBpcyBub3QgY2FsbGFibGUnKTtcbiAgICB9XG5cbiAgICB2YXIgYUFyZ3MgICA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMSksXG4gICAgICAgIGZUb0JpbmQgPSB0aGlzLFxuICAgICAgICBmTk9QICAgID0gZnVuY3Rpb24oKSB7fSxcbiAgICAgICAgZkJvdW5kICA9IGZ1bmN0aW9uKCkge1xuICAgICAgICAgIHJldHVybiBmVG9CaW5kLmFwcGx5KHRoaXMgaW5zdGFuY2VvZiBmTk9QICYmIG9UaGlzXG4gICAgICAgICAgICAgICAgID8gdGhpc1xuICAgICAgICAgICAgICAgICA6IG9UaGlzLFxuICAgICAgICAgICAgICAgICBhQXJncy5jb25jYXQoQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzKSkpO1xuICAgICAgICB9O1xuXG4gICAgZk5PUC5wcm90b3R5cGUgPSB0aGlzLnByb3RvdHlwZTtcbiAgICBmQm91bmQucHJvdG90eXBlID0gbmV3IGZOT1AoKTtcblxuICAgIHJldHVybiBmQm91bmQ7XG4gIH07XG59XG5cblxudmFyIEV2ZW50RW1pdHRlciA9IHJlcXVpcmUoJ2V2ZW50cycpLkV2ZW50RW1pdHRlcjtcblxudmFyIGluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKTtcblxudmFyIHBhY2tlcnMgPSByZXF1aXJlKCcuL3BhY2tlcnMnKTtcbnZhciBNYXBwZXIgPSByZXF1aXJlKCcuL01hcHBlcicpO1xuXG5cbnZhciBCQVNFX1RJTUVPVVQgPSA1MDAwO1xuXG5cbmZ1bmN0aW9uIHVuaWZ5UmVzcG9uc2VNZXRob2RzKHJlc3BvbnNlTWV0aG9kcylcbntcbiAgaWYoIXJlc3BvbnNlTWV0aG9kcykgcmV0dXJuIHt9O1xuXG4gIGZvcih2YXIga2V5IGluIHJlc3BvbnNlTWV0aG9kcylcbiAge1xuICAgIHZhciB2YWx1ZSA9IHJlc3BvbnNlTWV0aG9kc1trZXldO1xuXG4gICAgaWYodHlwZW9mIHZhbHVlID09ICdzdHJpbmcnKVxuICAgICAgcmVzcG9uc2VNZXRob2RzW2tleV0gPVxuICAgICAge1xuICAgICAgICByZXNwb25zZTogdmFsdWVcbiAgICAgIH1cbiAgfTtcblxuICByZXR1cm4gcmVzcG9uc2VNZXRob2RzO1xufTtcblxuZnVuY3Rpb24gdW5pZnlUcmFuc3BvcnQodHJhbnNwb3J0KVxue1xuICBpZighdHJhbnNwb3J0KSByZXR1cm47XG5cbiAgLy8gVHJhbnNwb3J0IGFzIGEgZnVuY3Rpb25cbiAgaWYodHJhbnNwb3J0IGluc3RhbmNlb2YgRnVuY3Rpb24pXG4gICAgcmV0dXJuIHtzZW5kOiB0cmFuc3BvcnR9O1xuXG4gIC8vIFdlYlNvY2tldCAmIERhdGFDaGFubmVsXG4gIGlmKHRyYW5zcG9ydC5zZW5kIGluc3RhbmNlb2YgRnVuY3Rpb24pXG4gICAgcmV0dXJuIHRyYW5zcG9ydDtcblxuICAvLyBNZXNzYWdlIEFQSSAoSW50ZXItd2luZG93ICYgV2ViV29ya2VyKVxuICBpZih0cmFuc3BvcnQucG9zdE1lc3NhZ2UgaW5zdGFuY2VvZiBGdW5jdGlvbilcbiAge1xuICAgIHRyYW5zcG9ydC5zZW5kID0gdHJhbnNwb3J0LnBvc3RNZXNzYWdlO1xuICAgIHJldHVybiB0cmFuc3BvcnQ7XG4gIH1cblxuICAvLyBTdHJlYW0gQVBJXG4gIGlmKHRyYW5zcG9ydC53cml0ZSBpbnN0YW5jZW9mIEZ1bmN0aW9uKVxuICB7XG4gICAgdHJhbnNwb3J0LnNlbmQgPSB0cmFuc3BvcnQud3JpdGU7XG4gICAgcmV0dXJuIHRyYW5zcG9ydDtcbiAgfVxuXG4gIC8vIFRyYW5zcG9ydHMgdGhhdCBvbmx5IGNhbiByZWNlaXZlIG1lc3NhZ2VzLCBidXQgbm90IHNlbmRcbiAgaWYodHJhbnNwb3J0Lm9ubWVzc2FnZSAhPT0gdW5kZWZpbmVkKSByZXR1cm47XG4gIGlmKHRyYW5zcG9ydC5wYXVzZSBpbnN0YW5jZW9mIEZ1bmN0aW9uKSByZXR1cm47XG5cbiAgdGhyb3cgbmV3IFN5bnRheEVycm9yKFwiVHJhbnNwb3J0IGlzIG5vdCBhIGZ1bmN0aW9uIG5vciBhIHZhbGlkIG9iamVjdFwiKTtcbn07XG5cblxuLyoqXG4gKiBSZXByZXNlbnRhdGlvbiBvZiBhIFJQQyBub3RpZmljYXRpb25cbiAqXG4gKiBAY2xhc3NcbiAqXG4gKiBAY29uc3RydWN0b3JcbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gbWV0aG9kIC1tZXRob2Qgb2YgdGhlIG5vdGlmaWNhdGlvblxuICogQHBhcmFtIHBhcmFtcyAtIHBhcmFtZXRlcnMgb2YgdGhlIG5vdGlmaWNhdGlvblxuICovXG5mdW5jdGlvbiBScGNOb3RpZmljYXRpb24obWV0aG9kLCBwYXJhbXMpXG57XG4gIGlmKGRlZmluZVByb3BlcnR5X0lFOClcbiAge1xuICAgIHRoaXMubWV0aG9kID0gbWV0aG9kXG4gICAgdGhpcy5wYXJhbXMgPSBwYXJhbXNcbiAgfVxuICBlbHNlXG4gIHtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywgJ21ldGhvZCcsIHt2YWx1ZTogbWV0aG9kLCBlbnVtZXJhYmxlOiB0cnVlfSk7XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsICdwYXJhbXMnLCB7dmFsdWU6IHBhcmFtcywgZW51bWVyYWJsZTogdHJ1ZX0pO1xuICB9XG59O1xuXG5cbi8qKlxuICogQGNsYXNzXG4gKlxuICogQGNvbnN0cnVjdG9yXG4gKlxuICogQHBhcmFtIHtvYmplY3R9IHBhY2tlclxuICpcbiAqIEBwYXJhbSB7b2JqZWN0fSBbb3B0aW9uc11cbiAqXG4gKiBAcGFyYW0ge29iamVjdH0gW3RyYW5zcG9ydF1cbiAqXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBbb25SZXF1ZXN0XVxuICovXG5mdW5jdGlvbiBScGNCdWlsZGVyKHBhY2tlciwgb3B0aW9ucywgdHJhbnNwb3J0LCBvblJlcXVlc3QpXG57XG4gIHZhciBzZWxmID0gdGhpcztcblxuICBpZighcGFja2VyKVxuICAgIHRocm93IG5ldyBTeW50YXhFcnJvcignUGFja2VyIGlzIG5vdCBkZWZpbmVkJyk7XG5cbiAgaWYoIXBhY2tlci5wYWNrIHx8ICFwYWNrZXIudW5wYWNrKVxuICAgIHRocm93IG5ldyBTeW50YXhFcnJvcignUGFja2VyIGlzIGludmFsaWQnKTtcblxuICB2YXIgcmVzcG9uc2VNZXRob2RzID0gdW5pZnlSZXNwb25zZU1ldGhvZHMocGFja2VyLnJlc3BvbnNlTWV0aG9kcyk7XG5cblxuICBpZihvcHRpb25zIGluc3RhbmNlb2YgRnVuY3Rpb24pXG4gIHtcbiAgICBpZih0cmFuc3BvcnQgIT0gdW5kZWZpbmVkKVxuICAgICAgdGhyb3cgbmV3IFN5bnRheEVycm9yKFwiVGhlcmUgY2FuJ3QgYmUgcGFyYW1ldGVycyBhZnRlciBvblJlcXVlc3RcIik7XG5cbiAgICBvblJlcXVlc3QgPSBvcHRpb25zO1xuICAgIHRyYW5zcG9ydCA9IHVuZGVmaW5lZDtcbiAgICBvcHRpb25zICAgPSB1bmRlZmluZWQ7XG4gIH07XG5cbiAgaWYob3B0aW9ucyAmJiBvcHRpb25zLnNlbmQgaW5zdGFuY2VvZiBGdW5jdGlvbilcbiAge1xuICAgIGlmKHRyYW5zcG9ydCAmJiAhKHRyYW5zcG9ydCBpbnN0YW5jZW9mIEZ1bmN0aW9uKSlcbiAgICAgIHRocm93IG5ldyBTeW50YXhFcnJvcihcIk9ubHkgYSBmdW5jdGlvbiBjYW4gYmUgYWZ0ZXIgdHJhbnNwb3J0XCIpO1xuXG4gICAgb25SZXF1ZXN0ID0gdHJhbnNwb3J0O1xuICAgIHRyYW5zcG9ydCA9IG9wdGlvbnM7XG4gICAgb3B0aW9ucyAgID0gdW5kZWZpbmVkO1xuICB9O1xuXG4gIGlmKHRyYW5zcG9ydCBpbnN0YW5jZW9mIEZ1bmN0aW9uKVxuICB7XG4gICAgaWYob25SZXF1ZXN0ICE9IHVuZGVmaW5lZClcbiAgICAgIHRocm93IG5ldyBTeW50YXhFcnJvcihcIlRoZXJlIGNhbid0IGJlIHBhcmFtZXRlcnMgYWZ0ZXIgb25SZXF1ZXN0XCIpO1xuXG4gICAgb25SZXF1ZXN0ID0gdHJhbnNwb3J0O1xuICAgIHRyYW5zcG9ydCA9IHVuZGVmaW5lZDtcbiAgfTtcblxuICBpZih0cmFuc3BvcnQgJiYgdHJhbnNwb3J0LnNlbmQgaW5zdGFuY2VvZiBGdW5jdGlvbilcbiAgICBpZihvblJlcXVlc3QgJiYgIShvblJlcXVlc3QgaW5zdGFuY2VvZiBGdW5jdGlvbikpXG4gICAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoXCJPbmx5IGEgZnVuY3Rpb24gY2FuIGJlIGFmdGVyIHRyYW5zcG9ydFwiKTtcblxuICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcblxuXG4gIEV2ZW50RW1pdHRlci5jYWxsKHRoaXMpO1xuXG4gIGlmKG9uUmVxdWVzdClcbiAgICB0aGlzLm9uKCdyZXF1ZXN0Jywgb25SZXF1ZXN0KTtcblxuXG4gIGlmKGRlZmluZVByb3BlcnR5X0lFOClcbiAgICB0aGlzLnBlZXJJRCA9IG9wdGlvbnMucGVlcklEXG4gIGVsc2VcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywgJ3BlZXJJRCcsIHt2YWx1ZTogb3B0aW9ucy5wZWVySUR9KTtcblxuICB2YXIgbWF4X3JldHJpZXMgPSBvcHRpb25zLm1heF9yZXRyaWVzIHx8IDA7XG5cblxuICBmdW5jdGlvbiB0cmFuc3BvcnRNZXNzYWdlKGV2ZW50KVxuICB7XG4gICAgc2VsZi5kZWNvZGUoZXZlbnQuZGF0YSB8fCBldmVudCk7XG4gIH07XG5cbiAgdGhpcy5nZXRUcmFuc3BvcnQgPSBmdW5jdGlvbigpXG4gIHtcbiAgICByZXR1cm4gdHJhbnNwb3J0O1xuICB9XG4gIHRoaXMuc2V0VHJhbnNwb3J0ID0gZnVuY3Rpb24odmFsdWUpXG4gIHtcbiAgICAvLyBSZW1vdmUgbGlzdGVuZXIgZnJvbSBvbGQgdHJhbnNwb3J0XG4gICAgaWYodHJhbnNwb3J0KVxuICAgIHtcbiAgICAgIC8vIFczQyB0cmFuc3BvcnRzXG4gICAgICBpZih0cmFuc3BvcnQucmVtb3ZlRXZlbnRMaXN0ZW5lcilcbiAgICAgICAgdHJhbnNwb3J0LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ21lc3NhZ2UnLCB0cmFuc3BvcnRNZXNzYWdlKTtcblxuICAgICAgLy8gTm9kZS5qcyBTdHJlYW1zIEFQSVxuICAgICAgZWxzZSBpZih0cmFuc3BvcnQucmVtb3ZlTGlzdGVuZXIpXG4gICAgICAgIHRyYW5zcG9ydC5yZW1vdmVMaXN0ZW5lcignZGF0YScsIHRyYW5zcG9ydE1lc3NhZ2UpO1xuICAgIH07XG5cbiAgICAvLyBTZXQgbGlzdGVuZXIgb24gbmV3IHRyYW5zcG9ydFxuICAgIGlmKHZhbHVlKVxuICAgIHtcbiAgICAgIC8vIFczQyB0cmFuc3BvcnRzXG4gICAgICBpZih2YWx1ZS5hZGRFdmVudExpc3RlbmVyKVxuICAgICAgICB2YWx1ZS5hZGRFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgdHJhbnNwb3J0TWVzc2FnZSk7XG5cbiAgICAgIC8vIE5vZGUuanMgU3RyZWFtcyBBUElcbiAgICAgIGVsc2UgaWYodmFsdWUuYWRkTGlzdGVuZXIpXG4gICAgICAgIHZhbHVlLmFkZExpc3RlbmVyKCdkYXRhJywgdHJhbnNwb3J0TWVzc2FnZSk7XG4gICAgfTtcblxuICAgIHRyYW5zcG9ydCA9IHVuaWZ5VHJhbnNwb3J0KHZhbHVlKTtcbiAgfVxuXG4gIGlmKCFkZWZpbmVQcm9wZXJ0eV9JRTgpXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsICd0cmFuc3BvcnQnLFxuICAgIHtcbiAgICAgIGdldDogdGhpcy5nZXRUcmFuc3BvcnQuYmluZCh0aGlzKSxcbiAgICAgIHNldDogdGhpcy5zZXRUcmFuc3BvcnQuYmluZCh0aGlzKVxuICAgIH0pXG5cbiAgdGhpcy5zZXRUcmFuc3BvcnQodHJhbnNwb3J0KTtcblxuXG4gIHZhciByZXF1ZXN0X3RpbWVvdXQgICAgICA9IG9wdGlvbnMucmVxdWVzdF90aW1lb3V0ICAgICAgfHwgQkFTRV9USU1FT1VUO1xuICB2YXIgcGluZ19yZXF1ZXN0X3RpbWVvdXQgPSBvcHRpb25zLnBpbmdfcmVxdWVzdF90aW1lb3V0IHx8IHJlcXVlc3RfdGltZW91dDtcbiAgdmFyIHJlc3BvbnNlX3RpbWVvdXQgICAgID0gb3B0aW9ucy5yZXNwb25zZV90aW1lb3V0ICAgICB8fCBCQVNFX1RJTUVPVVQ7XG4gIHZhciBkdXBsaWNhdGVzX3RpbWVvdXQgICA9IG9wdGlvbnMuZHVwbGljYXRlc190aW1lb3V0ICAgfHwgQkFTRV9USU1FT1VUO1xuXG5cbiAgdmFyIHJlcXVlc3RJRCA9IDA7XG5cbiAgdmFyIHJlcXVlc3RzICA9IG5ldyBNYXBwZXIoKTtcbiAgdmFyIHJlc3BvbnNlcyA9IG5ldyBNYXBwZXIoKTtcbiAgdmFyIHByb2Nlc3NlZFJlc3BvbnNlcyA9IG5ldyBNYXBwZXIoKTtcblxuICB2YXIgbWVzc2FnZTJLZXkgPSB7fTtcblxuXG4gIC8qKlxuICAgKiBTdG9yZSB0aGUgcmVzcG9uc2UgdG8gcHJldmVudCB0byBwcm9jZXNzIGR1cGxpY2F0ZSByZXF1ZXN0IGxhdGVyXG4gICAqL1xuICBmdW5jdGlvbiBzdG9yZVJlc3BvbnNlKG1lc3NhZ2UsIGlkLCBkZXN0KVxuICB7XG4gICAgdmFyIHJlc3BvbnNlID1cbiAgICB7XG4gICAgICBtZXNzYWdlOiBtZXNzYWdlLFxuICAgICAgLyoqIFRpbWVvdXQgdG8gYXV0by1jbGVhbiBvbGQgcmVzcG9uc2VzICovXG4gICAgICB0aW1lb3V0OiBzZXRUaW1lb3V0KGZ1bmN0aW9uKClcbiAgICAgIHtcbiAgICAgICAgcmVzcG9uc2VzLnJlbW92ZShpZCwgZGVzdCk7XG4gICAgICB9LFxuICAgICAgcmVzcG9uc2VfdGltZW91dClcbiAgICB9O1xuXG4gICAgcmVzcG9uc2VzLnNldChyZXNwb25zZSwgaWQsIGRlc3QpO1xuICB9O1xuXG4gIC8qKlxuICAgKiBTdG9yZSB0aGUgcmVzcG9uc2UgdG8gaWdub3JlIGR1cGxpY2F0ZWQgbWVzc2FnZXMgbGF0ZXJcbiAgICovXG4gIGZ1bmN0aW9uIHN0b3JlUHJvY2Vzc2VkUmVzcG9uc2UoYWNrLCBmcm9tKVxuICB7XG4gICAgdmFyIHRpbWVvdXQgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uKClcbiAgICB7XG4gICAgICBwcm9jZXNzZWRSZXNwb25zZXMucmVtb3ZlKGFjaywgZnJvbSk7XG4gICAgfSxcbiAgICBkdXBsaWNhdGVzX3RpbWVvdXQpO1xuXG4gICAgcHJvY2Vzc2VkUmVzcG9uc2VzLnNldCh0aW1lb3V0LCBhY2ssIGZyb20pO1xuICB9O1xuXG5cbiAgLyoqXG4gICAqIFJlcHJlc2VudGF0aW9uIG9mIGEgUlBDIHJlcXVlc3RcbiAgICpcbiAgICogQGNsYXNzXG4gICAqIEBleHRlbmRzIFJwY05vdGlmaWNhdGlvblxuICAgKlxuICAgKiBAY29uc3RydWN0b3JcbiAgICpcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1ldGhvZCAtbWV0aG9kIG9mIHRoZSBub3RpZmljYXRpb25cbiAgICogQHBhcmFtIHBhcmFtcyAtIHBhcmFtZXRlcnMgb2YgdGhlIG5vdGlmaWNhdGlvblxuICAgKiBAcGFyYW0ge0ludGVnZXJ9IGlkIC0gaWRlbnRpZmllciBvZiB0aGUgcmVxdWVzdFxuICAgKiBAcGFyYW0gW2Zyb21dIC0gc291cmNlIG9mIHRoZSBub3RpZmljYXRpb25cbiAgICovXG4gIGZ1bmN0aW9uIFJwY1JlcXVlc3QobWV0aG9kLCBwYXJhbXMsIGlkLCBmcm9tLCB0cmFuc3BvcnQpXG4gIHtcbiAgICBScGNOb3RpZmljYXRpb24uY2FsbCh0aGlzLCBtZXRob2QsIHBhcmFtcyk7XG5cbiAgICB0aGlzLmdldFRyYW5zcG9ydCA9IGZ1bmN0aW9uKClcbiAgICB7XG4gICAgICByZXR1cm4gdHJhbnNwb3J0O1xuICAgIH1cbiAgICB0aGlzLnNldFRyYW5zcG9ydCA9IGZ1bmN0aW9uKHZhbHVlKVxuICAgIHtcbiAgICAgIHRyYW5zcG9ydCA9IHVuaWZ5VHJhbnNwb3J0KHZhbHVlKTtcbiAgICB9XG5cbiAgICBpZighZGVmaW5lUHJvcGVydHlfSUU4KVxuICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsICd0cmFuc3BvcnQnLFxuICAgICAge1xuICAgICAgICBnZXQ6IHRoaXMuZ2V0VHJhbnNwb3J0LmJpbmQodGhpcyksXG4gICAgICAgIHNldDogdGhpcy5zZXRUcmFuc3BvcnQuYmluZCh0aGlzKVxuICAgICAgfSlcblxuICAgIHZhciByZXNwb25zZSA9IHJlc3BvbnNlcy5nZXQoaWQsIGZyb20pO1xuXG4gICAgLyoqXG4gICAgICogQGNvbnN0YW50IHtCb29sZWFufSBkdXBsaWNhdGVkXG4gICAgICovXG4gICAgaWYoISh0cmFuc3BvcnQgfHwgc2VsZi5nZXRUcmFuc3BvcnQoKSkpXG4gICAge1xuICAgICAgaWYoZGVmaW5lUHJvcGVydHlfSUU4KVxuICAgICAgICB0aGlzLmR1cGxpY2F0ZWQgPSBCb29sZWFuKHJlc3BvbnNlKVxuICAgICAgZWxzZVxuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywgJ2R1cGxpY2F0ZWQnLFxuICAgICAgICB7XG4gICAgICAgICAgdmFsdWU6IEJvb2xlYW4ocmVzcG9uc2UpXG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHZhciByZXNwb25zZU1ldGhvZCA9IHJlc3BvbnNlTWV0aG9kc1ttZXRob2RdO1xuXG4gICAgdGhpcy5wYWNrID0gcGFja2VyLnBhY2suYmluZChwYWNrZXIsIHRoaXMsIGlkKVxuXG4gICAgLyoqXG4gICAgICogR2VuZXJhdGUgYSByZXNwb25zZSB0byB0aGlzIHJlcXVlc3RcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7RXJyb3J9IFtlcnJvcl1cbiAgICAgKiBAcGFyYW0geyp9IFtyZXN1bHRdXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfVxuICAgICAqL1xuICAgIHRoaXMucmVwbHkgPSBmdW5jdGlvbihlcnJvciwgcmVzdWx0LCB0cmFuc3BvcnQpXG4gICAge1xuICAgICAgLy8gRml4IG9wdGlvbmFsIHBhcmFtZXRlcnNcbiAgICAgIGlmKGVycm9yIGluc3RhbmNlb2YgRnVuY3Rpb24gfHwgZXJyb3IgJiYgZXJyb3Iuc2VuZCBpbnN0YW5jZW9mIEZ1bmN0aW9uKVxuICAgICAge1xuICAgICAgICBpZihyZXN1bHQgIT0gdW5kZWZpbmVkKVxuICAgICAgICAgIHRocm93IG5ldyBTeW50YXhFcnJvcihcIlRoZXJlIGNhbid0IGJlIHBhcmFtZXRlcnMgYWZ0ZXIgY2FsbGJhY2tcIik7XG5cbiAgICAgICAgdHJhbnNwb3J0ID0gZXJyb3I7XG4gICAgICAgIHJlc3VsdCA9IG51bGw7XG4gICAgICAgIGVycm9yID0gdW5kZWZpbmVkO1xuICAgICAgfVxuXG4gICAgICBlbHNlIGlmKHJlc3VsdCBpbnN0YW5jZW9mIEZ1bmN0aW9uXG4gICAgICB8fCByZXN1bHQgJiYgcmVzdWx0LnNlbmQgaW5zdGFuY2VvZiBGdW5jdGlvbilcbiAgICAgIHtcbiAgICAgICAgaWYodHJhbnNwb3J0ICE9IHVuZGVmaW5lZClcbiAgICAgICAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoXCJUaGVyZSBjYW4ndCBiZSBwYXJhbWV0ZXJzIGFmdGVyIGNhbGxiYWNrXCIpO1xuXG4gICAgICAgIHRyYW5zcG9ydCA9IHJlc3VsdDtcbiAgICAgICAgcmVzdWx0ID0gbnVsbDtcbiAgICAgIH07XG5cbiAgICAgIHRyYW5zcG9ydCA9IHVuaWZ5VHJhbnNwb3J0KHRyYW5zcG9ydCk7XG5cbiAgICAgIC8vIER1cGxpY2F0ZWQgcmVxdWVzdCwgcmVtb3ZlIG9sZCByZXNwb25zZSB0aW1lb3V0XG4gICAgICBpZihyZXNwb25zZSlcbiAgICAgICAgY2xlYXJUaW1lb3V0KHJlc3BvbnNlLnRpbWVvdXQpO1xuXG4gICAgICBpZihmcm9tICE9IHVuZGVmaW5lZClcbiAgICAgIHtcbiAgICAgICAgaWYoZXJyb3IpXG4gICAgICAgICAgZXJyb3IuZGVzdCA9IGZyb207XG5cbiAgICAgICAgaWYocmVzdWx0KVxuICAgICAgICAgIHJlc3VsdC5kZXN0ID0gZnJvbTtcbiAgICAgIH07XG5cbiAgICAgIHZhciBtZXNzYWdlO1xuXG4gICAgICAvLyBOZXcgcmVxdWVzdCBvciBvdmVycmlkZW4gb25lLCBjcmVhdGUgbmV3IHJlc3BvbnNlIHdpdGggcHJvdmlkZWQgZGF0YVxuICAgICAgaWYoZXJyb3IgfHwgcmVzdWx0ICE9IHVuZGVmaW5lZClcbiAgICAgIHtcbiAgICAgICAgaWYoc2VsZi5wZWVySUQgIT0gdW5kZWZpbmVkKVxuICAgICAgICB7XG4gICAgICAgICAgaWYoZXJyb3IpXG4gICAgICAgICAgICBlcnJvci5mcm9tID0gc2VsZi5wZWVySUQ7XG4gICAgICAgICAgZWxzZVxuICAgICAgICAgICAgcmVzdWx0LmZyb20gPSBzZWxmLnBlZXJJRDtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFByb3RvY29sIGluZGljYXRlcyB0aGF0IHJlc3BvbnNlcyBoYXMgb3duIHJlcXVlc3QgbWV0aG9kc1xuICAgICAgICBpZihyZXNwb25zZU1ldGhvZClcbiAgICAgICAge1xuICAgICAgICAgIGlmKHJlc3BvbnNlTWV0aG9kLmVycm9yID09IHVuZGVmaW5lZCAmJiBlcnJvcilcbiAgICAgICAgICAgIG1lc3NhZ2UgPVxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBlcnJvcjogZXJyb3JcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICBlbHNlXG4gICAgICAgICAge1xuICAgICAgICAgICAgdmFyIG1ldGhvZCA9IGVycm9yXG4gICAgICAgICAgICAgICAgICAgICAgID8gcmVzcG9uc2VNZXRob2QuZXJyb3JcbiAgICAgICAgICAgICAgICAgICAgICAgOiByZXNwb25zZU1ldGhvZC5yZXNwb25zZTtcblxuICAgICAgICAgICAgbWVzc2FnZSA9XG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIG1ldGhvZDogbWV0aG9kLFxuICAgICAgICAgICAgICBwYXJhbXM6IGVycm9yIHx8IHJlc3VsdFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZVxuICAgICAgICAgIG1lc3NhZ2UgPVxuICAgICAgICAgIHtcbiAgICAgICAgICAgIGVycm9yOiAgZXJyb3IsXG4gICAgICAgICAgICByZXN1bHQ6IHJlc3VsdFxuICAgICAgICAgIH07XG5cbiAgICAgICAgbWVzc2FnZSA9IHBhY2tlci5wYWNrKG1lc3NhZ2UsIGlkKTtcbiAgICAgIH1cblxuICAgICAgLy8gRHVwbGljYXRlICYgbm90LW92ZXJyaWRlbiByZXF1ZXN0LCByZS1zZW5kIG9sZCByZXNwb25zZVxuICAgICAgZWxzZSBpZihyZXNwb25zZSlcbiAgICAgICAgbWVzc2FnZSA9IHJlc3BvbnNlLm1lc3NhZ2U7XG5cbiAgICAgIC8vIE5ldyBlbXB0eSByZXBseSwgcmVzcG9uc2UgbnVsbCB2YWx1ZVxuICAgICAgZWxzZVxuICAgICAgICBtZXNzYWdlID0gcGFja2VyLnBhY2soe3Jlc3VsdDogbnVsbH0sIGlkKTtcblxuICAgICAgLy8gU3RvcmUgdGhlIHJlc3BvbnNlIHRvIHByZXZlbnQgdG8gcHJvY2VzcyBhIGR1cGxpY2F0ZWQgcmVxdWVzdCBsYXRlclxuICAgICAgc3RvcmVSZXNwb25zZShtZXNzYWdlLCBpZCwgZnJvbSk7XG5cbiAgICAgIC8vIFJldHVybiB0aGUgc3RvcmVkIHJlc3BvbnNlIHNvIGl0IGNhbiBiZSBkaXJlY3RseSBzZW5kIGJhY2tcbiAgICAgIHRyYW5zcG9ydCA9IHRyYW5zcG9ydCB8fCB0aGlzLmdldFRyYW5zcG9ydCgpIHx8IHNlbGYuZ2V0VHJhbnNwb3J0KCk7XG5cbiAgICAgIGlmKHRyYW5zcG9ydClcbiAgICAgICAgcmV0dXJuIHRyYW5zcG9ydC5zZW5kKG1lc3NhZ2UpO1xuXG4gICAgICByZXR1cm4gbWVzc2FnZTtcbiAgICB9XG4gIH07XG4gIGluaGVyaXRzKFJwY1JlcXVlc3QsIFJwY05vdGlmaWNhdGlvbik7XG5cblxuICBmdW5jdGlvbiBjYW5jZWwobWVzc2FnZSlcbiAge1xuICAgIHZhciBrZXkgPSBtZXNzYWdlMktleVttZXNzYWdlXTtcbiAgICBpZigha2V5KSByZXR1cm47XG5cbiAgICBkZWxldGUgbWVzc2FnZTJLZXlbbWVzc2FnZV07XG5cbiAgICB2YXIgcmVxdWVzdCA9IHJlcXVlc3RzLnBvcChrZXkuaWQsIGtleS5kZXN0KTtcbiAgICBpZighcmVxdWVzdCkgcmV0dXJuO1xuXG4gICAgY2xlYXJUaW1lb3V0KHJlcXVlc3QudGltZW91dCk7XG5cbiAgICAvLyBTdGFydCBkdXBsaWNhdGVkIHJlc3BvbnNlcyB0aW1lb3V0XG4gICAgc3RvcmVQcm9jZXNzZWRSZXNwb25zZShrZXkuaWQsIGtleS5kZXN0KTtcbiAgfTtcblxuICAvKipcbiAgICogQWxsb3cgdG8gY2FuY2VsIGEgcmVxdWVzdCBhbmQgZG9uJ3Qgd2FpdCBmb3IgYSByZXNwb25zZVxuICAgKlxuICAgKiBJZiBgbWVzc2FnZWAgaXMgbm90IGdpdmVuLCBjYW5jZWwgYWxsIHRoZSByZXF1ZXN0XG4gICAqL1xuICB0aGlzLmNhbmNlbCA9IGZ1bmN0aW9uKG1lc3NhZ2UpXG4gIHtcbiAgICBpZihtZXNzYWdlKSByZXR1cm4gY2FuY2VsKG1lc3NhZ2UpO1xuXG4gICAgZm9yKHZhciBtZXNzYWdlIGluIG1lc3NhZ2UyS2V5KVxuICAgICAgY2FuY2VsKG1lc3NhZ2UpO1xuICB9O1xuXG5cbiAgdGhpcy5jbG9zZSA9IGZ1bmN0aW9uKClcbiAge1xuICAgIC8vIFByZXZlbnQgdG8gcmVjZWl2ZSBuZXcgbWVzc2FnZXNcbiAgICB2YXIgdHJhbnNwb3J0ID0gdGhpcy5nZXRUcmFuc3BvcnQoKTtcbiAgICBpZih0cmFuc3BvcnQgJiYgdHJhbnNwb3J0LmNsb3NlKVxuICAgICAgIHRyYW5zcG9ydC5jbG9zZSgpO1xuXG4gICAgLy8gUmVxdWVzdCAmIHByb2Nlc3NlZCByZXNwb25zZXNcbiAgICB0aGlzLmNhbmNlbCgpO1xuXG4gICAgcHJvY2Vzc2VkUmVzcG9uc2VzLmZvckVhY2goY2xlYXJUaW1lb3V0KTtcblxuICAgIC8vIFJlc3BvbnNlc1xuICAgIHJlc3BvbnNlcy5mb3JFYWNoKGZ1bmN0aW9uKHJlc3BvbnNlKVxuICAgIHtcbiAgICAgIGNsZWFyVGltZW91dChyZXNwb25zZS50aW1lb3V0KTtcbiAgICB9KTtcbiAgfTtcblxuXG4gIC8qKlxuICAgKiBHZW5lcmF0ZXMgYW5kIGVuY29kZSBhIEpzb25SUEMgMi4wIG1lc3NhZ2VcbiAgICpcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1ldGhvZCAtbWV0aG9kIG9mIHRoZSBub3RpZmljYXRpb25cbiAgICogQHBhcmFtIHBhcmFtcyAtIHBhcmFtZXRlcnMgb2YgdGhlIG5vdGlmaWNhdGlvblxuICAgKiBAcGFyYW0gW2Rlc3RdIC0gZGVzdGluYXRpb24gb2YgdGhlIG5vdGlmaWNhdGlvblxuICAgKiBAcGFyYW0ge29iamVjdH0gW3RyYW5zcG9ydF0gLSB0cmFuc3BvcnQgd2hlcmUgdG8gc2VuZCB0aGUgbWVzc2FnZVxuICAgKiBAcGFyYW0gW2NhbGxiYWNrXSAtIGZ1bmN0aW9uIGNhbGxlZCB3aGVuIGEgcmVzcG9uc2UgdG8gdGhpcyByZXF1ZXN0IGlzXG4gICAqICAgcmVjZWl2ZWQuIElmIG5vdCBkZWZpbmVkLCBhIG5vdGlmaWNhdGlvbiB3aWxsIGJlIHNlbmQgaW5zdGVhZFxuICAgKlxuICAgKiBAcmV0dXJucyB7c3RyaW5nfSBBIHJhdyBKc29uUlBDIDIuMCByZXF1ZXN0IG9yIG5vdGlmaWNhdGlvbiBzdHJpbmdcbiAgICovXG4gIHRoaXMuZW5jb2RlID0gZnVuY3Rpb24obWV0aG9kLCBwYXJhbXMsIGRlc3QsIHRyYW5zcG9ydCwgY2FsbGJhY2spXG4gIHtcbiAgICAvLyBGaXggb3B0aW9uYWwgcGFyYW1ldGVyc1xuICAgIGlmKHBhcmFtcyBpbnN0YW5jZW9mIEZ1bmN0aW9uKVxuICAgIHtcbiAgICAgIGlmKGRlc3QgIT0gdW5kZWZpbmVkKVxuICAgICAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoXCJUaGVyZSBjYW4ndCBiZSBwYXJhbWV0ZXJzIGFmdGVyIGNhbGxiYWNrXCIpO1xuXG4gICAgICBjYWxsYmFjayAgPSBwYXJhbXM7XG4gICAgICB0cmFuc3BvcnQgPSB1bmRlZmluZWQ7XG4gICAgICBkZXN0ICAgICAgPSB1bmRlZmluZWQ7XG4gICAgICBwYXJhbXMgICAgPSB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgZWxzZSBpZihkZXN0IGluc3RhbmNlb2YgRnVuY3Rpb24pXG4gICAge1xuICAgICAgaWYodHJhbnNwb3J0ICE9IHVuZGVmaW5lZClcbiAgICAgICAgdGhyb3cgbmV3IFN5bnRheEVycm9yKFwiVGhlcmUgY2FuJ3QgYmUgcGFyYW1ldGVycyBhZnRlciBjYWxsYmFja1wiKTtcblxuICAgICAgY2FsbGJhY2sgID0gZGVzdDtcbiAgICAgIHRyYW5zcG9ydCA9IHVuZGVmaW5lZDtcbiAgICAgIGRlc3QgICAgICA9IHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICBlbHNlIGlmKHRyYW5zcG9ydCBpbnN0YW5jZW9mIEZ1bmN0aW9uKVxuICAgIHtcbiAgICAgIGlmKGNhbGxiYWNrICE9IHVuZGVmaW5lZClcbiAgICAgICAgdGhyb3cgbmV3IFN5bnRheEVycm9yKFwiVGhlcmUgY2FuJ3QgYmUgcGFyYW1ldGVycyBhZnRlciBjYWxsYmFja1wiKTtcblxuICAgICAgY2FsbGJhY2sgID0gdHJhbnNwb3J0O1xuICAgICAgdHJhbnNwb3J0ID0gdW5kZWZpbmVkO1xuICAgIH07XG5cbiAgICBpZihzZWxmLnBlZXJJRCAhPSB1bmRlZmluZWQpXG4gICAge1xuICAgICAgcGFyYW1zID0gcGFyYW1zIHx8IHt9O1xuXG4gICAgICBwYXJhbXMuZnJvbSA9IHNlbGYucGVlcklEO1xuICAgIH07XG5cbiAgICBpZihkZXN0ICE9IHVuZGVmaW5lZClcbiAgICB7XG4gICAgICBwYXJhbXMgPSBwYXJhbXMgfHwge307XG5cbiAgICAgIHBhcmFtcy5kZXN0ID0gZGVzdDtcbiAgICB9O1xuXG4gICAgLy8gRW5jb2RlIG1lc3NhZ2VcbiAgICB2YXIgbWVzc2FnZSA9XG4gICAge1xuICAgICAgbWV0aG9kOiBtZXRob2QsXG4gICAgICBwYXJhbXM6IHBhcmFtc1xuICAgIH07XG5cbiAgICBpZihjYWxsYmFjaylcbiAgICB7XG4gICAgICB2YXIgaWQgPSByZXF1ZXN0SUQrKztcbiAgICAgIHZhciByZXRyaWVkID0gMDtcblxuICAgICAgbWVzc2FnZSA9IHBhY2tlci5wYWNrKG1lc3NhZ2UsIGlkKTtcblxuICAgICAgZnVuY3Rpb24gZGlzcGF0Y2hDYWxsYmFjayhlcnJvciwgcmVzdWx0KVxuICAgICAge1xuICAgICAgICBzZWxmLmNhbmNlbChtZXNzYWdlKTtcblxuICAgICAgICBjYWxsYmFjayhlcnJvciwgcmVzdWx0KTtcbiAgICAgIH07XG5cbiAgICAgIHZhciByZXF1ZXN0ID1cbiAgICAgIHtcbiAgICAgICAgbWVzc2FnZTogICAgICAgICBtZXNzYWdlLFxuICAgICAgICBjYWxsYmFjazogICAgICAgIGRpc3BhdGNoQ2FsbGJhY2ssXG4gICAgICAgIHJlc3BvbnNlTWV0aG9kczogcmVzcG9uc2VNZXRob2RzW21ldGhvZF0gfHwge31cbiAgICAgIH07XG5cbiAgICAgIHZhciBlbmNvZGVfdHJhbnNwb3J0ID0gdW5pZnlUcmFuc3BvcnQodHJhbnNwb3J0KTtcblxuICAgICAgZnVuY3Rpb24gc2VuZFJlcXVlc3QodHJhbnNwb3J0KVxuICAgICAge1xuICAgICAgICB2YXIgcnQgPSAobWV0aG9kID09PSAncGluZycgPyBwaW5nX3JlcXVlc3RfdGltZW91dCA6IHJlcXVlc3RfdGltZW91dCk7XG4gICAgICAgIHJlcXVlc3QudGltZW91dCA9IHNldFRpbWVvdXQodGltZW91dCwgcnQqTWF0aC5wb3coMiwgcmV0cmllZCsrKSk7XG4gICAgICAgIG1lc3NhZ2UyS2V5W21lc3NhZ2VdID0ge2lkOiBpZCwgZGVzdDogZGVzdH07XG4gICAgICAgIHJlcXVlc3RzLnNldChyZXF1ZXN0LCBpZCwgZGVzdCk7XG5cbiAgICAgICAgdHJhbnNwb3J0ID0gdHJhbnNwb3J0IHx8IGVuY29kZV90cmFuc3BvcnQgfHwgc2VsZi5nZXRUcmFuc3BvcnQoKTtcbiAgICAgICAgaWYodHJhbnNwb3J0KVxuICAgICAgICAgIHJldHVybiB0cmFuc3BvcnQuc2VuZChtZXNzYWdlKTtcblxuICAgICAgICByZXR1cm4gbWVzc2FnZTtcbiAgICAgIH07XG5cbiAgICAgIGZ1bmN0aW9uIHJldHJ5KHRyYW5zcG9ydClcbiAgICAgIHtcbiAgICAgICAgdHJhbnNwb3J0ID0gdW5pZnlUcmFuc3BvcnQodHJhbnNwb3J0KTtcblxuICAgICAgICBjb25zb2xlLndhcm4ocmV0cmllZCsnIHJldHJ5IGZvciByZXF1ZXN0IG1lc3NhZ2U6JyxtZXNzYWdlKTtcblxuICAgICAgICB2YXIgdGltZW91dCA9IHByb2Nlc3NlZFJlc3BvbnNlcy5wb3AoaWQsIGRlc3QpO1xuICAgICAgICBjbGVhclRpbWVvdXQodGltZW91dCk7XG5cbiAgICAgICAgcmV0dXJuIHNlbmRSZXF1ZXN0KHRyYW5zcG9ydCk7XG4gICAgICB9O1xuXG4gICAgICBmdW5jdGlvbiB0aW1lb3V0KClcbiAgICAgIHtcbiAgICAgICAgaWYocmV0cmllZCA8IG1heF9yZXRyaWVzKVxuICAgICAgICAgIHJldHVybiByZXRyeSh0cmFuc3BvcnQpO1xuXG4gICAgICAgIHZhciBlcnJvciA9IG5ldyBFcnJvcignUmVxdWVzdCBoYXMgdGltZWQgb3V0Jyk7XG4gICAgICAgICAgICBlcnJvci5yZXF1ZXN0ID0gbWVzc2FnZTtcblxuICAgICAgICBlcnJvci5yZXRyeSA9IHJldHJ5O1xuXG4gICAgICAgIGRpc3BhdGNoQ2FsbGJhY2soZXJyb3IpXG4gICAgICB9O1xuXG4gICAgICByZXR1cm4gc2VuZFJlcXVlc3QodHJhbnNwb3J0KTtcbiAgICB9O1xuXG4gICAgLy8gUmV0dXJuIHRoZSBwYWNrZWQgbWVzc2FnZVxuICAgIG1lc3NhZ2UgPSBwYWNrZXIucGFjayhtZXNzYWdlKTtcblxuICAgIHRyYW5zcG9ydCA9IHRyYW5zcG9ydCB8fCB0aGlzLmdldFRyYW5zcG9ydCgpO1xuICAgIGlmKHRyYW5zcG9ydClcbiAgICAgIHJldHVybiB0cmFuc3BvcnQuc2VuZChtZXNzYWdlKTtcblxuICAgIHJldHVybiBtZXNzYWdlO1xuICB9O1xuXG4gIC8qKlxuICAgKiBEZWNvZGUgYW5kIHByb2Nlc3MgYSBKc29uUlBDIDIuMCBtZXNzYWdlXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBtZXNzYWdlIC0gc3RyaW5nIHdpdGggdGhlIGNvbnRlbnQgb2YgdGhlIG1lc3NhZ2VcbiAgICpcbiAgICogQHJldHVybnMge1JwY05vdGlmaWNhdGlvbnxScGNSZXF1ZXN0fHVuZGVmaW5lZH0gLSB0aGUgcmVwcmVzZW50YXRpb24gb2YgdGhlXG4gICAqICAgbm90aWZpY2F0aW9uIG9yIHRoZSByZXF1ZXN0LiBJZiBhIHJlc3BvbnNlIHdhcyBwcm9jZXNzZWQsIGl0IHdpbGwgcmV0dXJuXG4gICAqICAgYHVuZGVmaW5lZGAgdG8gbm90aWZ5IHRoYXQgaXQgd2FzIHByb2Nlc3NlZFxuICAgKlxuICAgKiBAdGhyb3dzIHtUeXBlRXJyb3J9IC0gTWVzc2FnZSBpcyBub3QgZGVmaW5lZFxuICAgKi9cbiAgdGhpcy5kZWNvZGUgPSBmdW5jdGlvbihtZXNzYWdlLCB0cmFuc3BvcnQpXG4gIHtcbiAgICBpZighbWVzc2FnZSlcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJNZXNzYWdlIGlzIG5vdCBkZWZpbmVkXCIpO1xuXG4gICAgdHJ5XG4gICAge1xuICAgICAgbWVzc2FnZSA9IHBhY2tlci51bnBhY2sobWVzc2FnZSk7XG4gICAgfVxuICAgIGNhdGNoKGUpXG4gICAge1xuICAgICAgLy8gSWdub3JlIGludmFsaWQgbWVzc2FnZXNcbiAgICAgIHJldHVybiBjb25zb2xlLmRlYnVnKGUsIG1lc3NhZ2UpO1xuICAgIH07XG5cbiAgICB2YXIgaWQgICAgID0gbWVzc2FnZS5pZDtcbiAgICB2YXIgYWNrICAgID0gbWVzc2FnZS5hY2s7XG4gICAgdmFyIG1ldGhvZCA9IG1lc3NhZ2UubWV0aG9kO1xuICAgIHZhciBwYXJhbXMgPSBtZXNzYWdlLnBhcmFtcyB8fCB7fTtcblxuICAgIHZhciBmcm9tID0gcGFyYW1zLmZyb207XG4gICAgdmFyIGRlc3QgPSBwYXJhbXMuZGVzdDtcblxuICAgIC8vIElnbm9yZSBtZXNzYWdlcyBzZW5kIGJ5IHVzXG4gICAgaWYoc2VsZi5wZWVySUQgIT0gdW5kZWZpbmVkICYmIGZyb20gPT0gc2VsZi5wZWVySUQpIHJldHVybjtcblxuICAgIC8vIE5vdGlmaWNhdGlvblxuICAgIGlmKGlkID09IHVuZGVmaW5lZCAmJiBhY2sgPT0gdW5kZWZpbmVkKVxuICAgIHtcbiAgICAgIHZhciBub3RpZmljYXRpb24gPSBuZXcgUnBjTm90aWZpY2F0aW9uKG1ldGhvZCwgcGFyYW1zKTtcblxuICAgICAgaWYoc2VsZi5lbWl0KCdyZXF1ZXN0Jywgbm90aWZpY2F0aW9uKSkgcmV0dXJuO1xuICAgICAgcmV0dXJuIG5vdGlmaWNhdGlvbjtcbiAgICB9O1xuXG5cbiAgICBmdW5jdGlvbiBwcm9jZXNzUmVxdWVzdCgpXG4gICAge1xuICAgICAgLy8gSWYgd2UgaGF2ZSBhIHRyYW5zcG9ydCBhbmQgaXQncyBhIGR1cGxpY2F0ZWQgcmVxdWVzdCwgcmVwbHkgaW5tZWRpYXRseVxuICAgICAgdHJhbnNwb3J0ID0gdW5pZnlUcmFuc3BvcnQodHJhbnNwb3J0KSB8fCBzZWxmLmdldFRyYW5zcG9ydCgpO1xuICAgICAgaWYodHJhbnNwb3J0KVxuICAgICAge1xuICAgICAgICB2YXIgcmVzcG9uc2UgPSByZXNwb25zZXMuZ2V0KGlkLCBmcm9tKTtcbiAgICAgICAgaWYocmVzcG9uc2UpXG4gICAgICAgICAgcmV0dXJuIHRyYW5zcG9ydC5zZW5kKHJlc3BvbnNlLm1lc3NhZ2UpO1xuICAgICAgfTtcblxuICAgICAgdmFyIGlkQWNrID0gKGlkICE9IHVuZGVmaW5lZCkgPyBpZCA6IGFjaztcbiAgICAgIHZhciByZXF1ZXN0ID0gbmV3IFJwY1JlcXVlc3QobWV0aG9kLCBwYXJhbXMsIGlkQWNrLCBmcm9tLCB0cmFuc3BvcnQpO1xuXG4gICAgICBpZihzZWxmLmVtaXQoJ3JlcXVlc3QnLCByZXF1ZXN0KSkgcmV0dXJuO1xuICAgICAgcmV0dXJuIHJlcXVlc3Q7XG4gICAgfTtcblxuICAgIGZ1bmN0aW9uIHByb2Nlc3NSZXNwb25zZShyZXF1ZXN0LCBlcnJvciwgcmVzdWx0KVxuICAgIHtcbiAgICAgIHJlcXVlc3QuY2FsbGJhY2soZXJyb3IsIHJlc3VsdCk7XG4gICAgfTtcblxuICAgIGZ1bmN0aW9uIGR1cGxpY2F0ZWRSZXNwb25zZSh0aW1lb3V0KVxuICAgIHtcbiAgICAgIGNvbnNvbGUud2FybihcIlJlc3BvbnNlIGFscmVhZHkgcHJvY2Vzc2VkXCIsIG1lc3NhZ2UpO1xuXG4gICAgICAvLyBVcGRhdGUgZHVwbGljYXRlZCByZXNwb25zZXMgdGltZW91dFxuICAgICAgY2xlYXJUaW1lb3V0KHRpbWVvdXQpO1xuICAgICAgc3RvcmVQcm9jZXNzZWRSZXNwb25zZShhY2ssIGZyb20pO1xuICAgIH07XG5cblxuICAgIC8vIFJlcXVlc3QsIG9yIHJlc3BvbnNlIHdpdGggb3duIG1ldGhvZFxuICAgIGlmKG1ldGhvZClcbiAgICB7XG4gICAgICAvLyBDaGVjayBpZiBpdCdzIGEgcmVzcG9uc2Ugd2l0aCBvd24gbWV0aG9kXG4gICAgICBpZihkZXN0ID09IHVuZGVmaW5lZCB8fCBkZXN0ID09IHNlbGYucGVlcklEKVxuICAgICAge1xuICAgICAgICB2YXIgcmVxdWVzdCA9IHJlcXVlc3RzLmdldChhY2ssIGZyb20pO1xuICAgICAgICBpZihyZXF1ZXN0KVxuICAgICAgICB7XG4gICAgICAgICAgdmFyIHJlc3BvbnNlTWV0aG9kcyA9IHJlcXVlc3QucmVzcG9uc2VNZXRob2RzO1xuXG4gICAgICAgICAgaWYobWV0aG9kID09IHJlc3BvbnNlTWV0aG9kcy5lcnJvcilcbiAgICAgICAgICAgIHJldHVybiBwcm9jZXNzUmVzcG9uc2UocmVxdWVzdCwgcGFyYW1zKTtcblxuICAgICAgICAgIGlmKG1ldGhvZCA9PSByZXNwb25zZU1ldGhvZHMucmVzcG9uc2UpXG4gICAgICAgICAgICByZXR1cm4gcHJvY2Vzc1Jlc3BvbnNlKHJlcXVlc3QsIG51bGwsIHBhcmFtcyk7XG5cbiAgICAgICAgICByZXR1cm4gcHJvY2Vzc1JlcXVlc3QoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBwcm9jZXNzZWQgPSBwcm9jZXNzZWRSZXNwb25zZXMuZ2V0KGFjaywgZnJvbSk7XG4gICAgICAgIGlmKHByb2Nlc3NlZClcbiAgICAgICAgICByZXR1cm4gZHVwbGljYXRlZFJlc3BvbnNlKHByb2Nlc3NlZCk7XG4gICAgICB9XG5cbiAgICAgIC8vIFJlcXVlc3RcbiAgICAgIHJldHVybiBwcm9jZXNzUmVxdWVzdCgpO1xuICAgIH07XG5cbiAgICB2YXIgZXJyb3IgID0gbWVzc2FnZS5lcnJvcjtcbiAgICB2YXIgcmVzdWx0ID0gbWVzc2FnZS5yZXN1bHQ7XG5cbiAgICAvLyBJZ25vcmUgcmVzcG9uc2VzIG5vdCBzZW5kIHRvIHVzXG4gICAgaWYoZXJyb3IgICYmIGVycm9yLmRlc3QgICYmIGVycm9yLmRlc3QgICE9IHNlbGYucGVlcklEKSByZXR1cm47XG4gICAgaWYocmVzdWx0ICYmIHJlc3VsdC5kZXN0ICYmIHJlc3VsdC5kZXN0ICE9IHNlbGYucGVlcklEKSByZXR1cm47XG5cbiAgICAvLyBSZXNwb25zZVxuICAgIHZhciByZXF1ZXN0ID0gcmVxdWVzdHMuZ2V0KGFjaywgZnJvbSk7XG4gICAgaWYoIXJlcXVlc3QpXG4gICAge1xuICAgICAgdmFyIHByb2Nlc3NlZCA9IHByb2Nlc3NlZFJlc3BvbnNlcy5nZXQoYWNrLCBmcm9tKTtcbiAgICAgIGlmKHByb2Nlc3NlZClcbiAgICAgICAgcmV0dXJuIGR1cGxpY2F0ZWRSZXNwb25zZShwcm9jZXNzZWQpO1xuXG4gICAgICByZXR1cm4gY29uc29sZS53YXJuKFwiTm8gY2FsbGJhY2sgd2FzIGRlZmluZWQgZm9yIHRoaXMgbWVzc2FnZVwiLCBtZXNzYWdlKTtcbiAgICB9O1xuXG4gICAgLy8gUHJvY2VzcyByZXNwb25zZVxuICAgIHByb2Nlc3NSZXNwb25zZShyZXF1ZXN0LCBlcnJvciwgcmVzdWx0KTtcbiAgfTtcbn07XG5pbmhlcml0cyhScGNCdWlsZGVyLCBFdmVudEVtaXR0ZXIpO1xuXG5cblJwY0J1aWxkZXIuUnBjTm90aWZpY2F0aW9uID0gUnBjTm90aWZpY2F0aW9uO1xuXG5cbm1vZHVsZS5leHBvcnRzID0gUnBjQnVpbGRlcjtcblxudmFyIGNsaWVudHMgPSByZXF1aXJlKCcuL2NsaWVudHMnKTtcbnZhciB0cmFuc3BvcnRzID0gcmVxdWlyZSgnLi9jbGllbnRzL3RyYW5zcG9ydHMnKTtcblxuUnBjQnVpbGRlci5jbGllbnRzID0gY2xpZW50cztcblJwY0J1aWxkZXIuY2xpZW50cy50cmFuc3BvcnRzID0gdHJhbnNwb3J0cztcblJwY0J1aWxkZXIucGFja2VycyA9IHBhY2tlcnM7XG4iLCIvKipcbiAqIEpzb25SUEMgMi4wIHBhY2tlclxuICovXG5cbi8qKlxuICogUGFjayBhIEpzb25SUEMgMi4wIG1lc3NhZ2VcbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gbWVzc2FnZSAtIG9iamVjdCB0byBiZSBwYWNrYWdlZC4gSXQgcmVxdWlyZXMgdG8gaGF2ZSBhbGwgdGhlXG4gKiAgIGZpZWxkcyBuZWVkZWQgYnkgdGhlIEpzb25SUEMgMi4wIG1lc3NhZ2UgdGhhdCBpdCdzIGdvaW5nIHRvIGJlIGdlbmVyYXRlZFxuICpcbiAqIEByZXR1cm4ge1N0cmluZ30gLSB0aGUgc3RyaW5naWZpZWQgSnNvblJQQyAyLjAgbWVzc2FnZVxuICovXG5mdW5jdGlvbiBwYWNrKG1lc3NhZ2UsIGlkKVxue1xuICB2YXIgcmVzdWx0ID1cbiAge1xuICAgIGpzb25ycGM6IFwiMi4wXCJcbiAgfTtcblxuICAvLyBSZXF1ZXN0XG4gIGlmKG1lc3NhZ2UubWV0aG9kKVxuICB7XG4gICAgcmVzdWx0Lm1ldGhvZCA9IG1lc3NhZ2UubWV0aG9kO1xuXG4gICAgaWYobWVzc2FnZS5wYXJhbXMpXG4gICAgICByZXN1bHQucGFyYW1zID0gbWVzc2FnZS5wYXJhbXM7XG5cbiAgICAvLyBSZXF1ZXN0IGlzIGEgbm90aWZpY2F0aW9uXG4gICAgaWYoaWQgIT0gdW5kZWZpbmVkKVxuICAgICAgcmVzdWx0LmlkID0gaWQ7XG4gIH1cblxuICAvLyBSZXNwb25zZVxuICBlbHNlIGlmKGlkICE9IHVuZGVmaW5lZClcbiAge1xuICAgIGlmKG1lc3NhZ2UuZXJyb3IpXG4gICAge1xuICAgICAgaWYobWVzc2FnZS5yZXN1bHQgIT09IHVuZGVmaW5lZClcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkJvdGggcmVzdWx0IGFuZCBlcnJvciBhcmUgZGVmaW5lZFwiKTtcblxuICAgICAgcmVzdWx0LmVycm9yID0gbWVzc2FnZS5lcnJvcjtcbiAgICB9XG4gICAgZWxzZSBpZihtZXNzYWdlLnJlc3VsdCAhPT0gdW5kZWZpbmVkKVxuICAgICAgcmVzdWx0LnJlc3VsdCA9IG1lc3NhZ2UucmVzdWx0O1xuICAgIGVsc2VcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJObyByZXN1bHQgb3IgZXJyb3IgaXMgZGVmaW5lZFwiKTtcblxuICAgIHJlc3VsdC5pZCA9IGlkO1xuICB9O1xuXG4gIHJldHVybiBKU09OLnN0cmluZ2lmeShyZXN1bHQpO1xufTtcblxuLyoqXG4gKiBVbnBhY2sgYSBKc29uUlBDIDIuMCBtZXNzYWdlXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2UgLSBzdHJpbmcgd2l0aCB0aGUgY29udGVudCBvZiB0aGUgSnNvblJQQyAyLjAgbWVzc2FnZVxuICpcbiAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gLSBJbnZhbGlkIEpzb25SUEMgdmVyc2lvblxuICpcbiAqIEByZXR1cm4ge09iamVjdH0gLSBvYmplY3QgZmlsbGVkIHdpdGggdGhlIEpzb25SUEMgMi4wIG1lc3NhZ2UgY29udGVudFxuICovXG5mdW5jdGlvbiB1bnBhY2sobWVzc2FnZSlcbntcbiAgdmFyIHJlc3VsdCA9IG1lc3NhZ2U7XG5cbiAgaWYodHlwZW9mIG1lc3NhZ2UgPT09ICdzdHJpbmcnIHx8IG1lc3NhZ2UgaW5zdGFuY2VvZiBTdHJpbmcpIHtcbiAgICByZXN1bHQgPSBKU09OLnBhcnNlKG1lc3NhZ2UpO1xuICB9XG5cbiAgLy8gQ2hlY2sgaWYgaXQncyBhIHZhbGlkIG1lc3NhZ2VcblxuICB2YXIgdmVyc2lvbiA9IHJlc3VsdC5qc29ucnBjO1xuICBpZih2ZXJzaW9uICE9PSAnMi4wJylcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiSW52YWxpZCBKc29uUlBDIHZlcnNpb24gJ1wiICsgdmVyc2lvbiArIFwiJzogXCIgKyBtZXNzYWdlKTtcblxuICAvLyBSZXNwb25zZVxuICBpZihyZXN1bHQubWV0aG9kID09IHVuZGVmaW5lZClcbiAge1xuICAgIGlmKHJlc3VsdC5pZCA9PSB1bmRlZmluZWQpXG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiSW52YWxpZCBtZXNzYWdlOiBcIittZXNzYWdlKTtcblxuICAgIHZhciByZXN1bHRfZGVmaW5lZCA9IHJlc3VsdC5yZXN1bHQgIT09IHVuZGVmaW5lZDtcbiAgICB2YXIgZXJyb3JfZGVmaW5lZCAgPSByZXN1bHQuZXJyb3IgICE9PSB1bmRlZmluZWQ7XG5cbiAgICAvLyBDaGVjayBvbmx5IHJlc3VsdCBvciBlcnJvciBpcyBkZWZpbmVkLCBub3QgYm90aCBvciBub25lXG4gICAgaWYocmVzdWx0X2RlZmluZWQgJiYgZXJyb3JfZGVmaW5lZClcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJCb3RoIHJlc3VsdCBhbmQgZXJyb3IgYXJlIGRlZmluZWQ6IFwiK21lc3NhZ2UpO1xuXG4gICAgaWYoIXJlc3VsdF9kZWZpbmVkICYmICFlcnJvcl9kZWZpbmVkKVxuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIk5vIHJlc3VsdCBvciBlcnJvciBpcyBkZWZpbmVkOiBcIittZXNzYWdlKTtcblxuICAgIHJlc3VsdC5hY2sgPSByZXN1bHQuaWQ7XG4gICAgZGVsZXRlIHJlc3VsdC5pZDtcbiAgfVxuXG4gIC8vIFJldHVybiB1bnBhY2tlZCBtZXNzYWdlXG4gIHJldHVybiByZXN1bHQ7XG59O1xuXG5cbmV4cG9ydHMucGFjayAgID0gcGFjaztcbmV4cG9ydHMudW5wYWNrID0gdW5wYWNrO1xuIiwiZnVuY3Rpb24gcGFjayhtZXNzYWdlKVxue1xuICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiTm90IHlldCBpbXBsZW1lbnRlZFwiKTtcbn07XG5cbmZ1bmN0aW9uIHVucGFjayhtZXNzYWdlKVxue1xuICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiTm90IHlldCBpbXBsZW1lbnRlZFwiKTtcbn07XG5cblxuZXhwb3J0cy5wYWNrICAgPSBwYWNrO1xuZXhwb3J0cy51bnBhY2sgPSB1bnBhY2s7XG4iLCJ2YXIgSnNvblJQQyA9IHJlcXVpcmUoJy4vSnNvblJQQycpO1xudmFyIFhtbFJQQyAgPSByZXF1aXJlKCcuL1htbFJQQycpO1xuXG5cbmV4cG9ydHMuSnNvblJQQyA9IEpzb25SUEM7XG5leHBvcnRzLlhtbFJQQyAgPSBYbWxSUEM7XG4iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE0LTIwMTUgS3VyZW50byAoaHR0cDovL2t1cmVudG8ub3JnLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICovXG5cbnZhciBmcmVlaWNlID0gcmVxdWlyZSgnZnJlZWljZScpXG52YXIgaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpXG52YXIgVUFQYXJzZXIgPSByZXF1aXJlKCd1YS1wYXJzZXItanMnKVxudmFyIHV1aWQgPSByZXF1aXJlKCd1dWlkJylcbnZhciBoYXJrID0gcmVxdWlyZSgnaGFyaycpXG5cbnZhciBFdmVudEVtaXR0ZXIgPSByZXF1aXJlKCdldmVudHMnKS5FdmVudEVtaXR0ZXJcbnZhciByZWN1cnNpdmUgPSByZXF1aXJlKCdtZXJnZScpLnJlY3Vyc2l2ZS5iaW5kKHVuZGVmaW5lZCwgdHJ1ZSlcbnZhciBzZHBUcmFuc2xhdG9yID0gcmVxdWlyZSgnc2RwLXRyYW5zbGF0b3InKVxudmFyIGxvZ2dlciA9IHdpbmRvdy5Mb2dnZXIgfHwgY29uc29sZVxuXG4vLyB2YXIgZ1VNID0gbmF2aWdhdG9yLm1lZGlhRGV2aWNlcy5nZXRVc2VyTWVkaWEgfHwgZnVuY3Rpb24gKGNvbnN0cmFpbnRzKSB7XG4vLyAgIHJldHVybiBuZXcgUHJvbWlzZShuYXZpZ2F0b3IuZ2V0VXNlck1lZGlhKGNvbnN0cmFpbnRzLCBmdW5jdGlvbiAoc3RyZWFtKSB7XG4vLyAgICAgdmlkZW9TdHJlYW0gPSBzdHJlYW1cbi8vICAgICBzdGFydCgpXG4vLyAgIH0pLmVyb3IoY2FsbGJhY2spKTtcbi8vIH1cblxuLyp0cnkge1xuICByZXF1aXJlKCdrdXJlbnRvLWJyb3dzZXItZXh0ZW5zaW9ucycpXG59IGNhdGNoIChlcnJvcikge1xuICBpZiAodHlwZW9mIGdldFNjcmVlbkNvbnN0cmFpbnRzID09PSAndW5kZWZpbmVkJykge1xuICAgIGxvZ2dlci53YXJuKCdzY3JlZW4gc2hhcmluZyBpcyBub3QgYXZhaWxhYmxlJylcblxuICAgIGdldFNjcmVlbkNvbnN0cmFpbnRzID0gZnVuY3Rpb24gZ2V0U2NyZWVuQ29uc3RyYWludHMoc2VuZFNvdXJjZSwgY2FsbGJhY2spIHtcbiAgICAgIGNhbGxiYWNrKG5ldyBFcnJvcihcIlRoaXMgbGlicmFyeSBpcyBub3QgZW5hYmxlZCBmb3Igc2NyZWVuIHNoYXJpbmdcIikpXG4gICAgfVxuICB9XG59Ki9cblxudmFyIE1FRElBX0NPTlNUUkFJTlRTID0ge1xuICBhdWRpbzogdHJ1ZSxcbiAgdmlkZW86IHtcbiAgICB3aWR0aDogNjQwLFxuICAgIGZyYW1lcmF0ZTogMTVcbiAgfVxufVxuXG4vLyBTb21laG93LCB0aGUgVUFQYXJzZXIgY29uc3RydWN0b3IgZ2V0cyBhbiBlbXB0eSB3aW5kb3cgb2JqZWN0LlxuLy8gV2UgbmVlZCB0byBwYXNzIHRoZSB1c2VyIGFnZW50IHN0cmluZyBpbiBvcmRlciB0byBnZXQgaW5mb3JtYXRpb25cbnZhciB1YSA9ICh3aW5kb3cgJiYgd2luZG93Lm5hdmlnYXRvcikgPyB3aW5kb3cubmF2aWdhdG9yLnVzZXJBZ2VudCA6ICcnXG52YXIgcGFyc2VyID0gbmV3IFVBUGFyc2VyKHVhKVxudmFyIGJyb3dzZXIgPSBwYXJzZXIuZ2V0QnJvd3NlcigpXG5cbnZhciB1c2VQbGFuQiA9IGZhbHNlXG5pZiAoYnJvd3Nlci5uYW1lID09PSAnQ2hyb21lJyB8fCBicm93c2VyLm5hbWUgPT09ICdDaHJvbWl1bScpIHtcbiAgbG9nZ2VyLmRlYnVnKGJyb3dzZXIubmFtZSArIFwiOiB1c2luZyBTRFAgUGxhbkJcIilcbiAgdXNlUGxhbkIgPSB0cnVlXG59XG5cbmZ1bmN0aW9uIG5vb3AoZXJyb3IpIHtcbiAgaWYgKGVycm9yKSBsb2dnZXIuZXJyb3IoZXJyb3IpXG59XG5cbmZ1bmN0aW9uIHRyYWNrU3RvcCh0cmFjaykge1xuICB0cmFjay5zdG9wICYmIHRyYWNrLnN0b3AoKVxufVxuXG5mdW5jdGlvbiBzdHJlYW1TdG9wKHN0cmVhbSkge1xuICBzdHJlYW0uZ2V0VHJhY2tzKCkuZm9yRWFjaCh0cmFja1N0b3ApXG59XG5cbi8qKlxuICogUmV0dXJucyBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiBhIFNlc3Npb25EZXNjcmlwdGlvbiBvYmplY3QuXG4gKi9cbnZhciBkdW1wU0RQID0gZnVuY3Rpb24gKGRlc2NyaXB0aW9uKSB7XG4gIGlmICh0eXBlb2YgZGVzY3JpcHRpb24gPT09ICd1bmRlZmluZWQnIHx8IGRlc2NyaXB0aW9uID09PSBudWxsKSB7XG4gICAgcmV0dXJuICcnXG4gIH1cblxuICByZXR1cm4gJ3R5cGU6ICcgKyBkZXNjcmlwdGlvbi50eXBlICsgJ1xcclxcbicgKyBkZXNjcmlwdGlvbi5zZHBcbn1cblxuZnVuY3Rpb24gYnVmZmVyaXplQ2FuZGlkYXRlcyhwYywgb25lcnJvcikge1xuICB2YXIgY2FuZGlkYXRlc1F1ZXVlID0gW11cblxuICBwYy5hZGRFdmVudExpc3RlbmVyKCdzaWduYWxpbmdzdGF0ZWNoYW5nZScsIGZ1bmN0aW9uICgpIHtcbiAgICBpZiAodGhpcy5zaWduYWxpbmdTdGF0ZSA9PT0gJ3N0YWJsZScpIHtcbiAgICAgIHdoaWxlIChjYW5kaWRhdGVzUXVldWUubGVuZ3RoKSB7XG4gICAgICAgIHZhciBlbnRyeSA9IGNhbmRpZGF0ZXNRdWV1ZS5zaGlmdCgpXG5cbiAgICAgICAgdGhpcy5hZGRJY2VDYW5kaWRhdGUoZW50cnkuY2FuZGlkYXRlLCBlbnRyeS5jYWxsYmFjaywgZW50cnkuY2FsbGJhY2spXG4gICAgICB9XG4gICAgfVxuICB9KVxuXG4gIHJldHVybiBmdW5jdGlvbiAoY2FuZGlkYXRlLCBjYWxsYmFjaykge1xuICAgIGNhbGxiYWNrID0gY2FsbGJhY2sgfHwgb25lcnJvclxuXG4gICAgc3dpdGNoIChwYy5zaWduYWxpbmdTdGF0ZSkge1xuICAgIGNhc2UgJ2Nsb3NlZCc6XG4gICAgICBjYWxsYmFjayhuZXcgRXJyb3IoJ1BlZXJDb25uZWN0aW9uIG9iamVjdCBpcyBjbG9zZWQnKSlcbiAgICAgIGJyZWFrXG4gICAgY2FzZSAnc3RhYmxlJzpcbiAgICAgIGlmIChwYy5yZW1vdGVEZXNjcmlwdGlvbikge1xuICAgICAgICBwYy5hZGRJY2VDYW5kaWRhdGUoY2FuZGlkYXRlLCBjYWxsYmFjaywgY2FsbGJhY2spXG4gICAgICAgIGJyZWFrXG4gICAgICB9XG4gICAgZGVmYXVsdDpcbiAgICAgIGNhbmRpZGF0ZXNRdWV1ZS5wdXNoKHtcbiAgICAgICAgY2FuZGlkYXRlOiBjYW5kaWRhdGUsXG4gICAgICAgIGNhbGxiYWNrOiBjYWxsYmFja1xuICAgICAgfSlcbiAgICB9XG4gIH1cbn1cblxuLyogU2ltdWxjYXN0IHV0aWxpdGllcyAqL1xuXG5mdW5jdGlvbiByZW1vdmVGSURGcm9tT2ZmZXIoc2RwKSB7XG4gIHZhciBuID0gc2RwLmluZGV4T2YoXCJhPXNzcmMtZ3JvdXA6RklEXCIpO1xuXG4gIGlmIChuID4gMCkge1xuICAgIHJldHVybiBzZHAuc2xpY2UoMCwgbik7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIHNkcDtcbiAgfVxufVxuXG5mdW5jdGlvbiBnZXRTaW11bGNhc3RJbmZvKHZpZGVvU3RyZWFtKSB7XG4gIHZhciB2aWRlb1RyYWNrcyA9IHZpZGVvU3RyZWFtLmdldFZpZGVvVHJhY2tzKCk7XG4gIGlmICghdmlkZW9UcmFja3MubGVuZ3RoKSB7XG4gICAgbG9nZ2VyLndhcm4oJ05vIHZpZGVvIHRyYWNrcyBhdmFpbGFibGUgaW4gdGhlIHZpZGVvIHN0cmVhbScpXG4gICAgcmV0dXJuICcnXG4gIH1cbiAgdmFyIGxpbmVzID0gW1xuICAgICdhPXgtZ29vZ2xlLWZsYWc6Y29uZmVyZW5jZScsXG4gICAgJ2E9c3NyYy1ncm91cDpTSU0gMSAyIDMnLFxuICAgICdhPXNzcmM6MSBjbmFtZTpsb2NhbFZpZGVvJyxcbiAgICAnYT1zc3JjOjEgbXNpZDonICsgdmlkZW9TdHJlYW0uaWQgKyAnICcgKyB2aWRlb1RyYWNrc1swXS5pZCxcbiAgICAnYT1zc3JjOjEgbXNsYWJlbDonICsgdmlkZW9TdHJlYW0uaWQsXG4gICAgJ2E9c3NyYzoxIGxhYmVsOicgKyB2aWRlb1RyYWNrc1swXS5pZCxcbiAgICAnYT1zc3JjOjIgY25hbWU6bG9jYWxWaWRlbycsXG4gICAgJ2E9c3NyYzoyIG1zaWQ6JyArIHZpZGVvU3RyZWFtLmlkICsgJyAnICsgdmlkZW9UcmFja3NbMF0uaWQsXG4gICAgJ2E9c3NyYzoyIG1zbGFiZWw6JyArIHZpZGVvU3RyZWFtLmlkLFxuICAgICdhPXNzcmM6MiBsYWJlbDonICsgdmlkZW9UcmFja3NbMF0uaWQsXG4gICAgJ2E9c3NyYzozIGNuYW1lOmxvY2FsVmlkZW8nLFxuICAgICdhPXNzcmM6MyBtc2lkOicgKyB2aWRlb1N0cmVhbS5pZCArICcgJyArIHZpZGVvVHJhY2tzWzBdLmlkLFxuICAgICdhPXNzcmM6MyBtc2xhYmVsOicgKyB2aWRlb1N0cmVhbS5pZCxcbiAgICAnYT1zc3JjOjMgbGFiZWw6JyArIHZpZGVvVHJhY2tzWzBdLmlkXG4gIF07XG5cbiAgbGluZXMucHVzaCgnJyk7XG5cbiAgcmV0dXJuIGxpbmVzLmpvaW4oJ1xcbicpO1xufVxuXG4vKipcbiAqIFdyYXBwZXIgb2JqZWN0IG9mIGFuIFJUQ1BlZXJDb25uZWN0aW9uLiBUaGlzIG9iamVjdCBpcyBhaW1lZCB0byBzaW1wbGlmeSB0aGVcbiAqIGRldmVsb3BtZW50IG9mIFdlYlJUQy1iYXNlZCBhcHBsaWNhdGlvbnMuXG4gKlxuICogQGNvbnN0cnVjdG9yIG1vZHVsZTprdXJlbnRvVXRpbHMuV2ViUnRjUGVlclxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBtb2RlIE1vZGUgaW4gd2hpY2ggdGhlIFBlZXJDb25uZWN0aW9uIHdpbGwgYmUgY29uZmlndXJlZC5cbiAqICBWYWxpZCB2YWx1ZXMgYXJlOiAncmVjdicsICdzZW5kJywgYW5kICdzZW5kUmVjdidcbiAqIEBwYXJhbSBsb2NhbFZpZGVvIFZpZGVvIHRhZyBmb3IgdGhlIGxvY2FsIHN0cmVhbVxuICogQHBhcmFtIHJlbW90ZVZpZGVvIFZpZGVvIHRhZyBmb3IgdGhlIHJlbW90ZSBzdHJlYW1cbiAqIEBwYXJhbSB7TWVkaWFTdHJlYW19IHZpZGVvU3RyZWFtIFN0cmVhbSB0byBiZSB1c2VkIGFzIHByaW1hcnkgc291cmNlXG4gKiAgKHR5cGljYWxseSB2aWRlbyBhbmQgYXVkaW8sIG9yIG9ubHkgdmlkZW8gaWYgY29tYmluZWQgd2l0aCBhdWRpb1N0cmVhbSkgZm9yXG4gKiAgbG9jYWxWaWRlbyBhbmQgdG8gYmUgYWRkZWQgYXMgc3RyZWFtIHRvIHRoZSBSVENQZWVyQ29ubmVjdGlvblxuICogQHBhcmFtIHtNZWRpYVN0cmVhbX0gYXVkaW9TdHJlYW0gU3RyZWFtIHRvIGJlIHVzZWQgYXMgc2Vjb25kIHNvdXJjZVxuICogICh0eXBpY2FsbHkgZm9yIGF1ZGlvKSBmb3IgbG9jYWxWaWRlbyBhbmQgdG8gYmUgYWRkZWQgYXMgc3RyZWFtIHRvIHRoZVxuICogIFJUQ1BlZXJDb25uZWN0aW9uXG4gKi9cbmZ1bmN0aW9uIFdlYlJ0Y1BlZXIobW9kZSwgb3B0aW9ucywgY2FsbGJhY2spIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIFdlYlJ0Y1BlZXIpKSB7XG4gICAgcmV0dXJuIG5ldyBXZWJSdGNQZWVyKG1vZGUsIG9wdGlvbnMsIGNhbGxiYWNrKVxuICB9XG5cbiAgV2ViUnRjUGVlci5zdXBlcl8uY2FsbCh0aGlzKVxuXG4gIGlmIChvcHRpb25zIGluc3RhbmNlb2YgRnVuY3Rpb24pIHtcbiAgICBjYWxsYmFjayA9IG9wdGlvbnNcbiAgICBvcHRpb25zID0gdW5kZWZpbmVkXG4gIH1cblxuICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fVxuICBjYWxsYmFjayA9IChjYWxsYmFjayB8fCBub29wKS5iaW5kKHRoaXMpXG5cbiAgdmFyIHNlbGYgPSB0aGlzXG4gIHZhciBsb2NhbFZpZGVvID0gb3B0aW9ucy5sb2NhbFZpZGVvXG4gIHZhciByZW1vdGVWaWRlbyA9IG9wdGlvbnMucmVtb3RlVmlkZW9cbiAgdmFyIHZpZGVvU3RyZWFtID0gb3B0aW9ucy52aWRlb1N0cmVhbVxuICB2YXIgYXVkaW9TdHJlYW0gPSBvcHRpb25zLmF1ZGlvU3RyZWFtXG4gIHZhciBtZWRpYUNvbnN0cmFpbnRzID0gb3B0aW9ucy5tZWRpYUNvbnN0cmFpbnRzXG5cbiAgdmFyIGNvbm5lY3Rpb25Db25zdHJhaW50cyA9IG9wdGlvbnMuY29ubmVjdGlvbkNvbnN0cmFpbnRzXG4gIHZhciBwYyA9IG9wdGlvbnMucGVlckNvbm5lY3Rpb25cbiAgdmFyIHNlbmRTb3VyY2UgPSBvcHRpb25zLnNlbmRTb3VyY2UgfHwgJ3dlYmNhbSdcblxuICB2YXIgZGF0YUNoYW5uZWxDb25maWcgPSBvcHRpb25zLmRhdGFDaGFubmVsQ29uZmlnXG4gIHZhciB1c2VEYXRhQ2hhbm5lbHMgPSBvcHRpb25zLmRhdGFDaGFubmVscyB8fCBmYWxzZVxuICB2YXIgZGF0YUNoYW5uZWxcblxuICB2YXIgZ3VpZCA9IHV1aWQudjQoKVxuICB2YXIgY29uZmlndXJhdGlvbiA9IHJlY3Vyc2l2ZSh7XG4gICAgICBpY2VTZXJ2ZXJzOiBmcmVlaWNlKClcbiAgICB9LFxuICAgIG9wdGlvbnMuY29uZmlndXJhdGlvbilcblxuICB2YXIgb25pY2VjYW5kaWRhdGUgPSBvcHRpb25zLm9uaWNlY2FuZGlkYXRlXG4gIGlmIChvbmljZWNhbmRpZGF0ZSkgdGhpcy5vbignaWNlY2FuZGlkYXRlJywgb25pY2VjYW5kaWRhdGUpXG5cbiAgdmFyIG9uY2FuZGlkYXRlZ2F0aGVyaW5nZG9uZSA9IG9wdGlvbnMub25jYW5kaWRhdGVnYXRoZXJpbmdkb25lXG4gIGlmIChvbmNhbmRpZGF0ZWdhdGhlcmluZ2RvbmUpIHtcbiAgICB0aGlzLm9uKCdjYW5kaWRhdGVnYXRoZXJpbmdkb25lJywgb25jYW5kaWRhdGVnYXRoZXJpbmdkb25lKVxuICB9XG5cbiAgdmFyIHNpbXVsY2FzdCA9IG9wdGlvbnMuc2ltdWxjYXN0XG4gIHZhciBtdWx0aXN0cmVhbSA9IG9wdGlvbnMubXVsdGlzdHJlYW1cbiAgdmFyIGludGVyb3AgPSBuZXcgc2RwVHJhbnNsYXRvci5JbnRlcm9wKClcbiAgdmFyIGNhbmRpZGF0ZXNRdWV1ZU91dCA9IFtdXG4gIHZhciBjYW5kaWRhdGVnYXRoZXJpbmdkb25lID0gZmFsc2VcblxuICBPYmplY3QuZGVmaW5lUHJvcGVydGllcyh0aGlzLCB7XG4gICAgJ3BlZXJDb25uZWN0aW9uJzoge1xuICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBwY1xuICAgICAgfVxuICAgIH0sXG5cbiAgICAnaWQnOiB7XG4gICAgICB2YWx1ZTogb3B0aW9ucy5pZCB8fCBndWlkLFxuICAgICAgd3JpdGFibGU6IGZhbHNlXG4gICAgfSxcblxuICAgICdyZW1vdGVWaWRlbyc6IHtcbiAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gcmVtb3RlVmlkZW9cbiAgICAgIH1cbiAgICB9LFxuXG4gICAgJ2xvY2FsVmlkZW8nOiB7XG4gICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIGxvY2FsVmlkZW9cbiAgICAgIH1cbiAgICB9LFxuXG4gICAgJ2RhdGFDaGFubmVsJzoge1xuICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBkYXRhQ2hhbm5lbFxuICAgICAgfVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBAbWVtYmVyIHsoZXh0ZXJuYWw6SW1hZ2VEYXRhfHVuZGVmaW5lZCl9IGN1cnJlbnRGcmFtZVxuICAgICAqL1xuICAgICdjdXJyZW50RnJhbWUnOiB7XG4gICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgLy8gW1RvRG9dIEZpbmQgc29sdXRpb24gd2hlbiB3ZSBoYXZlIGEgcmVtb3RlIHN0cmVhbSBidXQgd2UgZGlkbid0IHNldFxuICAgICAgICAvLyBhIHJlbW90ZVZpZGVvIHRhZ1xuICAgICAgICBpZiAoIXJlbW90ZVZpZGVvKSByZXR1cm47XG5cbiAgICAgICAgaWYgKHJlbW90ZVZpZGVvLnJlYWR5U3RhdGUgPCByZW1vdGVWaWRlby5IQVZFX0NVUlJFTlRfREFUQSlcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ05vIHZpZGVvIHN0cmVhbSBkYXRhIGF2YWlsYWJsZScpXG5cbiAgICAgICAgdmFyIGNhbnZhcyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2NhbnZhcycpXG4gICAgICAgIGNhbnZhcy53aWR0aCA9IHJlbW90ZVZpZGVvLnZpZGVvV2lkdGhcbiAgICAgICAgY2FudmFzLmhlaWdodCA9IHJlbW90ZVZpZGVvLnZpZGVvSGVpZ2h0XG5cbiAgICAgICAgY2FudmFzLmdldENvbnRleHQoJzJkJykuZHJhd0ltYWdlKHJlbW90ZVZpZGVvLCAwLCAwKVxuXG4gICAgICAgIHJldHVybiBjYW52YXNcbiAgICAgIH1cbiAgICB9XG4gIH0pXG5cbiAgLy8gSW5pdCBQZWVyQ29ubmVjdGlvblxuICBpZiAoIXBjKSB7XG4gICAgcGMgPSBuZXcgUlRDUGVlckNvbm5lY3Rpb24oY29uZmlndXJhdGlvbik7XG4gICAgaWYgKHVzZURhdGFDaGFubmVscyAmJiAhZGF0YUNoYW5uZWwpIHtcbiAgICAgIHZhciBkY0lkID0gJ1dlYlJ0Y1BlZXItJyArIHNlbGYuaWRcbiAgICAgIHZhciBkY09wdGlvbnMgPSB1bmRlZmluZWRcbiAgICAgIGlmIChkYXRhQ2hhbm5lbENvbmZpZykge1xuICAgICAgICBkY0lkID0gZGF0YUNoYW5uZWxDb25maWcuaWQgfHwgZGNJZFxuICAgICAgICBkY09wdGlvbnMgPSBkYXRhQ2hhbm5lbENvbmZpZy5vcHRpb25zXG4gICAgICB9XG4gICAgICBkYXRhQ2hhbm5lbCA9IHBjLmNyZWF0ZURhdGFDaGFubmVsKGRjSWQsIGRjT3B0aW9ucyk7XG4gICAgICBpZiAoZGF0YUNoYW5uZWxDb25maWcpIHtcbiAgICAgICAgZGF0YUNoYW5uZWwub25vcGVuID0gZGF0YUNoYW5uZWxDb25maWcub25vcGVuO1xuICAgICAgICBkYXRhQ2hhbm5lbC5vbmNsb3NlID0gZGF0YUNoYW5uZWxDb25maWcub25jbG9zZTtcbiAgICAgICAgZGF0YUNoYW5uZWwub25tZXNzYWdlID0gZGF0YUNoYW5uZWxDb25maWcub25tZXNzYWdlO1xuICAgICAgICBkYXRhQ2hhbm5lbC5vbmJ1ZmZlcmVkYW1vdW50bG93ID0gZGF0YUNoYW5uZWxDb25maWcub25idWZmZXJlZGFtb3VudGxvdztcbiAgICAgICAgZGF0YUNoYW5uZWwub25lcnJvciA9IGRhdGFDaGFubmVsQ29uZmlnLm9uZXJyb3IgfHwgbm9vcDtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwYy5hZGRFdmVudExpc3RlbmVyKCdpY2VjYW5kaWRhdGUnLCBmdW5jdGlvbiAoZXZlbnQpIHtcbiAgICB2YXIgY2FuZGlkYXRlID0gZXZlbnQuY2FuZGlkYXRlXG5cbiAgICBpZiAoRXZlbnRFbWl0dGVyLmxpc3RlbmVyQ291bnQoc2VsZiwgJ2ljZWNhbmRpZGF0ZScpIHx8XG4gICAgICBFdmVudEVtaXR0ZXIubGlzdGVuZXJDb3VudChcbiAgICAgICAgc2VsZiwgJ2NhbmRpZGF0ZWdhdGhlcmluZ2RvbmUnKSkge1xuICAgICAgaWYgKGNhbmRpZGF0ZSkge1xuICAgICAgICB2YXIgY2FuZFxuXG4gICAgICAgIGlmIChtdWx0aXN0cmVhbSAmJiB1c2VQbGFuQikge1xuICAgICAgICAgIGNhbmQgPSBpbnRlcm9wLmNhbmRpZGF0ZVRvVW5pZmllZFBsYW4oY2FuZGlkYXRlKVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNhbmQgPSBjYW5kaWRhdGVcbiAgICAgICAgfVxuXG4gICAgICAgIHNlbGYuZW1pdCgnaWNlY2FuZGlkYXRlJywgY2FuZClcbiAgICAgICAgY2FuZGlkYXRlZ2F0aGVyaW5nZG9uZSA9IGZhbHNlXG4gICAgICB9IGVsc2UgaWYgKCFjYW5kaWRhdGVnYXRoZXJpbmdkb25lKSB7XG4gICAgICAgIHNlbGYuZW1pdCgnY2FuZGlkYXRlZ2F0aGVyaW5nZG9uZScpXG4gICAgICAgIGNhbmRpZGF0ZWdhdGhlcmluZ2RvbmUgPSB0cnVlXG4gICAgICB9XG4gICAgfSBlbHNlIGlmICghY2FuZGlkYXRlZ2F0aGVyaW5nZG9uZSkge1xuICAgICAgLy8gTm90IGxpc3RlbmluZyB0byAnaWNlY2FuZGlkYXRlJyBvciAnY2FuZGlkYXRlZ2F0aGVyaW5nZG9uZScgZXZlbnRzLCBxdWV1ZVxuICAgICAgLy8gdGhlIGNhbmRpZGF0ZSB1bnRpbCBvbmUgb2YgdGhlbSBpcyBsaXN0ZW5lZFxuICAgICAgY2FuZGlkYXRlc1F1ZXVlT3V0LnB1c2goY2FuZGlkYXRlKVxuXG4gICAgICBpZiAoIWNhbmRpZGF0ZSkgY2FuZGlkYXRlZ2F0aGVyaW5nZG9uZSA9IHRydWVcbiAgICB9XG4gIH0pXG5cbiAgcGMub250cmFjayA9IG9wdGlvbnMub25hZGRzdHJlYW1cbiAgcGMub25uZWdvdGlhdGlvbm5lZWRlZCA9IG9wdGlvbnMub25uZWdvdGlhdGlvbm5lZWRlZFxuICB0aGlzLm9uKCduZXdMaXN0ZW5lcicsIGZ1bmN0aW9uIChldmVudCwgbGlzdGVuZXIpIHtcbiAgICBpZiAoZXZlbnQgPT09ICdpY2VjYW5kaWRhdGUnIHx8IGV2ZW50ID09PSAnY2FuZGlkYXRlZ2F0aGVyaW5nZG9uZScpIHtcbiAgICAgIHdoaWxlIChjYW5kaWRhdGVzUXVldWVPdXQubGVuZ3RoKSB7XG4gICAgICAgIHZhciBjYW5kaWRhdGUgPSBjYW5kaWRhdGVzUXVldWVPdXQuc2hpZnQoKVxuXG4gICAgICAgIGlmICghY2FuZGlkYXRlID09PSAoZXZlbnQgPT09ICdjYW5kaWRhdGVnYXRoZXJpbmdkb25lJykpIHtcbiAgICAgICAgICBsaXN0ZW5lcihjYW5kaWRhdGUpXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH0pXG5cbiAgdmFyIGFkZEljZUNhbmRpZGF0ZSA9IGJ1ZmZlcml6ZUNhbmRpZGF0ZXMocGMpXG5cbiAgLyoqXG4gICAqIENhbGxiYWNrIGZ1bmN0aW9uIGludm9rZWQgd2hlbiBhbiBJQ0UgY2FuZGlkYXRlIGlzIHJlY2VpdmVkLiBEZXZlbG9wZXJzIGFyZVxuICAgKiBleHBlY3RlZCB0byBpbnZva2UgdGhpcyBmdW5jdGlvbiBpbiBvcmRlciB0byBjb21wbGV0ZSB0aGUgU0RQIG5lZ290aWF0aW9uLlxuICAgKlxuICAgKiBAZnVuY3Rpb24gbW9kdWxlOmt1cmVudG9VdGlscy5XZWJSdGNQZWVyLnByb3RvdHlwZS5hZGRJY2VDYW5kaWRhdGVcbiAgICpcbiAgICogQHBhcmFtIGljZUNhbmRpZGF0ZSAtIExpdGVyYWwgb2JqZWN0IHdpdGggdGhlIElDRSBjYW5kaWRhdGUgZGVzY3JpcHRpb25cbiAgICogQHBhcmFtIGNhbGxiYWNrIC0gQ2FsbGVkIHdoZW4gdGhlIElDRSBjYW5kaWRhdGUgaGFzIGJlZW4gYWRkZWQuXG4gICAqL1xuICB0aGlzLmFkZEljZUNhbmRpZGF0ZSA9IGZ1bmN0aW9uIChpY2VDYW5kaWRhdGUsIGNhbGxiYWNrKSB7XG4gICAgdmFyIGNhbmRpZGF0ZVxuXG4gICAgaWYgKG11bHRpc3RyZWFtICYmIHVzZVBsYW5CKSB7XG4gICAgICBjYW5kaWRhdGUgPSBpbnRlcm9wLmNhbmRpZGF0ZVRvUGxhbkIoaWNlQ2FuZGlkYXRlKVxuICAgIH0gZWxzZSB7XG4gICAgICBjYW5kaWRhdGUgPSBuZXcgUlRDSWNlQ2FuZGlkYXRlKGljZUNhbmRpZGF0ZSlcbiAgICB9XG5cbiAgICBsb2dnZXIuZGVidWcoJ1JlbW90ZSBJQ0UgY2FuZGlkYXRlIHJlY2VpdmVkJywgaWNlQ2FuZGlkYXRlKVxuICAgIGNhbGxiYWNrID0gKGNhbGxiYWNrIHx8IG5vb3ApLmJpbmQodGhpcylcbiAgICBhZGRJY2VDYW5kaWRhdGUoY2FuZGlkYXRlLCBjYWxsYmFjaylcbiAgfVxuXG4gIHRoaXMuZ2VuZXJhdGVPZmZlciA9IGZ1bmN0aW9uIChjYWxsYmFjaykge1xuICAgIGNhbGxiYWNrID0gY2FsbGJhY2suYmluZCh0aGlzKVxuXG4gICAgdmFyIG9mZmVyQXVkaW8gPSB0cnVlXG4gICAgdmFyIG9mZmVyVmlkZW8gPSB0cnVlXG4gICAgLy8gQ29uc3RyYWludHMgbXVzdCBoYXZlIGJvdGggYmxvY2tzXG4gICAgaWYgKG1lZGlhQ29uc3RyYWludHMpIHtcbiAgICAgIG9mZmVyQXVkaW8gPSAodHlwZW9mIG1lZGlhQ29uc3RyYWludHMuYXVkaW8gPT09ICdib29sZWFuJykgP1xuICAgICAgICBtZWRpYUNvbnN0cmFpbnRzLmF1ZGlvIDogdHJ1ZVxuICAgICAgb2ZmZXJWaWRlbyA9ICh0eXBlb2YgbWVkaWFDb25zdHJhaW50cy52aWRlbyA9PT0gJ2Jvb2xlYW4nKSA/XG4gICAgICAgIG1lZGlhQ29uc3RyYWludHMudmlkZW8gOiB0cnVlXG4gICAgfVxuXG4gICAgdmFyIGJyb3dzZXJEZXBlbmRhbnRDb25zdHJhaW50cyA9IHtcbiAgICAgIG9mZmVyVG9SZWNlaXZlQXVkaW86IChtb2RlICE9PSAnc2VuZG9ubHknICYmIG9mZmVyQXVkaW8pLFxuICAgICAgb2ZmZXJUb1JlY2VpdmVWaWRlbzogKG1vZGUgIT09ICdzZW5kb25seScgJiYgb2ZmZXJWaWRlbylcbiAgICB9XG5cbiAgICAvL0ZJWE1FOiBjbGFyaWZ5IHBvc3NpYmxlIGNvbnN0cmFpbnRzIHBhc3NlZCB0byBjcmVhdGVPZmZlcigpXG4gICAgLyp2YXIgY29uc3RyYWludHMgPSByZWN1cnNpdmUoYnJvd3NlckRlcGVuZGFudENvbnN0cmFpbnRzLFxuICAgICAgY29ubmVjdGlvbkNvbnN0cmFpbnRzKSovXG5cbiAgICB2YXIgY29uc3RyYWludHMgPSBicm93c2VyRGVwZW5kYW50Q29uc3RyYWludHM7XG5cbiAgICBsb2dnZXIuZGVidWcoJ2NvbnN0cmFpbnRzOiAnICsgSlNPTi5zdHJpbmdpZnkoY29uc3RyYWludHMpKVxuXG4gICAgcGMuY3JlYXRlT2ZmZXIoY29uc3RyYWludHMpLnRoZW4oZnVuY3Rpb24gKG9mZmVyKSB7XG4gICAgICBsb2dnZXIuZGVidWcoJ0NyZWF0ZWQgU0RQIG9mZmVyJylcbiAgICAgIG9mZmVyID0gbWFuZ2xlU2RwVG9BZGRTaW11bGNhc3Qob2ZmZXIpXG4gICAgICByZXR1cm4gcGMuc2V0TG9jYWxEZXNjcmlwdGlvbihvZmZlcilcbiAgICB9KS50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciBsb2NhbERlc2NyaXB0aW9uID0gcGMubG9jYWxEZXNjcmlwdGlvblxuICAgICAgbG9nZ2VyLmRlYnVnKCdMb2NhbCBkZXNjcmlwdGlvbiBzZXQnLCBsb2NhbERlc2NyaXB0aW9uLnNkcClcbiAgICAgIGlmIChtdWx0aXN0cmVhbSAmJiB1c2VQbGFuQikge1xuICAgICAgICBsb2NhbERlc2NyaXB0aW9uID0gaW50ZXJvcC50b1VuaWZpZWRQbGFuKGxvY2FsRGVzY3JpcHRpb24pXG4gICAgICAgIGxvZ2dlci5kZWJ1Zygnb2ZmZXI6Om9yaWdQbGFuQi0+VW5pZmllZFBsYW4nLCBkdW1wU0RQKFxuICAgICAgICAgIGxvY2FsRGVzY3JpcHRpb24pKVxuICAgICAgfVxuICAgICAgY2FsbGJhY2sobnVsbCwgbG9jYWxEZXNjcmlwdGlvbi5zZHAsIHNlbGYucHJvY2Vzc0Fuc3dlci5iaW5kKFxuICAgICAgICBzZWxmKSlcbiAgICB9KS5jYXRjaChjYWxsYmFjaylcbiAgfVxuXG4gIHRoaXMuZ2V0TG9jYWxTZXNzaW9uRGVzY3JpcHRvciA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gcGMubG9jYWxEZXNjcmlwdGlvblxuICB9XG5cbiAgdGhpcy5nZXRSZW1vdGVTZXNzaW9uRGVzY3JpcHRvciA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gcGMucmVtb3RlRGVzY3JpcHRpb25cbiAgfVxuXG4gIGZ1bmN0aW9uIHNldFJlbW90ZVZpZGVvKCkge1xuICAgIGlmIChyZW1vdGVWaWRlbykge1xuICAgICAgdmFyIHN0cmVhbSA9IHBjLmdldFJlbW90ZVN0cmVhbXMoKVswXVxuICAgICAgdmFyIHVybCA9IHN0cmVhbSA/IFVSTC5jcmVhdGVPYmplY3RVUkwoc3RyZWFtKSA6ICcnXG5cbiAgICAgIHJlbW90ZVZpZGVvLnBhdXNlKClcbiAgICAgIHJlbW90ZVZpZGVvLnNyYyA9IHVybFxuICAgICAgcmVtb3RlVmlkZW8ubG9hZCgpXG5cbiAgICAgIGxvZ2dlci5kZWJ1ZygnUmVtb3RlIFVSTDonLCB1cmwpXG4gICAgfVxuICB9XG5cbiAgdGhpcy5zaG93TG9jYWxWaWRlbyA9IGZ1bmN0aW9uICgpIHtcbiAgICBsb2NhbFZpZGVvLnNyYyA9IFVSTC5jcmVhdGVPYmplY3RVUkwodmlkZW9TdHJlYW0pXG4gICAgbG9jYWxWaWRlby5tdXRlZCA9IHRydWVcbiAgfVxuXG4gIHRoaXMuc2VuZCA9IGZ1bmN0aW9uIChkYXRhKSB7XG4gICAgaWYgKGRhdGFDaGFubmVsICYmIGRhdGFDaGFubmVsLnJlYWR5U3RhdGUgPT09ICdvcGVuJykge1xuICAgICAgZGF0YUNoYW5uZWwuc2VuZChkYXRhKVxuICAgIH0gZWxzZSB7XG4gICAgICBsb2dnZXIud2FybihcbiAgICAgICAgJ1RyeWluZyB0byBzZW5kIGRhdGEgb3ZlciBhIG5vbi1leGlzdGluZyBvciBjbG9zZWQgZGF0YSBjaGFubmVsJylcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQ2FsbGJhY2sgZnVuY3Rpb24gaW52b2tlZCB3aGVuIGEgU0RQIGFuc3dlciBpcyByZWNlaXZlZC4gRGV2ZWxvcGVycyBhcmVcbiAgICogZXhwZWN0ZWQgdG8gaW52b2tlIHRoaXMgZnVuY3Rpb24gaW4gb3JkZXIgdG8gY29tcGxldGUgdGhlIFNEUCBuZWdvdGlhdGlvbi5cbiAgICpcbiAgICogQGZ1bmN0aW9uIG1vZHVsZTprdXJlbnRvVXRpbHMuV2ViUnRjUGVlci5wcm90b3R5cGUucHJvY2Vzc0Fuc3dlclxuICAgKlxuICAgKiBAcGFyYW0gc2RwQW5zd2VyIC0gRGVzY3JpcHRpb24gb2Ygc2RwQW5zd2VyXG4gICAqIEBwYXJhbSBjYWxsYmFjayAtXG4gICAqICAgICAgICAgICAgSW52b2tlZCBhZnRlciB0aGUgU0RQIGFuc3dlciBpcyBwcm9jZXNzZWQsIG9yIHRoZXJlIGlzIGFuIGVycm9yLlxuICAgKi9cbiAgdGhpcy5wcm9jZXNzQW5zd2VyID0gZnVuY3Rpb24gKHNkcEFuc3dlciwgY2FsbGJhY2spIHtcbiAgICBjYWxsYmFjayA9IChjYWxsYmFjayB8fCBub29wKS5iaW5kKHRoaXMpXG5cbiAgICB2YXIgYW5zd2VyID0gbmV3IFJUQ1Nlc3Npb25EZXNjcmlwdGlvbih7XG4gICAgICB0eXBlOiAnYW5zd2VyJyxcbiAgICAgIHNkcDogc2RwQW5zd2VyXG4gICAgfSlcblxuICAgIGlmIChtdWx0aXN0cmVhbSAmJiB1c2VQbGFuQikge1xuICAgICAgdmFyIHBsYW5CQW5zd2VyID0gaW50ZXJvcC50b1BsYW5CKGFuc3dlcilcbiAgICAgIGxvZ2dlci5kZWJ1ZygnYXNud2VyOjpwbGFuQicsIGR1bXBTRFAocGxhbkJBbnN3ZXIpKVxuICAgICAgYW5zd2VyID0gcGxhbkJBbnN3ZXJcbiAgICB9XG5cbiAgICBsb2dnZXIuZGVidWcoJ1NEUCBhbnN3ZXIgcmVjZWl2ZWQsIHNldHRpbmcgcmVtb3RlIGRlc2NyaXB0aW9uJylcblxuICAgIGlmIChwYy5zaWduYWxpbmdTdGF0ZSA9PT0gJ2Nsb3NlZCcpIHtcbiAgICAgIHJldHVybiBjYWxsYmFjaygnUGVlckNvbm5lY3Rpb24gaXMgY2xvc2VkJylcbiAgICB9XG5cbiAgICBwYy5zZXRSZW1vdGVEZXNjcmlwdGlvbihhbnN3ZXIsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgc2V0UmVtb3RlVmlkZW8oKVxuXG4gICAgICAgIGNhbGxiYWNrKClcbiAgICAgIH0sXG4gICAgICBjYWxsYmFjaylcbiAgfVxuXG4gIC8qKlxuICAgKiBDYWxsYmFjayBmdW5jdGlvbiBpbnZva2VkIHdoZW4gYSBTRFAgb2ZmZXIgaXMgcmVjZWl2ZWQuIERldmVsb3BlcnMgYXJlXG4gICAqIGV4cGVjdGVkIHRvIGludm9rZSB0aGlzIGZ1bmN0aW9uIGluIG9yZGVyIHRvIGNvbXBsZXRlIHRoZSBTRFAgbmVnb3RpYXRpb24uXG4gICAqXG4gICAqIEBmdW5jdGlvbiBtb2R1bGU6a3VyZW50b1V0aWxzLldlYlJ0Y1BlZXIucHJvdG90eXBlLnByb2Nlc3NPZmZlclxuICAgKlxuICAgKiBAcGFyYW0gc2RwT2ZmZXIgLSBEZXNjcmlwdGlvbiBvZiBzZHBPZmZlclxuICAgKiBAcGFyYW0gY2FsbGJhY2sgLSBDYWxsZWQgd2hlbiB0aGUgcmVtb3RlIGRlc2NyaXB0aW9uIGhhcyBiZWVuIHNldFxuICAgKiAgc3VjY2Vzc2Z1bGx5LlxuICAgKi9cbiAgdGhpcy5wcm9jZXNzT2ZmZXIgPSBmdW5jdGlvbiAoc2RwT2ZmZXIsIGNhbGxiYWNrKSB7XG4gICAgY2FsbGJhY2sgPSBjYWxsYmFjay5iaW5kKHRoaXMpXG5cbiAgICB2YXIgb2ZmZXIgPSBuZXcgUlRDU2Vzc2lvbkRlc2NyaXB0aW9uKHtcbiAgICAgIHR5cGU6ICdvZmZlcicsXG4gICAgICBzZHA6IHNkcE9mZmVyXG4gICAgfSlcblxuICAgIGlmIChtdWx0aXN0cmVhbSAmJiB1c2VQbGFuQikge1xuICAgICAgdmFyIHBsYW5CT2ZmZXIgPSBpbnRlcm9wLnRvUGxhbkIob2ZmZXIpXG4gICAgICBsb2dnZXIuZGVidWcoJ29mZmVyOjpwbGFuQicsIGR1bXBTRFAocGxhbkJPZmZlcikpXG4gICAgICBvZmZlciA9IHBsYW5CT2ZmZXJcbiAgICB9XG5cbiAgICBsb2dnZXIuZGVidWcoJ1NEUCBvZmZlciByZWNlaXZlZCwgc2V0dGluZyByZW1vdGUgZGVzY3JpcHRpb24nKVxuXG4gICAgaWYgKHBjLnNpZ25hbGluZ1N0YXRlID09PSAnY2xvc2VkJykge1xuICAgICAgcmV0dXJuIGNhbGxiYWNrKCdQZWVyQ29ubmVjdGlvbiBpcyBjbG9zZWQnKVxuICAgIH1cblxuICAgIHBjLnNldFJlbW90ZURlc2NyaXB0aW9uKG9mZmVyKS50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICAgIHJldHVybiBzZXRSZW1vdGVWaWRlbygpXG4gICAgfSkudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICByZXR1cm4gcGMuY3JlYXRlQW5zd2VyKClcbiAgICB9KS50aGVuKGZ1bmN0aW9uIChhbnN3ZXIpIHtcbiAgICAgIGFuc3dlciA9IG1hbmdsZVNkcFRvQWRkU2ltdWxjYXN0KGFuc3dlcilcbiAgICAgIGxvZ2dlci5kZWJ1ZygnQ3JlYXRlZCBTRFAgYW5zd2VyJylcbiAgICAgIHJldHVybiBwYy5zZXRMb2NhbERlc2NyaXB0aW9uKGFuc3dlcilcbiAgICB9KS50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciBsb2NhbERlc2NyaXB0aW9uID0gcGMubG9jYWxEZXNjcmlwdGlvblxuICAgICAgaWYgKG11bHRpc3RyZWFtICYmIHVzZVBsYW5CKSB7XG4gICAgICAgIGxvY2FsRGVzY3JpcHRpb24gPSBpbnRlcm9wLnRvVW5pZmllZFBsYW4obG9jYWxEZXNjcmlwdGlvbilcbiAgICAgICAgbG9nZ2VyLmRlYnVnKCdhbnN3ZXI6Om9yaWdQbGFuQi0+VW5pZmllZFBsYW4nLCBkdW1wU0RQKFxuICAgICAgICAgIGxvY2FsRGVzY3JpcHRpb24pKVxuICAgICAgfVxuICAgICAgbG9nZ2VyLmRlYnVnKCdMb2NhbCBkZXNjcmlwdGlvbiBzZXQnLCBsb2NhbERlc2NyaXB0aW9uLnNkcClcbiAgICAgIGNhbGxiYWNrKG51bGwsIGxvY2FsRGVzY3JpcHRpb24uc2RwKVxuICAgIH0pLmNhdGNoKGNhbGxiYWNrKVxuICB9XG5cbiAgZnVuY3Rpb24gbWFuZ2xlU2RwVG9BZGRTaW11bGNhc3QoYW5zd2VyKSB7XG4gICAgaWYgKHNpbXVsY2FzdCkge1xuICAgICAgaWYgKGJyb3dzZXIubmFtZSA9PT0gJ0Nocm9tZScgfHwgYnJvd3Nlci5uYW1lID09PSAnQ2hyb21pdW0nKSB7XG4gICAgICAgIGxvZ2dlci5kZWJ1ZygnQWRkaW5nIG11bHRpY2FzdCBpbmZvJylcbiAgICAgICAgYW5zd2VyID0gbmV3IFJUQ1Nlc3Npb25EZXNjcmlwdGlvbih7XG4gICAgICAgICAgJ3R5cGUnOiBhbnN3ZXIudHlwZSxcbiAgICAgICAgICAnc2RwJzogcmVtb3ZlRklERnJvbU9mZmVyKGFuc3dlci5zZHApICsgZ2V0U2ltdWxjYXN0SW5mbyhcbiAgICAgICAgICAgIHZpZGVvU3RyZWFtKVxuICAgICAgICB9KVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbG9nZ2VyLndhcm4oJ1NpbXVsY2FzdCBpcyBvbmx5IGF2YWlsYWJsZSBpbiBDaHJvbWUgYnJvd3Nlci4nKVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBhbnN3ZXJcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGlzIGZ1bmN0aW9uIGNyZWF0ZXMgdGhlIFJUQ1BlZXJDb25uZWN0aW9uIG9iamVjdCB0YWtpbmcgaW50byBhY2NvdW50IHRoZVxuICAgKiBwcm9wZXJ0aWVzIHJlY2VpdmVkIGluIHRoZSBjb25zdHJ1Y3Rvci4gSXQgc3RhcnRzIHRoZSBTRFAgbmVnb3RpYXRpb25cbiAgICogcHJvY2VzczogZ2VuZXJhdGVzIHRoZSBTRFAgb2ZmZXIgYW5kIGludm9rZXMgdGhlIG9uc2Rwb2ZmZXIgY2FsbGJhY2suIFRoaXNcbiAgICogY2FsbGJhY2sgaXMgZXhwZWN0ZWQgdG8gc2VuZCB0aGUgU0RQIG9mZmVyLCBpbiBvcmRlciB0byBvYnRhaW4gYW4gU0RQXG4gICAqIGFuc3dlciBmcm9tIGFub3RoZXIgcGVlci5cbiAgICovXG4gIGZ1bmN0aW9uIHN0YXJ0KCkge1xuICAgIGlmIChwYy5zaWduYWxpbmdTdGF0ZSA9PT0gJ2Nsb3NlZCcpIHtcbiAgICAgIGNhbGxiYWNrKFxuICAgICAgICAnVGhlIHBlZXIgY29ubmVjdGlvbiBvYmplY3QgaXMgaW4gXCJjbG9zZWRcIiBzdGF0ZS4gVGhpcyBpcyBtb3N0IGxpa2VseSBkdWUgdG8gYW4gaW52b2NhdGlvbiBvZiB0aGUgZGlzcG9zZSBtZXRob2QgYmVmb3JlIGFjY2VwdGluZyBpbiB0aGUgZGlhbG9ndWUnXG4gICAgICApXG4gICAgfVxuXG4gICAgaWYgKHZpZGVvU3RyZWFtICYmIGxvY2FsVmlkZW8pIHtcbiAgICAgIHNlbGYuc2hvd0xvY2FsVmlkZW8oKVxuICAgIH1cblxuICAgIGlmICh2aWRlb1N0cmVhbSkge1xuICAgICAgcGMuYWRkU3RyZWFtKHZpZGVvU3RyZWFtKVxuICAgIH1cblxuICAgIGlmIChhdWRpb1N0cmVhbSkge1xuICAgICAgcGMuYWRkU3RyZWFtKGF1ZGlvU3RyZWFtKVxuICAgIH1cblxuICAgIC8vIFtIYWNrXSBodHRwczovL2NvZGUuZ29vZ2xlLmNvbS9wL2Nocm9taXVtL2lzc3Vlcy9kZXRhaWw/aWQ9NDQzNTU4XG4gICAgdmFyIGJyb3dzZXIgPSBwYXJzZXIuZ2V0QnJvd3NlcigpXG4gICAgaWYgKG1vZGUgPT09ICdzZW5kb25seScgJiZcbiAgICAgIChicm93c2VyLm5hbWUgPT09ICdDaHJvbWUnIHx8IGJyb3dzZXIubmFtZSA9PT0gJ0Nocm9taXVtJykgJiZcbiAgICAgIGJyb3dzZXIubWFqb3IgPT09IDM5KSB7XG4gICAgICBtb2RlID0gJ3NlbmRyZWN2J1xuICAgIH1cblxuICAgIGNhbGxiYWNrKClcbiAgfVxuXG4gIGlmIChtb2RlICE9PSAncmVjdm9ubHknICYmICF2aWRlb1N0cmVhbSAmJiAhYXVkaW9TdHJlYW0pIHtcbiAgICBmdW5jdGlvbiBnZXRNZWRpYShjb25zdHJhaW50cykge1xuICAgICAgaWYgKGNvbnN0cmFpbnRzID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgY29uc3RyYWludHMgPSBNRURJQV9DT05TVFJBSU5UU1xuICAgICAgfVxuXG4gICAgICBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmdldFVzZXJNZWRpYShjb25zdHJhaW50cykudGhlbihmdW5jdGlvbiAoc3RyZWFtKSB7XG4gICAgICAgIHZpZGVvU3RyZWFtID0gc3RyZWFtXG4gICAgICAgIHN0YXJ0KClcbiAgICAgIH0pLmNhdGNoKGNhbGxiYWNrKTtcbiAgICB9XG4gICAgaWYgKHNlbmRTb3VyY2UgPT09ICd3ZWJjYW0nKSB7XG4gICAgICBnZXRNZWRpYShtZWRpYUNvbnN0cmFpbnRzKVxuICAgIH0gZWxzZSB7XG4gICAgICBnZXRTY3JlZW5Db25zdHJhaW50cyhzZW5kU291cmNlLCBmdW5jdGlvbiAoZXJyb3IsIGNvbnN0cmFpbnRzXykge1xuICAgICAgICBpZiAoZXJyb3IpXG4gICAgICAgICAgcmV0dXJuIGNhbGxiYWNrKGVycm9yKVxuXG4gICAgICAgIGNvbnN0cmFpbnRzID0gW21lZGlhQ29uc3RyYWludHNdXG4gICAgICAgIGNvbnN0cmFpbnRzLnVuc2hpZnQoY29uc3RyYWludHNfKVxuICAgICAgICBnZXRNZWRpYShyZWN1cnNpdmUuYXBwbHkodW5kZWZpbmVkLCBjb25zdHJhaW50cykpXG4gICAgICB9LCBndWlkKVxuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBzZXRUaW1lb3V0KHN0YXJ0LCAwKVxuICB9XG5cbiAgdGhpcy5vbignX2Rpc3Bvc2UnLCBmdW5jdGlvbiAoKSB7XG4gICAgaWYgKGxvY2FsVmlkZW8pIHtcbiAgICAgIGxvY2FsVmlkZW8ucGF1c2UoKVxuICAgICAgbG9jYWxWaWRlby5zcmMgPSAnJ1xuICAgICAgbG9jYWxWaWRlby5sb2FkKClcbiAgICAgIC8vVW5tdXRlIGxvY2FsIHZpZGVvIGluIGNhc2UgdGhlIHZpZGVvIHRhZyBpcyBsYXRlciB1c2VkIGZvciByZW1vdGUgdmlkZW9cbiAgICAgIGxvY2FsVmlkZW8ubXV0ZWQgPSBmYWxzZVxuICAgIH1cbiAgICBpZiAocmVtb3RlVmlkZW8pIHtcbiAgICAgIHJlbW90ZVZpZGVvLnBhdXNlKClcbiAgICAgIHJlbW90ZVZpZGVvLnNyYyA9ICcnXG4gICAgICByZW1vdGVWaWRlby5sb2FkKClcbiAgICB9XG4gICAgc2VsZi5yZW1vdmVBbGxMaXN0ZW5lcnMoKVxuXG4gICAgaWYgKHdpbmRvdy5jYW5jZWxDaG9vc2VEZXNrdG9wTWVkaWEgIT09IHVuZGVmaW5lZCkge1xuICAgICAgd2luZG93LmNhbmNlbENob29zZURlc2t0b3BNZWRpYShndWlkKVxuICAgIH1cbiAgfSlcbn1cbmluaGVyaXRzKFdlYlJ0Y1BlZXIsIEV2ZW50RW1pdHRlcilcblxuZnVuY3Rpb24gY3JlYXRlRW5hYmxlRGVzY3JpcHRvcih0eXBlKSB7XG4gIHZhciBtZXRob2QgPSAnZ2V0JyArIHR5cGUgKyAnVHJhY2tzJ1xuXG4gIHJldHVybiB7XG4gICAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgIC8vIFtUb0RvXSBTaG91bGQgcmV0dXJuIHVuZGVmaW5lZCBpZiBub3QgYWxsIHRyYWNrcyBoYXZlIHRoZSBzYW1lIHZhbHVlP1xuXG4gICAgICBpZiAoIXRoaXMucGVlckNvbm5lY3Rpb24pIHJldHVyblxuXG4gICAgICB2YXIgc3RyZWFtcyA9IHRoaXMucGVlckNvbm5lY3Rpb24uZ2V0TG9jYWxTdHJlYW1zKClcbiAgICAgIGlmICghc3RyZWFtcy5sZW5ndGgpIHJldHVyblxuXG4gICAgICBmb3IgKHZhciBpID0gMCwgc3RyZWFtOyBzdHJlYW0gPSBzdHJlYW1zW2ldOyBpKyspIHtcbiAgICAgICAgdmFyIHRyYWNrcyA9IHN0cmVhbVttZXRob2RdKClcbiAgICAgICAgZm9yICh2YXIgaiA9IDAsIHRyYWNrOyB0cmFjayA9IHRyYWNrc1tqXTsgaisrKVxuICAgICAgICAgIGlmICghdHJhY2suZW5hYmxlZCkgcmV0dXJuIGZhbHNlXG4gICAgICB9XG5cbiAgICAgIHJldHVybiB0cnVlXG4gICAgfSxcbiAgICBzZXQ6IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgZnVuY3Rpb24gdHJhY2tTZXRFbmFibGUodHJhY2spIHtcbiAgICAgICAgdHJhY2suZW5hYmxlZCA9IHZhbHVlXG4gICAgICB9XG5cbiAgICAgIHRoaXMucGVlckNvbm5lY3Rpb24uZ2V0TG9jYWxTdHJlYW1zKCkuZm9yRWFjaChmdW5jdGlvbiAoc3RyZWFtKSB7XG4gICAgICAgIHN0cmVhbVttZXRob2RdKCkuZm9yRWFjaCh0cmFja1NldEVuYWJsZSlcbiAgICAgIH0pXG4gICAgfVxuICB9XG59XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKFdlYlJ0Y1BlZXIucHJvdG90eXBlLCB7XG4gICdlbmFibGVkJzoge1xuICAgIGVudW1lcmFibGU6IHRydWUsXG4gICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgICByZXR1cm4gdGhpcy5hdWRpb0VuYWJsZWQgJiYgdGhpcy52aWRlb0VuYWJsZWRcbiAgICB9LFxuICAgIHNldDogZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICB0aGlzLmF1ZGlvRW5hYmxlZCA9IHRoaXMudmlkZW9FbmFibGVkID0gdmFsdWVcbiAgICB9XG4gIH0sXG4gICdhdWRpb0VuYWJsZWQnOiBjcmVhdGVFbmFibGVEZXNjcmlwdG9yKCdBdWRpbycpLFxuICAndmlkZW9FbmFibGVkJzogY3JlYXRlRW5hYmxlRGVzY3JpcHRvcignVmlkZW8nKVxufSlcblxuV2ViUnRjUGVlci5wcm90b3R5cGUuZ2V0TG9jYWxTdHJlYW0gPSBmdW5jdGlvbiAoaW5kZXgpIHtcbiAgaWYgKHRoaXMucGVlckNvbm5lY3Rpb24pIHtcbiAgICByZXR1cm4gdGhpcy5wZWVyQ29ubmVjdGlvbi5nZXRMb2NhbFN0cmVhbXMoKVtpbmRleCB8fCAwXVxuICB9XG59XG5cbldlYlJ0Y1BlZXIucHJvdG90eXBlLmdldFJlbW90ZVN0cmVhbSA9IGZ1bmN0aW9uIChpbmRleCkge1xuICBpZiAodGhpcy5wZWVyQ29ubmVjdGlvbikge1xuICAgIHJldHVybiB0aGlzLnBlZXJDb25uZWN0aW9uLmdldFJlbW90ZVN0cmVhbXMoKVtpbmRleCB8fCAwXVxuICB9XG59XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIFRoaXMgbWV0aG9kIGZyZWVzIHRoZSByZXNvdXJjZXMgdXNlZCBieSBXZWJSdGNQZWVyLlxuICpcbiAqIEBmdW5jdGlvbiBtb2R1bGU6a3VyZW50b1V0aWxzLldlYlJ0Y1BlZXIucHJvdG90eXBlLmRpc3Bvc2VcbiAqL1xuV2ViUnRjUGVlci5wcm90b3R5cGUuZGlzcG9zZSA9IGZ1bmN0aW9uICgpIHtcbiAgbG9nZ2VyLmRlYnVnKCdEaXNwb3NpbmcgV2ViUnRjUGVlcicpXG5cbiAgdmFyIHBjID0gdGhpcy5wZWVyQ29ubmVjdGlvblxuICB2YXIgZGMgPSB0aGlzLmRhdGFDaGFubmVsXG4gIHRyeSB7XG4gICAgaWYgKGRjKSB7XG4gICAgICBpZiAoZGMuc2lnbmFsaW5nU3RhdGUgPT09ICdjbG9zZWQnKSByZXR1cm5cblxuICAgICAgZGMuY2xvc2UoKVxuICAgIH1cblxuICAgIGlmIChwYykge1xuICAgICAgaWYgKHBjLnNpZ25hbGluZ1N0YXRlID09PSAnY2xvc2VkJykgcmV0dXJuXG5cbiAgICAgIHBjLmdldExvY2FsU3RyZWFtcygpLmZvckVhY2goc3RyZWFtU3RvcClcblxuICAgICAgLy8gRklYTUUgVGhpcyBpcyBub3QgeWV0IGltcGxlbWVudGVkIGluIGZpcmVmb3hcbiAgICAgIC8vIGlmKHZpZGVvU3RyZWFtKSBwYy5yZW1vdmVTdHJlYW0odmlkZW9TdHJlYW0pO1xuICAgICAgLy8gaWYoYXVkaW9TdHJlYW0pIHBjLnJlbW92ZVN0cmVhbShhdWRpb1N0cmVhbSk7XG5cbiAgICAgIHBjLmNsb3NlKClcbiAgICB9XG4gIH0gY2F0Y2ggKGVycikge1xuICAgIGxvZ2dlci53YXJuKCdFeGNlcHRpb24gZGlzcG9zaW5nIHdlYnJ0YyBwZWVyICcgKyBlcnIpXG4gIH1cblxuICB0aGlzLmVtaXQoJ19kaXNwb3NlJylcbn1cblxuLy9cbi8vIFNwZWNpYWxpemVkIGNoaWxkIGNsYXNzZXNcbi8vXG5cbmZ1bmN0aW9uIFdlYlJ0Y1BlZXJSZWN2b25seShvcHRpb25zLCBjYWxsYmFjaykge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgV2ViUnRjUGVlclJlY3Zvbmx5KSkge1xuICAgIHJldHVybiBuZXcgV2ViUnRjUGVlclJlY3Zvbmx5KG9wdGlvbnMsIGNhbGxiYWNrKVxuICB9XG5cbiAgV2ViUnRjUGVlclJlY3Zvbmx5LnN1cGVyXy5jYWxsKHRoaXMsICdyZWN2b25seScsIG9wdGlvbnMsIGNhbGxiYWNrKVxufVxuaW5oZXJpdHMoV2ViUnRjUGVlclJlY3Zvbmx5LCBXZWJSdGNQZWVyKVxuXG5mdW5jdGlvbiBXZWJSdGNQZWVyU2VuZG9ubHkob3B0aW9ucywgY2FsbGJhY2spIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIFdlYlJ0Y1BlZXJTZW5kb25seSkpIHtcbiAgICByZXR1cm4gbmV3IFdlYlJ0Y1BlZXJTZW5kb25seShvcHRpb25zLCBjYWxsYmFjaylcbiAgfVxuXG4gIFdlYlJ0Y1BlZXJTZW5kb25seS5zdXBlcl8uY2FsbCh0aGlzLCAnc2VuZG9ubHknLCBvcHRpb25zLCBjYWxsYmFjaylcbn1cbmluaGVyaXRzKFdlYlJ0Y1BlZXJTZW5kb25seSwgV2ViUnRjUGVlcilcblxuZnVuY3Rpb24gV2ViUnRjUGVlclNlbmRyZWN2KG9wdGlvbnMsIGNhbGxiYWNrKSB7XG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBXZWJSdGNQZWVyU2VuZHJlY3YpKSB7XG4gICAgcmV0dXJuIG5ldyBXZWJSdGNQZWVyU2VuZHJlY3Yob3B0aW9ucywgY2FsbGJhY2spXG4gIH1cblxuICBXZWJSdGNQZWVyU2VuZHJlY3Yuc3VwZXJfLmNhbGwodGhpcywgJ3NlbmRyZWN2Jywgb3B0aW9ucywgY2FsbGJhY2spXG59XG5pbmhlcml0cyhXZWJSdGNQZWVyU2VuZHJlY3YsIFdlYlJ0Y1BlZXIpXG5cbmZ1bmN0aW9uIGhhcmtVdGlscyhzdHJlYW0sIG9wdGlvbnMpIHtcbiAgcmV0dXJuIGhhcmsoc3RyZWFtLCBvcHRpb25zKTtcbn1cblxuZXhwb3J0cy5idWZmZXJpemVDYW5kaWRhdGVzID0gYnVmZmVyaXplQ2FuZGlkYXRlc1xuXG5leHBvcnRzLldlYlJ0Y1BlZXJSZWN2b25seSA9IFdlYlJ0Y1BlZXJSZWN2b25seVxuZXhwb3J0cy5XZWJSdGNQZWVyU2VuZG9ubHkgPSBXZWJSdGNQZWVyU2VuZG9ubHlcbmV4cG9ydHMuV2ViUnRjUGVlclNlbmRyZWN2ID0gV2ViUnRjUGVlclNlbmRyZWN2XG5leHBvcnRzLmhhcmsgPSBoYXJrVXRpbHNcbiIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTQgS3VyZW50byAoaHR0cDovL2t1cmVudG8ub3JnLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG4vKipcbiAqIFRoaXMgbW9kdWxlIGNvbnRhaW5zIGEgc2V0IG9mIHJldXNhYmxlIGNvbXBvbmVudHMgdGhhdCBoYXZlIGJlZW4gZm91bmQgdXNlZnVsXG4gKiBkdXJpbmcgdGhlIGRldmVsb3BtZW50IG9mIHRoZSBXZWJSVEMgYXBwbGljYXRpb25zIHdpdGggS3VyZW50by5cbiAqIFxuICogQG1vZHVsZSBrdXJlbnRvVXRpbHNcbiAqIFxuICogQGNvcHlyaWdodCAyMDE0IEt1cmVudG8gKGh0dHA6Ly9rdXJlbnRvLm9yZy8pXG4gKiBAbGljZW5zZSBBTHYyXG4gKi9cblxudmFyIFdlYlJ0Y1BlZXIgPSByZXF1aXJlKCcuL1dlYlJ0Y1BlZXInKTtcblxuZXhwb3J0cy5XZWJSdGNQZWVyID0gV2ViUnRjUGVlcjtcbiIsImltcG9ydCB7IE9wZW5WaWR1IH0gZnJvbSAnLi9PcGVuVmlkdSc7XG5cbi8vVGhpcyBleHBvcnQgd2l0aCAtLXN0YW5kYWxvbmUgb3B0aW9uIGFsbG93cyB1c2luZyBPcGVuVmlkdSBmcm9tIGJvd3NlciB3aXRoIG5hbWVzcGFjZVxuLy9leHBvcnQgeyBPcGVuVmlkdSB9IGZyb20gJy4vT3BlblZpZHUnO1xuXG4vL1RoaXMgXCJoYWNrXCIgYWxsb3dzIHRvIHVzZSBPcGVuVmlkdSBmcm9tIHRoZSBnbG9iYWwgc3BhY2Ugd2luZG93XG5pZih3aW5kb3cpe1xuICAgIHdpbmRvd1tcIk9wZW5WaWR1XCJdID0gT3BlblZpZHU7XG59XG5cbi8vQ29tbWFuZCB0byBnZW5lcmF0ZSBidW5kbGUuanMgd2l0aG91dCBuYW1lc3BhY2Vcbi8vd2F0Y2hpZnkgTWFpbi50cyAtcCBbIHRzaWZ5IF0gLS1leGNsdWRlIGt1cmVudG8tYnJvd3Nlci1leHRlbnNpb25zIC0tZGVidWcgLW8gLi4vc3RhdGljL2pzL09wZW5WaWR1LmpzIC12IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNyBPcGVuVmlkdSAoaHR0cDovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuaW1wb3J0IHsgT3BlblZpZHVJbnRlcm5hbCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvT3BlblZpZHVJbnRlcm5hbCc7XG5cbmltcG9ydCB7IFNlc3Npb24gfSBmcm9tICcuL1Nlc3Npb24nO1xuaW1wb3J0IHsgUHVibGlzaGVyIH0gZnJvbSAnLi9QdWJsaXNoZXInO1xuXG5pbXBvcnQgKiBhcyBhZGFwdGVyIGZyb20gJ3dlYnJ0Yy1hZGFwdGVyJztcblxuaWYgKHdpbmRvdykge1xuICAgIHdpbmRvd1tcImFkYXB0ZXJcIl0gPSBhZGFwdGVyO1xufVxuXG5leHBvcnQgY2xhc3MgT3BlblZpZHUge1xuXG4gICAgb3BlblZpZHU6IE9wZW5WaWR1SW50ZXJuYWw7XG5cbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgdGhpcy5vcGVuVmlkdSA9IG5ldyBPcGVuVmlkdUludGVybmFsKCk7XG4gICAgICAgIGNvbnNvbGUuaW5mbyhcIidPcGVuVmlkdScgaW5pdGlhbGl6ZWRcIik7XG4gICAgfTtcblxuICAgIGluaXRTZXNzaW9uKGFwaUtleTogc3RyaW5nLCBzZXNzaW9uSWQ6IHN0cmluZyk6IFNlc3Npb247XG4gICAgaW5pdFNlc3Npb24oc2Vzc2lvbklkOiBzdHJpbmcpOiBTZXNzaW9uO1xuXG4gICAgaW5pdFNlc3Npb24ocGFyYW0xLCBwYXJhbTI/KTogYW55IHtcbiAgICAgICAgaWYgKHRoaXMuY2hlY2tTeXN0ZW1SZXF1aXJlbWVudHMoKSkge1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBwYXJhbTIgPT0gXCJzdHJpbmdcIikge1xuICAgICAgICAgICAgICAgIHJldHVybiBuZXcgU2Vzc2lvbih0aGlzLm9wZW5WaWR1LmluaXRTZXNzaW9uKHBhcmFtMiksIHRoaXMpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFNlc3Npb24odGhpcy5vcGVuVmlkdS5pbml0U2Vzc2lvbihwYXJhbTEpLCB0aGlzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGFsZXJ0KFwiQnJvd3NlciBub3Qgc3VwcG9ydGVkXCIpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgaW5pdFB1Ymxpc2hlcihwYXJlbnRJZDogc3RyaW5nKTogUHVibGlzaGVyO1xuICAgIGluaXRQdWJsaXNoZXIocGFyZW50SWQ6IHN0cmluZywgY2FtZXJhT3B0aW9uczogYW55KTogUHVibGlzaGVyO1xuICAgIGluaXRQdWJsaXNoZXIocGFyZW50SWQ6IHN0cmluZywgY2FtZXJhT3B0aW9uczogYW55LCBjYWxsYmFjazogYW55KTogUHVibGlzaGVyO1xuXG4gICAgaW5pdFB1Ymxpc2hlcihwYXJlbnRJZDogc3RyaW5nLCBjYW1lcmFPcHRpb25zPzogYW55LCBjYWxsYmFjaz86IEZ1bmN0aW9uKTogYW55IHtcbiAgICAgICAgaWYgKHRoaXMuY2hlY2tTeXN0ZW1SZXF1aXJlbWVudHMoKSkge1xuICAgICAgICAgICAgaWYgKGNhbWVyYU9wdGlvbnMgIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIGxldCBjYW1lcmFPcHRpb25zQXV4ID0ge1xuICAgICAgICAgICAgICAgICAgICBzZW5kQXVkaW86IGNhbWVyYU9wdGlvbnMuYXVkaW8gIT0gbnVsbCA/IGNhbWVyYU9wdGlvbnMuYXVkaW8gOiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICBzZW5kVmlkZW86IGNhbWVyYU9wdGlvbnMudmlkZW8gIT0gbnVsbCA/IGNhbWVyYU9wdGlvbnMudmlkZW8gOiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICBhY3RpdmVBdWRpbzogY2FtZXJhT3B0aW9ucy5hY3RpdmVBdWRpbyAhPSBudWxsID8gY2FtZXJhT3B0aW9ucy5hY3RpdmVBdWRpbyA6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgIGFjdGl2ZVZpZGVvOiBjYW1lcmFPcHRpb25zLmFjdGl2ZVZpZGVvICE9IG51bGwgPyBjYW1lcmFPcHRpb25zLmFjdGl2ZVZpZGVvIDogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgZGF0YTogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgbWVkaWFDb25zdHJhaW50czogdGhpcy5vcGVuVmlkdS5nZW5lcmF0ZU1lZGlhQ29uc3RyYWludHMoY2FtZXJhT3B0aW9ucylcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIGNhbWVyYU9wdGlvbnMgPSBjYW1lcmFPcHRpb25zQXV4O1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjYW1lcmFPcHRpb25zID0ge1xuICAgICAgICAgICAgICAgICAgICBzZW5kQXVkaW86IHRydWUsXG4gICAgICAgICAgICAgICAgICAgIHNlbmRWaWRlbzogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgYWN0aXZlQXVkaW86IHRydWUsXG4gICAgICAgICAgICAgICAgICAgIGFjdGl2ZVZpZGVvOiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICBkYXRhOiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICBtZWRpYUNvbnN0cmFpbnRzOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBhdWRpbzogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHZpZGVvOiB7IHdpZHRoOiB7IGlkZWFsOiAxMjgwIH0gfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFyIHB1Ymxpc2hlciA9IG5ldyBQdWJsaXNoZXIodGhpcy5vcGVuVmlkdS5pbml0UHVibGlzaGVyVGFnZ2VkKHBhcmVudElkLCBjYW1lcmFPcHRpb25zLCBjYWxsYmFjayksIHBhcmVudElkKTtcbiAgICAgICAgICAgIFxuICAgICAgICAgICAgY29uc29sZS5pbmZvKFwiJ1B1Ymxpc2hlcicgaW5pdGlhbGl6ZWRcIik7XG4gICAgICAgICAgICByZXR1cm4gcHVibGlzaGVyO1xuXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBhbGVydChcIkJyb3dzZXIgbm90IHN1cHBvcnRlZFwiKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGNoZWNrU3lzdGVtUmVxdWlyZW1lbnRzKCk6IG51bWJlciB7XG4gICAgICAgIGxldCBicm93c2VyID0gYWRhcHRlci5icm93c2VyRGV0YWlscy5icm93c2VyO1xuICAgICAgICBsZXQgdmVyc2lvbiA9IGFkYXB0ZXIuYnJvd3NlckRldGFpbHMudmVyc2lvbjtcblxuICAgICAgICAvL0J1ZyBmaXg6ICduYXZpZ2F0b3IudXNlckFnZW50JyBpbiBGaXJlZm94IGZvciBVYnVudHUgMTQuMDQgZG9lcyBub3QgcmV0dXJuIFwiRmlyZWZveC9bdmVyc2lvbl1cIiBpbiB0aGUgc3RyaW5nLCBzbyB2ZXJzaW9uIHJldHVybmVkIGlzIG51bGxcbiAgICAgICAgaWYgKChicm93c2VyID09ICdmaXJlZm94JykgJiYgKHZlcnNpb24gPT0gbnVsbCkpIHtcbiAgICAgICAgICAgIHJldHVybiAxO1xuICAgICAgICB9XG4gICAgICAgIGlmICgoKGJyb3dzZXIgPT0gJ2Nocm9tZScpICYmICh2ZXJzaW9uID49IDI4KSkgfHwgKChicm93c2VyID09ICdlZGdlJykgJiYgKHZlcnNpb24gPj0gMTIpKSB8fCAoKGJyb3dzZXIgPT0gJ2ZpcmVmb3gnKSAmJiAodmVyc2lvbiA+PSAyMikpKSB7XG4gICAgICAgICAgICByZXR1cm4gMTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiAwO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZ2V0RGV2aWNlcyhjYWxsYmFjaykge1xuICAgICAgICBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmVudW1lcmF0ZURldmljZXMoKS50aGVuKChkZXZpY2VJbmZvcykgPT4ge1xuICAgICAgICAgICAgY2FsbGJhY2sobnVsbCwgZGV2aWNlSW5mb3MpO1xuICAgICAgICB9KS5jYXRjaCgoZXJyb3IpID0+IHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoXCJFcnJvciBnZXR0aW5nIGRldmljZXNcIiwgZXJyb3IpO1xuICAgICAgICAgICAgY2FsbGJhY2soZXJyb3IsIG51bGwpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBlbmFibGVQcm9kTW9kZSgpIHtcbiAgICAgICAgY29uc29sZS5sb2cgPSBmdW5jdGlvbigpIHt9O1xuICAgICAgICBjb25zb2xlLmRlYnVnID0gZnVuY3Rpb24oKSB7fTtcbiAgICAgICAgY29uc29sZS5pbmZvID0gZnVuY3Rpb24oKSB7fTtcbiAgICAgICAgY29uc29sZS53YXJuID0gZnVuY3Rpb24oKSB7fTtcbiAgICB9XG5cbn1cbiIsIi8qXG4gKiBvcHRpb25zOiBuYW1lOiBYWFggZGF0YTogdHJ1ZSAoTWF5YmUgdGhpcyBpcyBiYXNlZCBvbiB3ZWJydGMpIGF1ZGlvOiB0cnVlLFxuICogdmlkZW86IHRydWUsIHVybDogXCJmaWxlOi8vLy4uLlwiID4gUGxheWVyIHNjcmVlbjogdHJ1ZSA+IERlc2t0b3AgKGltcGxpY2l0XG4gKiB2aWRlbzp0cnVlLCBhdWRpbzpmYWxzZSkgYXVkaW86IHRydWUsIHZpZGVvOiB0cnVlID4gV2ViY2FtXG4gKlxuICogc3RyZWFtLmhhc0F1ZGlvKCk7IHN0cmVhbS5oYXNWaWRlbygpOyBzdHJlYW0uaGFzRGF0YSgpO1xuICovXG5pbXBvcnQgeyBTdHJlYW0sIFN0cmVhbU9wdGlvbnMsIFZpZGVvT3B0aW9ucyB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvU3RyZWFtJztcbmltcG9ydCB7IFNlc3Npb24gfSBmcm9tICcuL1Nlc3Npb24nO1xuXG5pbXBvcnQgRXZlbnRFbWl0dGVyID0gcmVxdWlyZSgnd29sZnk4Ny1ldmVudGVtaXR0ZXInKTtcblxuZXhwb3J0IGNsYXNzIFB1Ymxpc2hlciB7XG5cbiAgICBwcml2YXRlIGVlID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuXG4gICAgYWNjZXNzQWxsb3dlZCA9IGZhbHNlO1xuICAgIGVsZW1lbnQ6IEVsZW1lbnQ7XG4gICAgaWQ6IHN0cmluZztcbiAgICBzdHJlYW06IFN0cmVhbTtcbiAgICBzZXNzaW9uOiBTZXNzaW9uOyAvL0luaXRpYWxpemVkIGJ5IFNlc3Npb24ucHVibGlzaChQdWJsaXNoZXIpXG5cbiAgICBjb25zdHJ1Y3RvcihzdHJlYW06IFN0cmVhbSwgcGFyZW50SWQ6IHN0cmluZykge1xuICAgICAgICB0aGlzLnN0cmVhbSA9IHN0cmVhbTtcblxuICAgICAgICB0aGlzLnN0cmVhbS5hZGRFdmVudExpc3RlbmVyKCdjYW1lcmEtYWNjZXNzLWNoYW5nZWQnLCAoZXZlbnQpID0+IHtcbiAgICAgICAgICAgIHRoaXMuYWNjZXNzQWxsb3dlZCA9IGV2ZW50LmFjY2Vzc0FsbG93ZWQ7XG4gICAgICAgICAgICBpZiAodGhpcy5hY2Nlc3NBbGxvd2VkKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ2FjY2Vzc0FsbG93ZWQnKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ2FjY2Vzc0RlbmllZCcpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgICBpZiAoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQocGFyZW50SWQpICE9IG51bGwpIHtcbiAgICAgICAgICAgIHRoaXMuZWxlbWVudCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKHBhcmVudElkKSEhO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHVibGlzaEF1ZGlvKHZhbHVlOiBib29sZWFuKSB7XG4gICAgICAgIHRoaXMuc3RyZWFtLmdldFdlYlJ0Y1BlZXIoKS5hdWRpb0VuYWJsZWQgPSB2YWx1ZTtcbiAgICB9XG5cbiAgICBwdWJsaXNoVmlkZW8odmFsdWU6IGJvb2xlYW4pIHtcbiAgICAgICAgdGhpcy5zdHJlYW0uZ2V0V2ViUnRjUGVlcigpLnZpZGVvRW5hYmxlZCA9IHZhbHVlO1xuICAgIH1cblxuICAgIGRlc3Ryb3koKSB7XG4gICAgICAgIHRoaXMuc2Vzc2lvbi51bnB1Ymxpc2godGhpcyk7XG4gICAgICAgIHRoaXMuc3RyZWFtLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5zdHJlYW0ucmVtb3ZlVmlkZW8odGhpcy5lbGVtZW50KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgc3Vic2NyaWJlVG9SZW1vdGUoKSB7XG4gICAgICAgIHRoaXMuc3RyZWFtLnN1YnNjcmliZVRvTXlSZW1vdGUoKTtcbiAgICB9XG5cbiAgICBvbihldmVudE5hbWU6IHN0cmluZywgY2FsbGJhY2spIHtcbiAgICAgICAgdGhpcy5lZS5hZGRMaXN0ZW5lcihldmVudE5hbWUsIGV2ZW50ID0+IHtcbiAgICAgICAgICAgIGlmIChldmVudCkge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIkV2ZW50ICdcIiArIGV2ZW50TmFtZSArIFwiJyB0cmlnZ2VyZWQgYnkgJ1B1Ymxpc2hlcidcIiwgZXZlbnQpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJFdmVudCAnXCIgKyBldmVudE5hbWUgKyBcIicgdHJpZ2dlcmVkIGJ5ICdQdWJsaXNoZXInXCIpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FsbGJhY2soZXZlbnQpO1xuICAgICAgICB9KTtcbiAgICAgICAgaWYgKGV2ZW50TmFtZSA9PSAndmlkZW9FbGVtZW50Q3JlYXRlZCcpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLnN0cmVhbS5pc1ZpZGVvRUxlbWVudENyZWF0ZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgndmlkZW9FbGVtZW50Q3JlYXRlZCcsIFt7XG4gICAgICAgICAgICAgICAgICAgIGVsZW1lbnQ6IHRoaXMuc3RyZWFtLmdldFZpZGVvRWxlbWVudCgpXG4gICAgICAgICAgICAgICAgfV0pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5hZGRPbmNlRXZlbnRMaXN0ZW5lcigndmlkZW8tZWxlbWVudC1jcmVhdGVkLWJ5LXN0cmVhbScsIChlbGVtZW50KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuaWQgPSBlbGVtZW50LmlkO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgndmlkZW9FbGVtZW50Q3JlYXRlZCcsIFt7XG4gICAgICAgICAgICAgICAgICAgICAgICBlbGVtZW50OiBlbGVtZW50LmVsZW1lbnRcbiAgICAgICAgICAgICAgICAgICAgfV0pO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChldmVudE5hbWUgPT0gJ3ZpZGVvUGxheWluZycpIHtcbiAgICAgICAgICAgIHZhciB2aWRlbyA9IHRoaXMuc3RyZWFtLmdldFZpZGVvRWxlbWVudCgpO1xuICAgICAgICAgICAgaWYgKCF0aGlzLnN0cmVhbS5kaXNwbGF5TXlSZW1vdGUoKSAmJiB2aWRlbyAmJlxuICAgICAgICAgICAgICAgIHZpZGVvLmN1cnJlbnRUaW1lID4gMCAmJiBcbiAgICAgICAgICAgICAgICB2aWRlby5wYXVzZWQgPT0gZmFsc2UgJiYgXG4gICAgICAgICAgICAgICAgdmlkZW8uZW5kZWQgPT0gZmFsc2UgJiZcbiAgICAgICAgICAgICAgICB2aWRlby5yZWFkeVN0YXRlID09IDQpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3ZpZGVvUGxheWluZycsIFt7XG4gICAgICAgICAgICAgICAgICAgICAgICBlbGVtZW50OiB0aGlzLnN0cmVhbS5nZXRWaWRlb0VsZW1lbnQoKVxuICAgICAgICAgICAgICAgICAgICB9XSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmFkZE9uY2VFdmVudExpc3RlbmVyKCd2aWRlby1pcy1wbGF5aW5nJywgKGVsZW1lbnQpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3ZpZGVvUGxheWluZycsIFt7XG4gICAgICAgICAgICAgICAgICAgICAgICBlbGVtZW50OiBlbGVtZW50LmVsZW1lbnRcbiAgICAgICAgICAgICAgICAgICAgfV0pO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChldmVudE5hbWUgPT0gJ3JlbW90ZVZpZGVvUGxheWluZycpIHtcbiAgICAgICAgICAgIHZhciB2aWRlbyA9IHRoaXMuc3RyZWFtLmdldFZpZGVvRWxlbWVudCgpO1xuICAgICAgICAgICAgaWYgKHRoaXMuc3RyZWFtLmRpc3BsYXlNeVJlbW90ZSgpICYmIHZpZGVvICYmXG4gICAgICAgICAgICAgICAgdmlkZW8uY3VycmVudFRpbWUgPiAwICYmIFxuICAgICAgICAgICAgICAgIHZpZGVvLnBhdXNlZCA9PSBmYWxzZSAmJiBcbiAgICAgICAgICAgICAgICB2aWRlby5lbmRlZCA9PSBmYWxzZSAmJlxuICAgICAgICAgICAgICAgIHZpZGVvLnJlYWR5U3RhdGUgPT0gNCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgncmVtb3RlVmlkZW9QbGF5aW5nJywgW3tcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnQ6IHRoaXMuc3RyZWFtLmdldFZpZGVvRWxlbWVudCgpXG4gICAgICAgICAgICAgICAgICAgIH1dKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uYWRkT25jZUV2ZW50TGlzdGVuZXIoJ3JlbW90ZS12aWRlby1pcy1wbGF5aW5nJywgKGVsZW1lbnQpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3JlbW90ZVZpZGVvUGxheWluZycsIFt7XG4gICAgICAgICAgICAgICAgICAgICAgICBlbGVtZW50OiBlbGVtZW50LmVsZW1lbnRcbiAgICAgICAgICAgICAgICAgICAgfV0pO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChldmVudE5hbWUgPT0gJ3N0cmVhbUNyZWF0ZWQnKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uaXNSZWFkeSkge1xuICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdzdHJlYW1DcmVhdGVkJywgW3sgc3RyZWFtOiB0aGlzLnN0cmVhbSB9XSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmFkZEV2ZW50TGlzdGVuZXIoJ3N0cmVhbS1jcmVhdGVkLWJ5LXB1Ymxpc2hlcicsICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS53YXJuKCdQdWJsaXNoZXIgZW1pdHRpbmcgc3RyZWFtQ3JlYXRlZCcpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgnc3RyZWFtQ3JlYXRlZCcsIFt7IHN0cmVhbTogdGhpcy5zdHJlYW0gfV0pO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChldmVudE5hbWUgPT0gJ2FjY2Vzc0FsbG93ZWQnKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uYWNjZXNzSXNBbGxvd2VkKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ2FjY2Vzc0FsbG93ZWQnKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uYWRkRXZlbnRMaXN0ZW5lcignYWNjZXNzLWFsbG93ZWQtYnktcHVibGlzaGVyJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgnYWNjZXNzQWxsb3dlZCcpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChldmVudE5hbWUgPT0gJ2FjY2Vzc0RlbmllZCcpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLnN0cmVhbS5hY2Nlc3NJc0RlbmllZCkge1xuICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdhY2Nlc3NEZW5pZWQnKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uYWRkRXZlbnRMaXN0ZW5lcignYWNjZXNzLWRlbmllZC1ieS1wdWJsaXNoZXInLCAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdhY2Nlc3NEZW5pZWQnKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbn0iLCJpbXBvcnQgeyBTZXNzaW9uSW50ZXJuYWwsIFNlc3Npb25PcHRpb25zIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9TZXNzaW9uSW50ZXJuYWwnO1xuaW1wb3J0IHsgU3RyZWFtIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9TdHJlYW0nO1xuaW1wb3J0IHsgQ29ubmVjdGlvbiB9IGZyb20gXCIuLi9PcGVuVmlkdUludGVybmFsL0Nvbm5lY3Rpb25cIjtcblxuaW1wb3J0IHsgT3BlblZpZHUgfSBmcm9tICcuL09wZW5WaWR1JztcbmltcG9ydCB7IFB1Ymxpc2hlciB9IGZyb20gJy4vUHVibGlzaGVyJztcbmltcG9ydCB7IFN1YnNjcmliZXIgfSBmcm9tICcuL1N1YnNjcmliZXInO1xuXG5pbXBvcnQgRXZlbnRFbWl0dGVyID0gcmVxdWlyZSgnd29sZnk4Ny1ldmVudGVtaXR0ZXInKTtcblxuZXhwb3J0IGNsYXNzIFNlc3Npb24ge1xuXG4gICAgc2Vzc2lvbklkOiBTdHJpbmc7XG4gICAgLy9jYXBhYmlsaXRpZXM6IENhcGFiaWxpdGllc1xuICAgIGNvbm5lY3Rpb246IENvbm5lY3Rpb247XG5cbiAgICBwcml2YXRlIGVlID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuXG4gICAgY29uc3RydWN0b3IocHJpdmF0ZSBzZXNzaW9uOiBTZXNzaW9uSW50ZXJuYWwsIHByaXZhdGUgb3BlblZpZHU6IE9wZW5WaWR1KSB7XG4gICAgICAgIHRoaXMuc2Vzc2lvbklkID0gc2Vzc2lvbi5nZXRTZXNzaW9uSWQoKTtcblxuICAgICAgICAvLyBMaXN0ZW5zIHRvIHRoZSBkZWFjdGl2YXRpb24gb2YgdGhlIGRlZmF1bHQgYmVoYXZpb3VyIHVwb24gdGhlIGRlbGV0aW9uIG9mIGEgU3RyZWFtIG9iamVjdFxuICAgICAgICB0aGlzLnNlc3Npb24uYWRkRXZlbnRMaXN0ZW5lcignc3RyZWFtLWRlc3Ryb3llZC1kZWZhdWx0JywgZXZlbnQgPT4ge1xuICAgICAgICAgICAgZXZlbnQuc3RyZWFtLnJlbW92ZVZpZGVvKCk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIExpc3RlbnMgdG8gdGhlIGRlYWN0aXZhdGlvbiBvZiB0aGUgZGVmYXVsdCBiZWhhdmlvdXIgdXBvbiB0aGUgZGlzY29ubmVjdGlvbiBvZiBhIFNlc3Npb25cbiAgICAgICAgdGhpcy5zZXNzaW9uLmFkZEV2ZW50TGlzdGVuZXIoJ3Nlc3Npb24tZGlzY29ubmVjdGVkLWRlZmF1bHQnLCAoKSA9PiB7XG4gICAgICAgICAgICBsZXQgczogU3RyZWFtO1xuICAgICAgICAgICAgZm9yIChzIG9mIHRoaXMub3BlblZpZHUub3BlblZpZHUuZ2V0UmVtb3RlU3RyZWFtcygpKSB7XG4gICAgICAgICAgICAgICAgcy5yZW1vdmVWaWRlbygpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHRoaXMuY29ubmVjdGlvbikge1xuICAgICAgICAgICAgICAgIGZvciAobGV0IHN0cmVhbUlkIGluIHRoaXMuY29ubmVjdGlvbi5nZXRTdHJlYW1zKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jb25uZWN0aW9uLmdldFN0cmVhbXMoKVtzdHJlYW1JZF0ucmVtb3ZlVmlkZW8oKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIFNldHMgb3IgdXBkYXRlcyB0aGUgdmFsdWUgb2YgJ2Nvbm5lY3Rpb24nIHByb3BlcnR5LiBUcmlnZ2VyZWQgYnkgU2Vzc2lvbkludGVybmFsIHdoZW4gc3VjY2VzZnVsIGNvbm5lY3Rpb25cbiAgICAgICAgdGhpcy5zZXNzaW9uLmFkZEV2ZW50TGlzdGVuZXIoJ3VwZGF0ZS1jb25uZWN0aW9uLW9iamVjdCcsIGV2ZW50ID0+IHtcbiAgICAgICAgICAgIHRoaXMuY29ubmVjdGlvbiA9IGV2ZW50LmNvbm5lY3Rpb247XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIGNvbm5lY3QodG9rZW46IHN0cmluZywgY2FsbGJhY2s6IGFueSk7XG4gICAgY29ubmVjdCh0b2tlbjogc3RyaW5nLCBtZXRhZGF0YTogYW55LCBjYWxsYmFjazogYW55KTtcblxuICAgIGNvbm5lY3QocGFyYW0xLCBwYXJhbTIsIHBhcmFtMz8pIHtcbiAgICAgICAgLy8gRWFybHkgY29uZmlndXJhdGlvbiB0byBkZWFjdGl2YXRlIGF1dG9tYXRpYyBzdWJzY3JpcHRpb24gdG8gc3RyZWFtc1xuICAgICAgICBpZiAocGFyYW0zKSB7XG4gICAgICAgICAgICB0aGlzLnNlc3Npb24uY29uZmlndXJlKHtcbiAgICAgICAgICAgICAgICBzZXNzaW9uSWQ6IHRoaXMuc2Vzc2lvbi5nZXRTZXNzaW9uSWQoKSxcbiAgICAgICAgICAgICAgICBwYXJ0aWNpcGFudElkOiBwYXJhbTEsXG4gICAgICAgICAgICAgICAgbWV0YWRhdGE6IHRoaXMuc2Vzc2lvbi5zdHJpbmdDbGllbnRNZXRhZGF0YShwYXJhbTIpLFxuICAgICAgICAgICAgICAgIHN1YnNjcmliZVRvU3RyZWFtczogZmFsc2VcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgdGhpcy5zZXNzaW9uLmNvbm5lY3QocGFyYW0xLCBwYXJhbTMpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5zZXNzaW9uLmNvbmZpZ3VyZSh7XG4gICAgICAgICAgICAgICAgc2Vzc2lvbklkOiB0aGlzLnNlc3Npb24uZ2V0U2Vzc2lvbklkKCksXG4gICAgICAgICAgICAgICAgcGFydGljaXBhbnRJZDogcGFyYW0xLFxuICAgICAgICAgICAgICAgIG1ldGFkYXRhOiAnJyxcbiAgICAgICAgICAgICAgICBzdWJzY3JpYmVUb1N0cmVhbXM6IGZhbHNlXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5jb25uZWN0KHBhcmFtMSwgcGFyYW0yKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGRpc2Nvbm5lY3QoKSB7XG4gICAgICAgIHRoaXMub3BlblZpZHUub3BlblZpZHUuY2xvc2UoZmFsc2UpO1xuICAgICAgICB0aGlzLnNlc3Npb24uZW1pdEV2ZW50KCdzZXNzaW9uRGlzY29ubmVjdGVkJywgW3tcbiAgICAgICAgICAgIHByZXZlbnREZWZhdWx0OiAoKSA9PiB7IHRoaXMuc2Vzc2lvbi5yZW1vdmVFdmVudCgnc2Vzc2lvbi1kaXNjb25uZWN0ZWQtZGVmYXVsdCcpOyB9XG4gICAgICAgIH1dKTtcbiAgICAgICAgdGhpcy5zZXNzaW9uLmVtaXRFdmVudCgnc2Vzc2lvbi1kaXNjb25uZWN0ZWQtZGVmYXVsdCcsIFt7fV0pO1xuICAgIH1cblxuICAgIHB1Ymxpc2gocHVibGlzaGVyOiBQdWJsaXNoZXIpIHtcbiAgICAgICAgcHVibGlzaGVyLnNlc3Npb24gPSB0aGlzO1xuICAgICAgICBwdWJsaXNoZXIuc3RyZWFtLnB1Ymxpc2goKTtcbiAgICB9XG5cbiAgICB1bnB1Ymxpc2gocHVibGlzaGVyOiBQdWJsaXNoZXIpIHtcbiAgICAgICAgdGhpcy5zZXNzaW9uLnVucHVibGlzaChwdWJsaXNoZXIuc3RyZWFtKTtcbiAgICB9XG5cbiAgICBvbihldmVudE5hbWU6IHN0cmluZywgY2FsbGJhY2spIHtcbiAgICAgICAgdGhpcy5zZXNzaW9uLmFkZEV2ZW50TGlzdGVuZXIoZXZlbnROYW1lLCBldmVudCA9PiB7XG4gICAgICAgICAgICBpZiAoZXZlbnQpIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJFdmVudCAnXCIgKyBldmVudE5hbWUgKyBcIicgdHJpZ2dlcmVkIGJ5ICdTZXNzaW9uJ1wiLCBldmVudCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIkV2ZW50ICdcIiArIGV2ZW50TmFtZSArIFwiJyB0cmlnZ2VyZWQgYnkgJ1Nlc3Npb24nXCIpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FsbGJhY2soZXZlbnQpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBvbmNlKGV2ZW50TmFtZTogc3RyaW5nLCBjYWxsYmFjaykge1xuICAgICAgICB0aGlzLnNlc3Npb24uYWRkT25jZUV2ZW50TGlzdGVuZXIoZXZlbnROYW1lLCBldmVudCA9PiB7XG4gICAgICAgICAgICBjYWxsYmFjayhldmVudCk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIG9mZihldmVudE5hbWU6IHN0cmluZywgZXZlbnRIYW5kbGVyKSB7XG4gICAgICAgIHRoaXMuc2Vzc2lvbi5yZW1vdmVMaXN0ZW5lcihldmVudE5hbWUsIGV2ZW50SGFuZGxlcik7XG4gICAgfVxuXG4gICAgc3Vic2NyaWJlKHN0cmVhbTogU3RyZWFtLCBodG1sSWQ6IHN0cmluZywgdmlkZW9PcHRpb25zOiBhbnkpOiBTdWJzY3JpYmVyO1xuICAgIHN1YnNjcmliZShzdHJlYW06IFN0cmVhbSwgaHRtbElkOiBzdHJpbmcpOiBTdWJzY3JpYmVyO1xuXG4gICAgc3Vic2NyaWJlKHBhcmFtMSwgcGFyYW0yLCBwYXJhbTM/KTogU3Vic2NyaWJlciB7XG4gICAgICAgIC8vIFN1YnNjcmlwdGlvblxuICAgICAgICB0aGlzLnNlc3Npb24uc3Vic2NyaWJlKHBhcmFtMSk7XG4gICAgICAgIGxldCBzdWJzY3JpYmVyID0gbmV3IFN1YnNjcmliZXIocGFyYW0xLCBwYXJhbTIpO1xuICAgICAgICBwYXJhbTEucGxheU9ubHlWaWRlbyhwYXJhbTIsIG51bGwpO1xuICAgICAgICByZXR1cm4gc3Vic2NyaWJlcjtcbiAgICB9XG5cbiAgICB1bnN1YnNjcmliZShzdWJzY3JpYmVyOiBTdWJzY3JpYmVyKSB7XG4gICAgICAgIHRoaXMuc2Vzc2lvbi51bnN1c2NyaWJlKHN1YnNjcmliZXIuc3RyZWFtKTtcbiAgICAgICAgc3Vic2NyaWJlci5zdHJlYW0ucmVtb3ZlVmlkZW8oKTtcbiAgICB9XG5cblxuXG5cbiAgICAvKiBTaG9ydGN1dCBldmVudCBBUEkgKi9cblxuICAgIG9uU3RyZWFtQ3JlYXRlZChjYWxsYmFjaykge1xuICAgICAgICB0aGlzLnNlc3Npb24uYWRkRXZlbnRMaXN0ZW5lcihcInN0cmVhbUNyZWF0ZWRcIiwgc3RyZWFtRXZlbnQgPT4ge1xuICAgICAgICAgICAgY2FsbGJhY2soc3RyZWFtRXZlbnQuc3RyZWFtKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgb25TdHJlYW1EZXN0cm95ZWQoY2FsbGJhY2spIHtcbiAgICAgICAgdGhpcy5zZXNzaW9uLmFkZEV2ZW50TGlzdGVuZXIoXCJzdHJlYW1EZXN0cm95ZWRcIiwgc3RyZWFtRXZlbnQgPT4ge1xuICAgICAgICAgICAgY2FsbGJhY2soc3RyZWFtRXZlbnQuc3RyZWFtKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgb25QYXJ0aWNpcGFudEpvaW5lZChjYWxsYmFjaykge1xuICAgICAgICB0aGlzLnNlc3Npb24uYWRkRXZlbnRMaXN0ZW5lcihcInBhcnRpY2lwYW50LWpvaW5lZFwiLCBwYXJ0aWNpcGFudEV2ZW50ID0+IHtcbiAgICAgICAgICAgIGNhbGxiYWNrKHBhcnRpY2lwYW50RXZlbnQuY29ubmVjdGlvbik7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIG9uUGFydGljaXBhbnRMZWZ0KGNhbGxiYWNrKSB7XG4gICAgICAgIHRoaXMuc2Vzc2lvbi5hZGRFdmVudExpc3RlbmVyKFwicGFydGljaXBhbnQtbGVmdFwiLCBwYXJ0aWNpcGFudEV2ZW50ID0+IHtcbiAgICAgICAgICAgIGNhbGxiYWNrKHBhcnRpY2lwYW50RXZlbnQuY29ubmVjdGlvbik7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIG9uUGFydGljaXBhbnRQdWJsaXNoZWQoY2FsbGJhY2spIHtcbiAgICAgICAgdGhpcy5zZXNzaW9uLmFkZEV2ZW50TGlzdGVuZXIoXCJwYXJ0aWNpcGFudC1wdWJsaXNoZWRcIiwgcGFydGljaXBhbnRFdmVudCA9PiB7XG4gICAgICAgICAgICBjYWxsYmFjayhwYXJ0aWNpcGFudEV2ZW50LmNvbm5lY3Rpb24pO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBvblBhcnRpY2lwYW50RXZpY3RlZChjYWxsYmFjaykge1xuICAgICAgICB0aGlzLnNlc3Npb24uYWRkRXZlbnRMaXN0ZW5lcihcInBhcnRpY2lwYW50LWV2aWN0ZWRcIiwgcGFydGljaXBhbnRFdmVudCA9PiB7XG4gICAgICAgICAgICBjYWxsYmFjayhwYXJ0aWNpcGFudEV2ZW50LmNvbm5lY3Rpb24pO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBvblJvb21DbG9zZWQoY2FsbGJhY2spIHtcbiAgICAgICAgdGhpcy5zZXNzaW9uLmFkZEV2ZW50TGlzdGVuZXIoXCJyb29tLWNsb3NlZFwiLCByb29tRXZlbnQgPT4ge1xuICAgICAgICAgICAgY2FsbGJhY2socm9vbUV2ZW50LnJvb20pO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBvbkxvc3RDb25uZWN0aW9uKGNhbGxiYWNrKSB7XG4gICAgICAgIHRoaXMuc2Vzc2lvbi5hZGRFdmVudExpc3RlbmVyKFwibG9zdC1jb25uZWN0aW9uXCIsIHJvb21FdmVudCA9PiB7XG4gICAgICAgICAgICBjYWxsYmFjayhyb29tRXZlbnQucm9vbSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIG9uTWVkaWFFcnJvcihjYWxsYmFjaykge1xuICAgICAgICB0aGlzLnNlc3Npb24uYWRkRXZlbnRMaXN0ZW5lcihcImVycm9yLW1lZGlhXCIsIGVycm9yRXZlbnQgPT4ge1xuICAgICAgICAgICAgY2FsbGJhY2soZXJyb3JFdmVudC5lcnJvcilcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyogU2hvcnRjdXQgZXZlbnQgQVBJICovXG59XG4iLCJpbXBvcnQgeyBTdHJlYW0sIFN0cmVhbU9wdGlvbnMsIFZpZGVvT3B0aW9ucyB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvU3RyZWFtJztcblxuaW1wb3J0IEV2ZW50RW1pdHRlciA9IHJlcXVpcmUoJ3dvbGZ5ODctZXZlbnRlbWl0dGVyJyk7XG5cbmV4cG9ydCBjbGFzcyBTdWJzY3JpYmVyIHtcblxuICAgIHByaXZhdGUgZWUgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG5cbiAgICBlbGVtZW50OiBFbGVtZW50O1xuICAgIGlkOiBzdHJpbmc7XG4gICAgc3RyZWFtOiBTdHJlYW07XG5cbiAgICBjb25zdHJ1Y3RvcihzdHJlYW06IFN0cmVhbSwgcGFyZW50SWQ6IHN0cmluZykge1xuICAgICAgICB0aGlzLnN0cmVhbSA9IHN0cmVhbTtcbiAgICAgICAgaWYgKGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKHBhcmVudElkKSAhPSBudWxsKSB7XG4gICAgICAgICAgICB0aGlzLmVsZW1lbnQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChwYXJlbnRJZCkhITtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIG9uKGV2ZW50TmFtZTogc3RyaW5nLCBjYWxsYmFjaykge1xuICAgICAgICB0aGlzLmVlLmFkZExpc3RlbmVyKGV2ZW50TmFtZSwgZXZlbnQgPT4ge1xuICAgICAgICAgICAgaWYgKGV2ZW50KSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKFwiRXZlbnQgJ1wiICsgZXZlbnROYW1lICsgXCInIHRyaWdnZXJlZCBieSAnU3Vic2NyaWJlcidcIiwgZXZlbnQpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJFdmVudCAnXCIgKyBldmVudE5hbWUgKyBcIicgdHJpZ2dlcmVkIGJ5ICdTdWJzY3JpYmVyJ1wiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhbGxiYWNrKGV2ZW50KTtcbiAgICAgICAgfSk7XG4gICAgICAgIGlmIChldmVudE5hbWUgPT0gJ3ZpZGVvRWxlbWVudENyZWF0ZWQnKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uaXNWaWRlb0VMZW1lbnRDcmVhdGVkKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3ZpZGVvRWxlbWVudENyZWF0ZWQnLCBbe1xuICAgICAgICAgICAgICAgICAgICBlbGVtZW50OiB0aGlzLnN0cmVhbS5nZXRWaWRlb0VsZW1lbnQoKVxuICAgICAgICAgICAgICAgIH1dKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uYWRkT25jZUV2ZW50TGlzdGVuZXIoJ3ZpZGVvLWVsZW1lbnQtY3JlYXRlZC1ieS1zdHJlYW0nLCBlbGVtZW50ID0+IHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS53YXJuKFwiU3Vic2NyaWJlciBlbWl0dGluZyB2aWRlb0VsZW1lbnRDcmVhdGVkXCIpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmlkID0gZWxlbWVudC5pZDtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3ZpZGVvRWxlbWVudENyZWF0ZWQnLCBbe1xuICAgICAgICAgICAgICAgICAgICAgICAgZWxlbWVudDogZWxlbWVudFxuICAgICAgICAgICAgICAgICAgICB9XSk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGV2ZW50TmFtZSA9PSAndmlkZW9QbGF5aW5nJykge1xuICAgICAgICAgICAgdmFyIHZpZGVvID0gdGhpcy5zdHJlYW0uZ2V0VmlkZW9FbGVtZW50KCk7XG4gICAgICAgICAgICBpZiAoIXRoaXMuc3RyZWFtLmRpc3BsYXlNeVJlbW90ZSgpICYmIHZpZGVvICYmXG4gICAgICAgICAgICAgICAgdmlkZW8uY3VycmVudFRpbWUgPiAwICYmIFxuICAgICAgICAgICAgICAgIHZpZGVvLnBhdXNlZCA9PSBmYWxzZSAmJiBcbiAgICAgICAgICAgICAgICB2aWRlby5lbmRlZCA9PSBmYWxzZSAmJlxuICAgICAgICAgICAgICAgIHZpZGVvLnJlYWR5U3RhdGUgPT0gNCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgndmlkZW9QbGF5aW5nJywgW3tcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnQ6IHRoaXMuc3RyZWFtLmdldFZpZGVvRWxlbWVudCgpXG4gICAgICAgICAgICAgICAgICAgIH1dKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uYWRkT25jZUV2ZW50TGlzdGVuZXIoJ3ZpZGVvLWlzLXBsYXlpbmcnLCAoZWxlbWVudCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgndmlkZW9QbGF5aW5nJywgW3tcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnQ6IGVsZW1lbnQuZWxlbWVudFxuICAgICAgICAgICAgICAgICAgICB9XSk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG59IiwiaW1wb3J0IHsgU3RyZWFtLCBTdHJlYW1PcHRpb25zIH0gZnJvbSAnLi9TdHJlYW0nO1xuaW1wb3J0IHsgT3BlblZpZHVJbnRlcm5hbCB9IGZyb20gJy4vT3BlblZpZHVJbnRlcm5hbCc7XG5pbXBvcnQgeyBTZXNzaW9uSW50ZXJuYWwgfSBmcm9tICcuL1Nlc3Npb25JbnRlcm5hbCc7XG5cbnR5cGUgT2JqTWFwPFQ+ID0geyBbczogc3RyaW5nXTogVDsgfVxuXG5leHBvcnQgaW50ZXJmYWNlIENvbm5lY3Rpb25PcHRpb25zIHtcbiAgICBpZDogc3RyaW5nO1xuICAgIG1ldGFkYXRhOiBzdHJpbmc7XG4gICAgc3RyZWFtcz86IFN0cmVhbU9wdGlvbnNbXTtcbiAgICBhdWRpb0FjdGl2ZTogYm9vbGVhbjtcbiAgICB2aWRlb0FjdGl2ZTogYm9vbGVhbjtcbn1cblxuZXhwb3J0IGNsYXNzIENvbm5lY3Rpb24ge1xuXG4gICAgcHVibGljIGNvbm5lY3Rpb25JZDogc3RyaW5nO1xuICAgIHB1YmxpYyBkYXRhOiBzdHJpbmc7XG4gICAgcHVibGljIGNyZWF0aW9uVGltZTogbnVtYmVyO1xuICAgIHByaXZhdGUgc3RyZWFtczogT2JqTWFwPFN0cmVhbT4gPSB7fTtcbiAgICBwcml2YXRlIHN0cmVhbXNPcHRzOiBTdHJlYW1PcHRpb25zW10gPSBbXTtcblxuICAgIGNvbnN0cnVjdG9yKCBwcml2YXRlIG9wZW5WaWR1OiBPcGVuVmlkdUludGVybmFsLCBwcml2YXRlIGxvY2FsOiBib29sZWFuLCBwcml2YXRlIHJvb206IFNlc3Npb25JbnRlcm5hbCwgcHJpdmF0ZSBvcHRpb25zPzogQ29ubmVjdGlvbk9wdGlvbnMgKSB7XG5cbiAgICAgICAgY29uc29sZS5pbmZvKCBcIidDb25uZWN0aW9uJyBjcmVhdGVkIChcIiArICggbG9jYWwgPyBcImxvY2FsXCIgOiBcInJlbW90ZVwiICkgKyBcIilcIiArICggbG9jYWwgPyBcIlwiIDogXCIsIHdpdGggJ2Nvbm5lY3Rpb25JZCcgW1wiICsgKG9wdGlvbnMgPyBvcHRpb25zLmlkIDogJycpICsgXCJdIFwiICkpO1xuXG4gICAgICAgIGlmICggb3B0aW9ucyApIHtcblxuICAgICAgICAgICAgdGhpcy5jb25uZWN0aW9uSWQgPSBvcHRpb25zLmlkO1xuICAgICAgICAgICAgdGhpcy5kYXRhID0gb3B0aW9ucy5tZXRhZGF0YTtcblxuICAgICAgICAgICAgaWYgKCBvcHRpb25zLnN0cmVhbXMgKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5pbml0U3RyZWFtcyhvcHRpb25zKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBcbiAgICB9XG5cbiAgICBhZGRTdHJlYW0oIHN0cmVhbTogU3RyZWFtICkge1xuICAgICAgICB0aGlzLnN0cmVhbXNbc3RyZWFtLmdldElkSW5QYXJ0aWNpcGFudCgpXSA9IHN0cmVhbTtcbiAgICAgICAgdGhpcy5yb29tLmdldFN0cmVhbXMoKVtzdHJlYW0uZ2V0SWRJblBhcnRpY2lwYW50KCldID0gc3RyZWFtO1xuICAgIH1cblxuICAgIGdldFN0cmVhbXMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnN0cmVhbXM7XG4gICAgfVxuXG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgZm9yICggbGV0IGtleSBpbiB0aGlzLnN0cmVhbXMgKSB7XG4gICAgICAgICAgICB0aGlzLnN0cmVhbXNba2V5XS5kaXNwb3NlKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBzZW5kSWNlQ2FuZGlkYXRlKCBjYW5kaWRhdGUgKSB7XG5cbiAgICAgICAgY29uc29sZS5kZWJ1ZygoIHRoaXMubG9jYWwgPyBcIkxvY2FsXCIgOiBcIlJlbW90ZVwiICksIFwiY2FuZGlkYXRlIGZvclwiLFxuICAgICAgICAgICAgdGhpcy5jb25uZWN0aW9uSWQsIEpTT04uc3RyaW5naWZ5KCBjYW5kaWRhdGUgKSApO1xuXG4gICAgICAgIHRoaXMub3BlblZpZHUuc2VuZFJlcXVlc3QoIFwib25JY2VDYW5kaWRhdGVcIiwge1xuICAgICAgICAgICAgZW5kcG9pbnROYW1lOiB0aGlzLmNvbm5lY3Rpb25JZCxcbiAgICAgICAgICAgIGNhbmRpZGF0ZTogY2FuZGlkYXRlLmNhbmRpZGF0ZSxcbiAgICAgICAgICAgIHNkcE1pZDogY2FuZGlkYXRlLnNkcE1pZCxcbiAgICAgICAgICAgIHNkcE1MaW5lSW5kZXg6IGNhbmRpZGF0ZS5zZHBNTGluZUluZGV4XG4gICAgICAgIH0sIGZ1bmN0aW9uKCBlcnJvciwgcmVzcG9uc2UgKSB7XG4gICAgICAgICAgICBpZiAoIGVycm9yICkge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoIFwiRXJyb3Igc2VuZGluZyBJQ0UgY2FuZGlkYXRlOiBcIlxuICAgICAgICAgICAgICAgICAgICArIEpTT04uc3RyaW5naWZ5KCBlcnJvciApICk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIGluaXRTdHJlYW1zKG9wdGlvbnMpIHtcbiAgICAgICAgZm9yICggbGV0IHN0cmVhbU9wdGlvbnMgb2Ygb3B0aW9ucy5zdHJlYW1zICkge1xuICAgICAgICAgICAgXG4gICAgICAgICAgICBsZXQgc3RyZWFtT3B0cyA9IHtcbiAgICAgICAgICAgICAgICBpZDogc3RyZWFtT3B0aW9ucy5pZCxcbiAgICAgICAgICAgICAgICBjb25uZWN0aW9uOiB0aGlzLFxuICAgICAgICAgICAgICAgIHNlbmRBdWRpbzogc3RyZWFtT3B0aW9ucy5zZW5kQXVkaW8sXG4gICAgICAgICAgICAgICAgc2VuZFZpZGVvOiBzdHJlYW1PcHRpb25zLnNlbmRWaWRlbyxcbiAgICAgICAgICAgICAgICByZWN2QXVkaW86ICggc3RyZWFtT3B0aW9ucy5hdWRpb0FjdGl2ZSA9PSB1bmRlZmluZWQgPyB0cnVlIDogc3RyZWFtT3B0aW9ucy5hdWRpb0FjdGl2ZSApLFxuICAgICAgICAgICAgICAgIHJlY3ZWaWRlbzogKCBzdHJlYW1PcHRpb25zLnZpZGVvQWN0aXZlID09IHVuZGVmaW5lZCA/IHRydWUgOiBzdHJlYW1PcHRpb25zLnZpZGVvQWN0aXZlICksXG4gICAgICAgICAgICAgICAgYWN0aXZlQXVkaW86IHN0cmVhbU9wdGlvbnMuYWN0aXZlQXVkaW8sXG4gICAgICAgICAgICAgICAgYWN0aXZlVmlkZW86IHN0cmVhbU9wdGlvbnMuYWN0aXZlVmlkZW8sXG4gICAgICAgICAgICAgICAgZGF0YTogc3RyZWFtT3B0aW9ucy5kYXRhLFxuICAgICAgICAgICAgICAgIG1lZGlhQ29uc3RyYWludHM6IHN0cmVhbU9wdGlvbnMubWVkaWFDb25zdHJhaW50c1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbGV0IHN0cmVhbSA9IG5ldyBTdHJlYW0odGhpcy5vcGVuVmlkdSwgZmFsc2UsIHRoaXMucm9vbSwgc3RyZWFtT3B0cyApO1xuXG4gICAgICAgICAgICB0aGlzLmFkZFN0cmVhbSggc3RyZWFtICk7XG4gICAgICAgICAgICB0aGlzLnN0cmVhbXNPcHRzLnB1c2goIHN0cmVhbU9wdHMgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnNvbGUuaW5mbyhcIlJlbW90ZSAnQ29ubmVjdGlvbicgd2l0aCAnY29ubmVjdGlvbklkJyBbXCIgKyB0aGlzLmNvbm5lY3Rpb25JZCArIFwiXSBpcyBub3cgY29uZmlndXJlZCBmb3IgcmVjZWl2aW5nIFN0cmVhbXMgd2l0aCBvcHRpb25zOiBcIiwgdGhpcy5zdHJlYW1zT3B0cyApO1xuICAgIH1cbn0iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3IE9wZW5WaWR1IChodHRwOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5pbXBvcnQgeyBTZXNzaW9uSW50ZXJuYWwsIFNlc3Npb25PcHRpb25zIH0gZnJvbSAnLi9TZXNzaW9uSW50ZXJuYWwnO1xuaW1wb3J0IHsgU3RyZWFtIH0gZnJvbSAnLi9TdHJlYW0nO1xuaW1wb3J0ICogYXMgUnBjQnVpbGRlciBmcm9tICcuLi9LdXJlbnRvVXRpbHMva3VyZW50by1qc29ucnBjJztcblxuZXhwb3J0IHR5cGUgQ2FsbGJhY2s8VD4gPSAoZXJyb3I/OiBhbnksIG9wZW5WaWR1PzogVCkgPT4gdm9pZDtcblxuZXhwb3J0IGNsYXNzIE9wZW5WaWR1SW50ZXJuYWwge1xuXG4gICAgcHJpdmF0ZSB3c1VyaTtcbiAgICBwcml2YXRlIHNlc3Npb246IFNlc3Npb25JbnRlcm5hbDtcbiAgICBwcml2YXRlIGpzb25ScGNDbGllbnQ6IGFueTtcbiAgICBwcml2YXRlIHJwY1BhcmFtczogYW55O1xuICAgIHByaXZhdGUgY2FsbGJhY2s6IENhbGxiYWNrPE9wZW5WaWR1SW50ZXJuYWw+O1xuICAgIHByaXZhdGUgY2FtZXJhOiBTdHJlYW07XG4gICAgcHJpdmF0ZSByZW1vdGVTdHJlYW1zOiBTdHJlYW1bXSA9IFtdO1xuXG4gICAgcHJpdmF0ZSBzZWNyZXQ6IHN0cmluZztcblxuICAgIGNvbnN0cnVjdG9yKCkgeyB9O1xuXG5cbiAgICAvKiBORVcgTUVUSE9EUyAqL1xuICAgIGluaXRTZXNzaW9uKHNlc3Npb25JZCkge1xuICAgICAgICBjb25zb2xlLmluZm8oXCInU2Vzc2lvbicgaW5pdGlhbGl6ZWQgd2l0aCAnc2Vzc2lvbklkJyBbXCIgKyBzZXNzaW9uSWQgKyBcIl1cIik7XG4gICAgICAgIHRoaXMuc2Vzc2lvbiA9IG5ldyBTZXNzaW9uSW50ZXJuYWwodGhpcywgc2Vzc2lvbklkKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuc2Vzc2lvbjtcbiAgICB9XG5cbiAgICBpbml0UHVibGlzaGVyVGFnZ2VkKHBhcmVudElkOiBzdHJpbmcsIGNhbWVyYU9wdGlvbnM6IGFueSwgY2FsbGJhY2s/KSB7XG5cbiAgICAgICAgdGhpcy5nZXRDYW1lcmEoY2FtZXJhT3B0aW9ucyk7XG5cbiAgICAgICAgaWYgKGNhbGxiYWNrID09IG51bGwpIHtcbiAgICAgICAgICAgIHRoaXMuY2FtZXJhLnJlcXVlc3RDYW1lcmFBY2Nlc3MoKGVycm9yLCBjYW1lcmEpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihcIkVycm9yIGFjY2Vzc2luZyB0aGUgY2FtZXJhXCIsIGVycm9yKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY2FtZXJhLnNldFZpZGVvRWxlbWVudCh0aGlzLmNhbWVyYVJlYWR5KGNhbWVyYSEsIHBhcmVudElkKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5jYW1lcmE7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmNhbWVyYS5yZXF1ZXN0Q2FtZXJhQWNjZXNzKChlcnJvciwgY2FtZXJhKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrKGVycm9yKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY2FtZXJhLnNldFZpZGVvRWxlbWVudCh0aGlzLmNhbWVyYVJlYWR5KGNhbWVyYSEsIHBhcmVudElkKSk7XG4gICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrKHVuZGVmaW5lZCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5jYW1lcmE7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBjYW1lcmFSZWFkeShjYW1lcmE6IFN0cmVhbSwgcGFyZW50SWQ6IHN0cmluZykge1xuICAgICAgICB0aGlzLmNhbWVyYSA9IGNhbWVyYTtcbiAgICAgICAgbGV0IHZpZGVvRWxlbWVudCA9IHRoaXMuY2FtZXJhLnBsYXlPbmx5VmlkZW8ocGFyZW50SWQsIG51bGwpO1xuICAgICAgICB0aGlzLmNhbWVyYS5lbWl0U3RyZWFtUmVhZHlFdmVudCgpO1xuICAgICAgICByZXR1cm4gdmlkZW9FbGVtZW50O1xuICAgIH1cblxuICAgIGluaXRQdWJsaXNoZXIoY2FtZXJhT3B0aW9uczogYW55LCBjYWxsYmFjaykge1xuICAgICAgICB0aGlzLmdldENhbWVyYShjYW1lcmFPcHRpb25zKTtcbiAgICAgICAgdGhpcy5jYW1lcmEucmVxdWVzdENhbWVyYUFjY2VzcygoZXJyb3IsIGNhbWVyYSkgPT4ge1xuICAgICAgICAgICAgaWYgKGVycm9yKSBjYWxsYmFjayhlcnJvcik7XG4gICAgICAgICAgICBlbHNlIGNhbGxiYWNrKHVuZGVmaW5lZCk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIGdldExvY2FsU3RyZWFtKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5jYW1lcmE7XG4gICAgfVxuXG4gICAgZ2V0UmVtb3RlU3RyZWFtcygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucmVtb3RlU3RyZWFtcztcbiAgICB9XG4gICAgLyogTkVXIE1FVEhPRFMgKi9cblxuICAgIGdldFdzVXJpKCkge1xuICAgICAgICByZXR1cm4gdGhpcy53c1VyaTtcbiAgICB9XG5cbiAgICBzZXRXc1VyaSh3c1VyaTogc3RyaW5nKSB7XG4gICAgICAgIHRoaXMud3NVcmkgPSB3c1VyaTtcbiAgICB9XG5cbiAgICBnZXRTZWNyZXQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnNlY3JldDtcbiAgICB9XG5cbiAgICBzZXRTZWNyZXQoc2VjcmV0OiBzdHJpbmcpIHtcbiAgICAgICAgdGhpcy5zZWNyZXQgPSBzZWNyZXQ7XG4gICAgfVxuXG4gICAgZ2V0T3BlblZpZHVTZXJ2ZXJVUkwoKSB7XG4gICAgICAgIHJldHVybiAnaHR0cHM6Ly8nICsgdGhpcy53c1VyaS5zcGxpdChcIndzczovL1wiKVsxXS5zcGxpdChcIi9yb29tXCIpWzBdO1xuICAgIH1cblxuICAgIGdldFJvb20oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnNlc3Npb247XG4gICAgfVxuXG4gICAgY29ubmVjdChjYWxsYmFjazogQ2FsbGJhY2s8T3BlblZpZHVJbnRlcm5hbD4pOiB2b2lkIHtcblxuICAgICAgICB0aGlzLmNhbGxiYWNrID0gY2FsbGJhY2s7XG5cbiAgICAgICAgdGhpcy5pbml0SnNvblJwY0NsaWVudCh0aGlzLndzVXJpKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGluaXRKc29uUnBjQ2xpZW50KHdzVXJpOiBzdHJpbmcpOiB2b2lkIHtcblxuICAgICAgICBsZXQgY29uZmlnID0ge1xuICAgICAgICAgICAgaGVhcnRiZWF0OiAzMDAwLFxuICAgICAgICAgICAgc2VuZENsb3NlTWVzc2FnZTogZmFsc2UsXG4gICAgICAgICAgICB3czoge1xuICAgICAgICAgICAgICAgIHVyaTogd3NVcmksXG4gICAgICAgICAgICAgICAgdXNlU29ja0pTOiBmYWxzZSxcbiAgICAgICAgICAgICAgICBvbmNvbm5lY3RlZDogdGhpcy5jb25uZWN0Q2FsbGJhY2suYmluZCh0aGlzKSxcbiAgICAgICAgICAgICAgICBvbmRpc2Nvbm5lY3Q6IHRoaXMuZGlzY29ubmVjdENhbGxiYWNrLmJpbmQodGhpcyksXG4gICAgICAgICAgICAgICAgb25yZWNvbm5lY3Rpbmc6IHRoaXMucmVjb25uZWN0aW5nQ2FsbGJhY2suYmluZCh0aGlzKSxcbiAgICAgICAgICAgICAgICBvbnJlY29ubmVjdGVkOiB0aGlzLnJlY29ubmVjdGVkQ2FsbGJhY2suYmluZCh0aGlzKVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHJwYzoge1xuICAgICAgICAgICAgICAgIHJlcXVlc3RUaW1lb3V0OiAxNTAwMCxcbiAgICAgICAgICAgICAgICAvL25vdGlmaWNhdGlvbnNcbiAgICAgICAgICAgICAgICBwYXJ0aWNpcGFudEpvaW5lZDogdGhpcy5vblBhcnRpY2lwYW50Sm9pbmVkLmJpbmQodGhpcyksXG4gICAgICAgICAgICAgICAgcGFydGljaXBhbnRQdWJsaXNoZWQ6IHRoaXMub25QYXJ0aWNpcGFudFB1Ymxpc2hlZC5iaW5kKHRoaXMpLFxuICAgICAgICAgICAgICAgIHBhcnRpY2lwYW50VW5wdWJsaXNoZWQ6IHRoaXMub25QYXJ0aWNpcGFudExlZnQuYmluZCh0aGlzKSxcbiAgICAgICAgICAgICAgICBwYXJ0aWNpcGFudExlZnQ6IHRoaXMub25QYXJ0aWNpcGFudExlZnQuYmluZCh0aGlzKSxcbiAgICAgICAgICAgICAgICBwYXJ0aWNpcGFudEV2aWN0ZWQ6IHRoaXMub25QYXJ0aWNpcGFudEV2aWN0ZWQuYmluZCh0aGlzKSxcbiAgICAgICAgICAgICAgICBzZW5kTWVzc2FnZTogdGhpcy5vbk5ld01lc3NhZ2UuYmluZCh0aGlzKSxcbiAgICAgICAgICAgICAgICBpY2VDYW5kaWRhdGU6IHRoaXMuaWNlQ2FuZGlkYXRlRXZlbnQuYmluZCh0aGlzKSxcbiAgICAgICAgICAgICAgICBtZWRpYUVycm9yOiB0aGlzLm9uTWVkaWFFcnJvci5iaW5kKHRoaXMpLFxuICAgICAgICAgICAgICAgIGN1c3Rvbk5vdGlmaWNhdGlvbjogdGhpcy5jdXN0b21Ob3RpZmljYXRpb24uYmluZCh0aGlzKVxuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuXG4gICAgICAgIHRoaXMuanNvblJwY0NsaWVudCA9IG5ldyBScGNCdWlsZGVyLmNsaWVudHMuSnNvblJwY0NsaWVudChjb25maWcpO1xuICAgIH1cblxuXG4gICAgcHJpdmF0ZSBjdXN0b21Ob3RpZmljYXRpb24ocGFyYW1zKSB7XG4gICAgICAgIGlmICh0aGlzLmlzUm9vbUF2YWlsYWJsZSgpKSB7XG4gICAgICAgICAgICB0aGlzLnNlc3Npb24uZW1pdEV2ZW50KFwiY3VzdG9tLW1lc3NhZ2UtcmVjZWl2ZWRcIiwgW3sgcGFyYW1zOiBwYXJhbXMgfV0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBjb25uZWN0Q2FsbGJhY2soZXJyb3IpIHtcbiAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICB0aGlzLmNhbGxiYWNrKGVycm9yKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuY2FsbGJhY2sobnVsbCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGlzUm9vbUF2YWlsYWJsZSgpIHtcbiAgICAgICAgaWYgKHRoaXMuc2Vzc2lvbiAhPT0gdW5kZWZpbmVkICYmIHRoaXMuc2Vzc2lvbiBpbnN0YW5jZW9mIFNlc3Npb25JbnRlcm5hbCkge1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zb2xlLndhcm4oJ1Jvb20gaW5zdGFuY2Ugbm90IGZvdW5kJyk7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGRpc2Nvbm5lY3RDYWxsYmFjaygpIHtcbiAgICAgICAgY29uc29sZS53YXJuKCdXZWJzb2NrZXQgY29ubmVjdGlvbiBsb3N0Jyk7XG4gICAgICAgIGlmICh0aGlzLmlzUm9vbUF2YWlsYWJsZSgpKSB7XG4gICAgICAgICAgICB0aGlzLnNlc3Npb24ub25Mb3N0Q29ubmVjdGlvbigpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgYWxlcnQoJ0Nvbm5lY3Rpb24gZXJyb3IuIFBsZWFzZSByZWxvYWQgcGFnZS4nKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgcmVjb25uZWN0aW5nQ2FsbGJhY2soKSB7XG4gICAgICAgIGNvbnNvbGUud2FybignV2Vic29ja2V0IGNvbm5lY3Rpb24gbG9zdCAocmVjb25uZWN0aW5nKScpO1xuICAgICAgICBpZiAodGhpcy5pc1Jvb21BdmFpbGFibGUoKSkge1xuICAgICAgICAgICAgdGhpcy5zZXNzaW9uLm9uTG9zdENvbm5lY3Rpb24oKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGFsZXJ0KCdDb25uZWN0aW9uIGVycm9yLiBQbGVhc2UgcmVsb2FkIHBhZ2UuJyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIHJlY29ubmVjdGVkQ2FsbGJhY2soKSB7XG4gICAgICAgIGNvbnNvbGUud2FybignV2Vic29ja2V0IHJlY29ubmVjdGVkJyk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBvblBhcnRpY2lwYW50Sm9pbmVkKHBhcmFtcykge1xuICAgICAgICBpZiAodGhpcy5pc1Jvb21BdmFpbGFibGUoKSkge1xuICAgICAgICAgICAgdGhpcy5zZXNzaW9uLm9uUGFydGljaXBhbnRKb2luZWQocGFyYW1zKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgb25QYXJ0aWNpcGFudFB1Ymxpc2hlZChwYXJhbXMpIHtcbiAgICAgICAgaWYgKHRoaXMuaXNSb29tQXZhaWxhYmxlKCkpIHtcbiAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5vblBhcnRpY2lwYW50UHVibGlzaGVkKHBhcmFtcyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIG9uUGFydGljaXBhbnRMZWZ0KHBhcmFtcykge1xuICAgICAgICBpZiAodGhpcy5pc1Jvb21BdmFpbGFibGUoKSkge1xuICAgICAgICAgICAgdGhpcy5zZXNzaW9uLm9uUGFydGljaXBhbnRMZWZ0KHBhcmFtcyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIG9uUGFydGljaXBhbnRFdmljdGVkKHBhcmFtcykge1xuICAgICAgICBpZiAodGhpcy5pc1Jvb21BdmFpbGFibGUoKSkge1xuICAgICAgICAgICAgdGhpcy5zZXNzaW9uLm9uUGFydGljaXBhbnRFdmljdGVkKHBhcmFtcyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIG9uTmV3TWVzc2FnZShwYXJhbXMpIHtcbiAgICAgICAgaWYgKHRoaXMuaXNSb29tQXZhaWxhYmxlKCkpIHtcbiAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5vbk5ld01lc3NhZ2UocGFyYW1zKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgaWNlQ2FuZGlkYXRlRXZlbnQocGFyYW1zKSB7XG4gICAgICAgIGlmICh0aGlzLmlzUm9vbUF2YWlsYWJsZSgpKSB7XG4gICAgICAgICAgICB0aGlzLnNlc3Npb24ucmVjdkljZUNhbmRpZGF0ZShwYXJhbXMpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBvblJvb21DbG9zZWQocGFyYW1zKSB7XG4gICAgICAgIGlmICh0aGlzLmlzUm9vbUF2YWlsYWJsZSgpKSB7XG4gICAgICAgICAgICB0aGlzLnNlc3Npb24ub25Sb29tQ2xvc2VkKHBhcmFtcyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIG9uTWVkaWFFcnJvcihwYXJhbXMpIHtcbiAgICAgICAgaWYgKHRoaXMuaXNSb29tQXZhaWxhYmxlKCkpIHtcbiAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5vbk1lZGlhRXJyb3IocGFyYW1zKTtcbiAgICAgICAgfVxuICAgIH1cblxuXG4gICAgc2V0UnBjUGFyYW1zKHBhcmFtczogYW55KSB7XG4gICAgICAgIHRoaXMucnBjUGFyYW1zID0gcGFyYW1zO1xuICAgIH1cblxuICAgIHNlbmRSZXF1ZXN0KG1ldGhvZCwgcGFyYW1zLCBjYWxsYmFjaz8pIHtcblxuICAgICAgICBpZiAocGFyYW1zICYmIHBhcmFtcyBpbnN0YW5jZW9mIEZ1bmN0aW9uKSB7XG4gICAgICAgICAgICBjYWxsYmFjayA9IHBhcmFtcztcbiAgICAgICAgICAgIHBhcmFtcyA9IHVuZGVmaW5lZDtcbiAgICAgICAgfVxuXG4gICAgICAgIHBhcmFtcyA9IHBhcmFtcyB8fCB7fTtcblxuICAgICAgICBpZiAodGhpcy5ycGNQYXJhbXMgJiYgdGhpcy5ycGNQYXJhbXMgIT09IG51bGwgJiYgdGhpcy5ycGNQYXJhbXMgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgZm9yIChsZXQgaW5kZXggaW4gdGhpcy5ycGNQYXJhbXMpIHtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5ycGNQYXJhbXMuaGFzT3duUHJvcGVydHkoaW5kZXgpKSB7XG4gICAgICAgICAgICAgICAgICAgIHBhcmFtc1tpbmRleF0gPSB0aGlzLnJwY1BhcmFtc1tpbmRleF07XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZGVidWcoJ1JQQyBwYXJhbSBhZGRlZCB0byByZXF1ZXN0IHsnICsgaW5kZXggKyAnOiAnICsgdGhpcy5ycGNQYXJhbXNbaW5kZXhdICsgJ30nKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBjb25zb2xlLmRlYnVnKCdTZW5kaW5nIHJlcXVlc3Q6IHttZXRob2Q6XCInICsgbWV0aG9kICsgJ1wiLCBwYXJhbXM6ICcgKyBKU09OLnN0cmluZ2lmeShwYXJhbXMpICsgJ30nKTtcblxuICAgICAgICB0aGlzLmpzb25ScGNDbGllbnQuc2VuZChtZXRob2QsIHBhcmFtcywgY2FsbGJhY2spO1xuICAgIH1cblxuICAgIGNsb3NlKGZvcmNlZCkge1xuICAgICAgICBpZiAodGhpcy5pc1Jvb21BdmFpbGFibGUoKSkge1xuICAgICAgICAgICAgdGhpcy5zZXNzaW9uLmxlYXZlKGZvcmNlZCwgdGhpcy5qc29uUnBjQ2xpZW50KTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICBkaXNjb25uZWN0UGFydGljaXBhbnQoc3RyZWFtKSB7XG4gICAgICAgIGlmICh0aGlzLmlzUm9vbUF2YWlsYWJsZSgpKSB7XG4gICAgICAgICAgICB0aGlzLnNlc3Npb24uZGlzY29ubmVjdChzdHJlYW0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZ2V0Q2FtZXJhKG9wdGlvbnM/KSB7XG5cbiAgICAgICAgaWYgKHRoaXMuY2FtZXJhKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5jYW1lcmE7XG4gICAgICAgIH1cblxuICAgICAgICBvcHRpb25zID0gb3B0aW9ucyB8fCB7XG4gICAgICAgICAgICBzZW5kQXVkaW86IHRydWUsXG4gICAgICAgICAgICBzZW5kVmlkZW86IHRydWUsXG4gICAgICAgICAgICBhY3RpdmVBdWRpbzogdHJ1ZSxcbiAgICAgICAgICAgIGFjdGl2ZVZpZGVvOiB0cnVlLFxuICAgICAgICAgICAgZGF0YTogdHJ1ZSxcbiAgICAgICAgICAgIG1lZGlhQ29uc3RyYWludHM6IHtcbiAgICAgICAgICAgICAgICBhdWRpbzogdHJ1ZSxcbiAgICAgICAgICAgICAgICB2aWRlbzogeyB3aWR0aDogeyBpZGVhbDogMTI4MCB9IH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBvcHRpb25zLmNvbm5lY3Rpb24gPSB0aGlzLnNlc3Npb24uZ2V0TG9jYWxQYXJ0aWNpcGFudCgpO1xuXG4gICAgICAgIHRoaXMuY2FtZXJhID0gbmV3IFN0cmVhbSh0aGlzLCB0cnVlLCB0aGlzLnNlc3Npb24sIG9wdGlvbnMpO1xuICAgICAgICByZXR1cm4gdGhpcy5jYW1lcmE7XG4gICAgfTtcblxuICAgIC8vQ0hBVFxuICAgIHNlbmRNZXNzYWdlKHJvb20sIHVzZXIsIG1lc3NhZ2UpIHtcbiAgICAgICAgdGhpcy5zZW5kUmVxdWVzdCgnc2VuZE1lc3NhZ2UnLCB7XG4gICAgICAgICAgICBtZXNzYWdlOiBtZXNzYWdlLFxuICAgICAgICAgICAgdXNlck1lc3NhZ2U6IHVzZXIsXG4gICAgICAgICAgICByb29tTWVzc2FnZTogcm9vbVxuICAgICAgICB9LCBmdW5jdGlvbiAoZXJyb3IsIHJlc3BvbnNlKSB7XG4gICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKGVycm9yKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfTtcblxuICAgIHNlbmRDdXN0b21SZXF1ZXN0KHBhcmFtcywgY2FsbGJhY2spIHtcbiAgICAgICAgdGhpcy5zZW5kUmVxdWVzdCgnY3VzdG9tUmVxdWVzdCcsIHBhcmFtcywgY2FsbGJhY2spO1xuICAgIH07XG5cblxuXG5cbiAgICB0b2dnbGVMb2NhbFZpZGVvVHJhY2soYWN0aXZhdGU6IGJvb2xlYW4pIHtcbiAgICAgICAgdGhpcy5nZXRDYW1lcmEoKS5nZXRXZWJSdGNQZWVyKCkudmlkZW9FbmFibGVkID0gYWN0aXZhdGU7XG4gICAgfVxuXG4gICAgdG9nZ2xlTG9jYWxBdWRpb1RyYWNrKGFjdGl2YXRlOiBib29sZWFuKSB7XG4gICAgICAgIHRoaXMuZ2V0Q2FtZXJhKCkuZ2V0V2ViUnRjUGVlcigpLmF1ZGlvRW5hYmxlZCA9IGFjdGl2YXRlO1xuICAgIH1cblxuICAgIHB1Ymxpc2hMb2NhbFZpZGVvQXVkaW8oKSB7XG4gICAgICAgIHRoaXMudG9nZ2xlTG9jYWxWaWRlb1RyYWNrKHRydWUpO1xuICAgICAgICB0aGlzLnRvZ2dsZUxvY2FsQXVkaW9UcmFjayh0cnVlKTtcbiAgICB9XG5cbiAgICB1bnB1Ymxpc2hMb2NhbFZpZGVvQXVkaW8oKSB7XG4gICAgICAgIHRoaXMudG9nZ2xlTG9jYWxWaWRlb1RyYWNrKGZhbHNlKTtcbiAgICAgICAgdGhpcy50b2dnbGVMb2NhbEF1ZGlvVHJhY2soZmFsc2UpO1xuICAgIH1cblxuICAgIGdlbmVyYXRlTWVkaWFDb25zdHJhaW50cyhjYW1lcmFPcHRpb25zOiBhbnkpIHtcbiAgICAgICAgbGV0IG1lZGlhQ29uc3RyYWludHMgPSB7XG4gICAgICAgICAgICBhdWRpbzogY2FtZXJhT3B0aW9ucy5hdWRpbyxcbiAgICAgICAgICAgIHZpZGVvOiB7fVxuICAgICAgICB9XG4gICAgICAgIGlmICghY2FtZXJhT3B0aW9ucy52aWRlbykge1xuICAgICAgICAgICAgbWVkaWFDb25zdHJhaW50cy52aWRlbyA9IGZhbHNlXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBsZXQgdywgaDtcbiAgICAgICAgICAgIHN3aXRjaCAoY2FtZXJhT3B0aW9ucy5xdWFsaXR5KSB7XG4gICAgICAgICAgICAgICAgY2FzZSAnTE9XJzpcbiAgICAgICAgICAgICAgICAgICAgdyA9IDMyMDtcbiAgICAgICAgICAgICAgICAgICAgaCA9IDI0MDtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSAnTUVESVVNJzpcbiAgICAgICAgICAgICAgICAgICAgdyA9IDY0MDtcbiAgICAgICAgICAgICAgICAgICAgaCA9IDQ4MDtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSAnSElHSCc6XG4gICAgICAgICAgICAgICAgICAgIHcgPSAxMjgwO1xuICAgICAgICAgICAgICAgICAgICBoID0gNzIwO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgICAgICB3ID0gNjQwO1xuICAgICAgICAgICAgICAgICAgICBoID0gNDgwO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbWVkaWFDb25zdHJhaW50cy52aWRlb1snd2lkdGgnXSA9IHsgZXhhY3Q6IHcgfTtcbiAgICAgICAgICAgIG1lZGlhQ29uc3RyYWludHMudmlkZW9bJ2hlaWdodCddID0geyBleGFjdDogaCB9O1xuICAgICAgICAgICAgLy9tZWRpYUNvbnN0cmFpbnRzLnZpZGVvWydmcmFtZVJhdGUnXSA9IHsgaWRlYWw6IE51bWJlcigoPEhUTUxJbnB1dEVsZW1lbnQ+ZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2ZyYW1lUmF0ZScpKS52YWx1ZSkgfTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbWVkaWFDb25zdHJhaW50cztcbiAgICB9XG5cbn1cbiIsImltcG9ydCB7IFN0cmVhbSB9IGZyb20gJy4vU3RyZWFtJztcbmltcG9ydCB7IE9wZW5WaWR1SW50ZXJuYWwgfSBmcm9tICcuL09wZW5WaWR1SW50ZXJuYWwnO1xuaW1wb3J0IHsgQ29ubmVjdGlvbiwgQ29ubmVjdGlvbk9wdGlvbnMgfSBmcm9tICcuL0Nvbm5lY3Rpb24nO1xuaW1wb3J0IEV2ZW50RW1pdHRlciA9IHJlcXVpcmUoJ3dvbGZ5ODctZXZlbnRlbWl0dGVyJyk7XG5cbmNvbnN0IFNFQ1JFVF9QQVJBTSA9ICc/c2VjcmV0PSc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgU2Vzc2lvbk9wdGlvbnMge1xuICAgIHNlc3Npb25JZDogc3RyaW5nO1xuICAgIHBhcnRpY2lwYW50SWQ6IHN0cmluZztcbiAgICBtZXRhZGF0YTogc3RyaW5nO1xuICAgIHN1YnNjcmliZVRvU3RyZWFtcz86IGJvb2xlYW47XG4gICAgdXBkYXRlU3BlYWtlckludGVydmFsPzogbnVtYmVyO1xuICAgIHRocmVzaG9sZFNwZWFrZXI/OiBudW1iZXI7XG59XG5cbmV4cG9ydCBjbGFzcyBTZXNzaW9uSW50ZXJuYWwge1xuXG4gICAgcHJpdmF0ZSBpZDogc3RyaW5nO1xuICAgIHByaXZhdGUgc2Vzc2lvbklkOiBzdHJpbmc7XG4gICAgcHJpdmF0ZSBlZSA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcbiAgICBwcml2YXRlIHN0cmVhbXMgPSB7fTtcbiAgICBwcml2YXRlIHBhcnRpY2lwYW50cyA9IHt9O1xuICAgIHByaXZhdGUgcGFydGljaXBhbnRzU3BlYWtpbmc6IENvbm5lY3Rpb25bXSA9IFtdO1xuICAgIHByaXZhdGUgY29ubmVjdGVkID0gZmFsc2U7XG4gICAgcHVibGljIGxvY2FsUGFydGljaXBhbnQ6IENvbm5lY3Rpb247XG4gICAgcHJpdmF0ZSBzdWJzY3JpYmVUb1N0cmVhbXM6IGJvb2xlYW47XG4gICAgcHJpdmF0ZSB1cGRhdGVTcGVha2VySW50ZXJ2YWw6IG51bWJlcjtcbiAgICBwdWJsaWMgdGhyZXNob2xkU3BlYWtlcjogbnVtYmVyO1xuICAgIHByaXZhdGUgb3B0aW9uczogU2Vzc2lvbk9wdGlvbnM7XG5cbiAgICBjb25zdHJ1Y3Rvcihwcml2YXRlIG9wZW5WaWR1OiBPcGVuVmlkdUludGVybmFsLCBzZXNzaW9uSWQ6IHN0cmluZykge1xuICAgICAgICB0aGlzLnNlc3Npb25JZCA9IHRoaXMuZ2V0VXJsV2l0aG91dFNlY3JldChzZXNzaW9uSWQpO1xuICAgICAgICB0aGlzLmxvY2FsUGFydGljaXBhbnQgPSBuZXcgQ29ubmVjdGlvbih0aGlzLm9wZW5WaWR1LCB0cnVlLCB0aGlzKTtcbiAgICAgICAgaWYgKCF0aGlzLm9wZW5WaWR1LmdldFdzVXJpKCkpIHtcbiAgICAgICAgICAgIHRoaXMucHJvY2Vzc09wZW5WaWR1VXJsKHNlc3Npb25JZCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIHByb2Nlc3NPcGVuVmlkdVVybCh1cmw6IHN0cmluZykge1xuICAgICAgICB0aGlzLm9wZW5WaWR1LnNldFNlY3JldCh0aGlzLmdldFNlY3JldEZyb21VcmwodXJsKSk7XG4gICAgICAgIHRoaXMub3BlblZpZHUuc2V0V3NVcmkodGhpcy5nZXRGaW5hbFVybCh1cmwpKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGdldFNlY3JldEZyb21VcmwodXJsOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgICAgICBsZXQgc2VjcmV0ID0gJyc7XG4gICAgICAgIGlmICh1cmwuaW5kZXhPZihTRUNSRVRfUEFSQU0pICE9PSAtMSkge1xuICAgICAgICAgICAgc2VjcmV0ID0gdXJsLnN1YnN0cmluZyh1cmwubGFzdEluZGV4T2YoU0VDUkVUX1BBUkFNKSArIFNFQ1JFVF9QQVJBTS5sZW5ndGgsIHVybC5sZW5ndGgpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBzZWNyZXQ7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnZXRVcmxXaXRob3V0U2VjcmV0KHVybDogc3RyaW5nKTogc3RyaW5nIHtcbiAgICAgICAgaWYgKHVybC5pbmRleE9mKFNFQ1JFVF9QQVJBTSkgIT09IC0xKSB7XG4gICAgICAgICAgICB1cmwgPSB1cmwuc3Vic3RyaW5nKDAsIHVybC5sYXN0SW5kZXhPZihTRUNSRVRfUEFSQU0pKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdXJsO1xuICAgIH1cblxuICAgIHByaXZhdGUgZ2V0RmluYWxVcmwodXJsOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgICAgICB1cmwgPSB0aGlzLmdldFVybFdpdGhvdXRTZWNyZXQodXJsKS5zdWJzdHJpbmcoMCwgdXJsLmxhc3RJbmRleE9mKCcvJykpICsgJy9yb29tJztcbiAgICAgICAgaWYgKHVybC5pbmRleE9mKFwiLm5ncm9rLmlvXCIpICE9PSAtMSkge1xuICAgICAgICAgICAgLy8gT3BlblZpZHUgc2VydmVyIFVSTCByZWZlcmVzIHRvIGEgbmdyb2sgSVA6IHNlY3VyZSB3c3MgcHJvdG9jb2wgYW5kIGRlbGV0ZSBwb3J0IG9mIFVSTFxuICAgICAgICAgICAgdXJsID0gdXJsLnJlcGxhY2UoXCJ3czovL1wiLCBcIndzczovL1wiKTtcbiAgICAgICAgICAgIGxldCByZWdleCA9IC9cXC5uZ3Jva1xcLmlvOlxcZCsvO1xuICAgICAgICAgICAgdXJsID0gdXJsLnJlcGxhY2UocmVnZXgsIFwiLm5ncm9rLmlvXCIpO1xuICAgICAgICB9IGVsc2UgaWYgKCh1cmwuaW5kZXhPZihcImxvY2FsaG9zdFwiKSAhPT0gLTEpIHx8ICh1cmwuaW5kZXhPZihcIjEyNy4wLjAuMVwiKSAhPSAtMSkpIHtcbiAgICAgICAgICAgIC8vIE9wZW5WaWR1IHNlcnZlciBVUkwgcmVmZXJlcyB0byBsb2NhbGhvc3QgSVBcblxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB1cmw7XG4gICAgfVxuXG5cblxuICAgIC8qIE5FVyBNRVRIT0RTICovXG4gICAgY29ubmVjdCh0b2tlbiwgY2FsbGJhY2spIHtcblxuICAgICAgICB0aGlzLm9wZW5WaWR1LmNvbm5lY3QoKGVycm9yKSA9PiB7XG4gICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICBjYWxsYmFjaygnRVJST1IgQ09OTkVDVElORyBUTyBPUEVOVklEVScpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG5cbiAgICAgICAgICAgICAgICBpZiAoIXRva2VuKSB7XG4gICAgICAgICAgICAgICAgICAgIHRva2VuID0gdGhpcy5yYW5kb21Ub2tlbigpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGxldCBqb2luUGFyYW1zID0ge1xuICAgICAgICAgICAgICAgICAgICB0b2tlbjogdG9rZW4sXG4gICAgICAgICAgICAgICAgICAgIHNlc3Npb246IHRoaXMuc2Vzc2lvbklkLFxuICAgICAgICAgICAgICAgICAgICBtZXRhZGF0YTogdGhpcy5vcHRpb25zLm1ldGFkYXRhLFxuICAgICAgICAgICAgICAgICAgICBzZWNyZXQ6IHRoaXMub3BlblZpZHUuZ2V0U2VjcmV0KCksXG4gICAgICAgICAgICAgICAgICAgIGRhdGFDaGFubmVsczogZmFsc2VcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBpZiAodGhpcy5sb2NhbFBhcnRpY2lwYW50KSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChPYmplY3Qua2V5cyh0aGlzLmxvY2FsUGFydGljaXBhbnQuZ2V0U3RyZWFtcygpKS5zb21lKHN0cmVhbUlkID0+XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbXNbc3RyZWFtSWRdLmlzRGF0YUNoYW5uZWxFbmFibGVkKCkpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBqb2luUGFyYW1zLmRhdGFDaGFubmVscyA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICB0aGlzLm9wZW5WaWR1LnNlbmRSZXF1ZXN0KCdqb2luUm9vbScsIGpvaW5QYXJhbXMsIChlcnJvciwgcmVzcG9uc2UpID0+IHtcblxuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrKGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcblxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jb25uZWN0ZWQgPSB0cnVlO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQgZXhQYXJ0aWNpcGFudHMgPSByZXNwb25zZS52YWx1ZTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gSU1QT1JUQU5UOiBVcGRhdGUgY29ubmVjdGlvbklkIHdpdGggdmFsdWUgc2VuZCBieSBzZXJ2ZXJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubG9jYWxQYXJ0aWNpcGFudC5jb25uZWN0aW9uSWQgPSByZXNwb25zZS5pZDtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucGFydGljaXBhbnRzW3Jlc3BvbnNlLmlkXSA9IHRoaXMubG9jYWxQYXJ0aWNpcGFudDtcblxuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IHJvb21FdmVudCA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJ0aWNpcGFudHM6IG5ldyBBcnJheTxDb25uZWN0aW9uPigpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmVhbXM6IG5ldyBBcnJheTxTdHJlYW0+KClcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGxlbmd0aCA9IGV4UGFydGljaXBhbnRzLmxlbmd0aDtcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBjb25uZWN0aW9uID0gbmV3IENvbm5lY3Rpb24odGhpcy5vcGVuVmlkdSwgZmFsc2UsIHRoaXMsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4UGFydGljaXBhbnRzW2ldKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25uZWN0aW9uLmNyZWF0aW9uVGltZSA9IG5ldyBEYXRlKCkuZ2V0VGltZSgpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5wYXJ0aWNpcGFudHNbY29ubmVjdGlvbi5jb25uZWN0aW9uSWRdID0gY29ubmVjdGlvbjtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJvb21FdmVudC5wYXJ0aWNpcGFudHMucHVzaChjb25uZWN0aW9uKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBzdHJlYW1zID0gY29ubmVjdGlvbi5nZXRTdHJlYW1zKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQga2V5IGluIHN0cmVhbXMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcm9vbUV2ZW50LnN0cmVhbXMucHVzaChzdHJlYW1zW2tleV0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5zdWJzY3JpYmVUb1N0cmVhbXMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmVhbXNba2V5XS5zdWJzY3JpYmUoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gVXBkYXRlIGxvY2FsIENvbm5lY3Rpb24gb2JqZWN0IHByb3BlcnRpZXMgd2l0aCB2YWx1ZXMgcmV0dXJuZWQgYnkgc2VydmVyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmxvY2FsUGFydGljaXBhbnQuZGF0YSA9IHJlc3BvbnNlLm1ldGFkYXRhO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5sb2NhbFBhcnRpY2lwYW50LmNyZWF0aW9uVGltZSA9IG5ldyBEYXRlKCkuZ2V0VGltZSgpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBVcGRhdGVzIHRoZSB2YWx1ZSBvZiBwcm9wZXJ0eSAnY29ubmVjdGlvbicgaW4gU2Vzc2lvbiBvYmplY3RcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCd1cGRhdGUtY29ubmVjdGlvbi1vYmplY3QnLCBbeyBjb25uZWN0aW9uOiB0aGlzLmxvY2FsUGFydGljaXBhbnQgfV0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gT3duIGNvbm5lY3Rpb24gY3JlYXRlZCBldmVudFxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ2Nvbm5lY3Rpb25DcmVhdGVkJywgW3sgY29ubmVjdGlvbjogdGhpcy5sb2NhbFBhcnRpY2lwYW50IH1dKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gT25lIGNvbm5lY3Rpb24gY3JlYXRlZCBldmVudCBmb3IgZWFjaCBleGlzdGluZyBjb25uZWN0aW9uIGluIHRoZSBzZXNzaW9uXG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBwYXJ0IG9mIHJvb21FdmVudC5wYXJ0aWNpcGFudHMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgnY29ubmVjdGlvbkNyZWF0ZWQnLCBbeyBjb25uZWN0aW9uOiBwYXJ0IH1dKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgLy9pZiAodGhpcy5zdWJzY3JpYmVUb1N0cmVhbXMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAobGV0IHN0cmVhbSBvZiByb29tRXZlbnQuc3RyZWFtcykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdzdHJlYW1DcmVhdGVkJywgW3sgc3RyZWFtIH1dKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEFkZGluZyB0aGUgcmVtb3RlIHN0cmVhbSB0byB0aGUgT3BlblZpZHUgb2JqZWN0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5vcGVuVmlkdS5nZXRSZW1vdGVTdHJlYW1zKCkucHVzaChzdHJlYW0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgLy99XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrKHVuZGVmaW5lZCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHVibGlzaCgpIHtcbiAgICAgICAgdGhpcy5vcGVuVmlkdS5nZXRDYW1lcmEoKS5wdWJsaXNoKCk7XG4gICAgfVxuICAgIC8qIE5FVyBNRVRIT0RTICovXG5cblxuXG5cblxuICAgIGNvbmZpZ3VyZShvcHRpb25zOiBTZXNzaW9uT3B0aW9ucykge1xuICAgICAgICB0aGlzLm9wdGlvbnMgPSBvcHRpb25zO1xuICAgICAgICB0aGlzLmlkID0gb3B0aW9ucy5zZXNzaW9uSWQ7XG4gICAgICAgIHRoaXMuc3Vic2NyaWJlVG9TdHJlYW1zID0gb3B0aW9ucy5zdWJzY3JpYmVUb1N0cmVhbXMgPT0gbnVsbCA/IHRydWUgOiBvcHRpb25zLnN1YnNjcmliZVRvU3RyZWFtcztcbiAgICAgICAgdGhpcy51cGRhdGVTcGVha2VySW50ZXJ2YWwgPSBvcHRpb25zLnVwZGF0ZVNwZWFrZXJJbnRlcnZhbCB8fCAxNTAwO1xuICAgICAgICB0aGlzLnRocmVzaG9sZFNwZWFrZXIgPSBvcHRpb25zLnRocmVzaG9sZFNwZWFrZXIgfHwgLTUwO1xuICAgICAgICB0aGlzLmFjdGl2YXRlVXBkYXRlTWFpblNwZWFrZXIoKTtcbiAgICB9XG5cbiAgICBnZXRJZCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaWQ7XG4gICAgfVxuXG4gICAgZ2V0U2Vzc2lvbklkKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5zZXNzaW9uSWQ7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBhY3RpdmF0ZVVwZGF0ZU1haW5TcGVha2VyKCkge1xuXG4gICAgICAgIHNldEludGVydmFsKCgpID0+IHtcbiAgICAgICAgICAgIGlmICh0aGlzLnBhcnRpY2lwYW50c1NwZWFraW5nLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgndXBkYXRlLW1haW4tc3BlYWtlcicsIFt7XG4gICAgICAgICAgICAgICAgICAgIHBhcnRpY2lwYW50SWQ6IHRoaXMucGFydGljaXBhbnRzU3BlYWtpbmdbdGhpcy5wYXJ0aWNpcGFudHNTcGVha2luZy5sZW5ndGggLSAxXVxuICAgICAgICAgICAgICAgIH1dKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSwgdGhpcy51cGRhdGVTcGVha2VySW50ZXJ2YWwpO1xuICAgIH1cblxuICAgIGdldExvY2FsUGFydGljaXBhbnQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmxvY2FsUGFydGljaXBhbnQ7XG4gICAgfVxuXG4gICAgYWRkRXZlbnRMaXN0ZW5lcihldmVudE5hbWUsIGxpc3RlbmVyKSB7XG4gICAgICAgIHRoaXMuZWUub24oZXZlbnROYW1lLCBsaXN0ZW5lcik7XG4gICAgfVxuXG4gICAgYWRkT25jZUV2ZW50TGlzdGVuZXIoZXZlbnROYW1lLCBsaXN0ZW5lcikge1xuICAgICAgICB0aGlzLmVlLm9uY2UoZXZlbnROYW1lLCBsaXN0ZW5lcik7XG4gICAgfVxuXG4gICAgcmVtb3ZlTGlzdGVuZXIoZXZlbnROYW1lLCBsaXN0ZW5lcikge1xuICAgICAgICB0aGlzLmVlLm9mZihldmVudE5hbWUsIGxpc3RlbmVyKTtcbiAgICB9XG5cbiAgICByZW1vdmVFdmVudChldmVudE5hbWUpIHtcbiAgICAgICAgdGhpcy5lZS5yZW1vdmVFdmVudChldmVudE5hbWUpO1xuICAgIH1cblxuICAgIGVtaXRFdmVudChldmVudE5hbWUsIGV2ZW50c0FycmF5KSB7XG4gICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KGV2ZW50TmFtZSwgZXZlbnRzQXJyYXkpO1xuICAgIH1cblxuXG4gICAgc3Vic2NyaWJlKHN0cmVhbTogU3RyZWFtKSB7XG4gICAgICAgIHN0cmVhbS5zdWJzY3JpYmUoKTtcbiAgICB9XG5cbiAgICB1bnN1c2NyaWJlKHN0cmVhbSkge1xuICAgICAgICBjb25zb2xlLmluZm8oXCJVbnN1YnNjcmliaW5nIGZyb20gXCIgKyBzdHJlYW0uZ2V0SWQoKSk7XG4gICAgICAgIHRoaXMub3BlblZpZHUuc2VuZFJlcXVlc3QoJ3Vuc3Vic2NyaWJlRnJvbVZpZGVvJywge1xuICAgICAgICAgICAgc2VuZGVyOiBzdHJlYW0uZ2V0SWQoKVxuICAgICAgICB9LFxuICAgICAgICAgICAgZnVuY3Rpb24gKGVycm9yLCByZXNwb25zZSkge1xuICAgICAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKFwiRXJyb3IgdW5zdWJzY3JpYmluZyBmcm9tIFN1YnNjcmliZXJcIiwgZXJyb3IpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIlVuc3Vic2NyaWJlZCBjb3JyZWN0bHkgZnJvbSBcIiArIHN0cmVhbS5nZXRJZCgpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBvblBhcnRpY2lwYW50UHVibGlzaGVkKG9wdGlvbnMpIHtcblxuICAgICAgICBvcHRpb25zLm1ldGFkYXRhID0gdGhpcy5wYXJ0aWNpcGFudHNbb3B0aW9ucy5pZF0uZGF0YTtcblxuICAgICAgICAvLyBHZXQgdGhlIGV4aXN0aW5nIENvbm5lY3Rpb24gY3JlYXRlZCBvbiAnb25QYXJ0aWNpcGFudEpvaW5lZCcgZm9yXG4gICAgICAgIC8vIGV4aXN0aW5nIHBhcnRpY2lwYW50cyBvciBjcmVhdGUgYSBuZXcgb25lIGZvciBuZXcgcGFydGljaXBhbnRzXG4gICAgICAgIGxldCBjb25uZWN0aW9uID0gdGhpcy5wYXJ0aWNpcGFudHNbb3B0aW9ucy5pZF07XG4gICAgICAgIGlmIChjb25uZWN0aW9uKSB7XG4gICAgICAgICAgICAvLyBVcGRhdGUgZXhpc3RpbmcgQ29ubmVjdGlvblxuICAgICAgICAgICAgY29ubmVjdGlvbi5vcHRpb25zID0gb3B0aW9ucztcbiAgICAgICAgICAgIGNvbm5lY3Rpb24uaW5pdFN0cmVhbXMob3B0aW9ucyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBDcmVhdGUgbmV3IENvbm5lY3Rpb25cbiAgICAgICAgICAgIGNvbm5lY3Rpb24gPSBuZXcgQ29ubmVjdGlvbih0aGlzLm9wZW5WaWR1LCBmYWxzZSwgdGhpcywgb3B0aW9ucyk7XG4gICAgICAgIH1cblxuICAgICAgICBsZXQgcGlkID0gY29ubmVjdGlvbi5jb25uZWN0aW9uSWQ7XG4gICAgICAgIGlmICghKHBpZCBpbiB0aGlzLnBhcnRpY2lwYW50cykpIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZGVidWcoXCJSZW1vdGUgQ29ubmVjdGlvbiBub3QgZm91bmQgaW4gY29ubmVjdGlvbnMgbGlzdCBieSBpdHMgaWQgW1wiICsgcGlkICsgXCJdXCIpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29uc29sZS5kZWJ1ZyhcIlJlbW90ZSBDb25uZWN0aW9uIGZvdW5kIGluIGNvbm5lY3Rpb25zIGxpc3QgYnkgaXRzIGlkIFtcIiArIHBpZCArIFwiXVwiKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbm5lY3Rpb24uY3JlYXRpb25UaW1lID0gdGhpcy5wYXJ0aWNpcGFudHNbcGlkXS5jcmVhdGlvblRpbWU7XG4gICAgICAgIHRoaXMucGFydGljaXBhbnRzW3BpZF0gPSBjb25uZWN0aW9uO1xuXG4gICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdwYXJ0aWNpcGFudC1wdWJsaXNoZWQnLCBbeyBjb25uZWN0aW9uIH1dKTtcblxuICAgICAgICBsZXQgc3RyZWFtcyA9IGNvbm5lY3Rpb24uZ2V0U3RyZWFtcygpO1xuICAgICAgICBmb3IgKGxldCBrZXkgaW4gc3RyZWFtcykge1xuICAgICAgICAgICAgbGV0IHN0cmVhbSA9IHN0cmVhbXNba2V5XTtcblxuICAgICAgICAgICAgaWYgKHRoaXMuc3Vic2NyaWJlVG9TdHJlYW1zKSB7XG4gICAgICAgICAgICAgICAgc3RyZWFtLnN1YnNjcmliZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3N0cmVhbUNyZWF0ZWQnLCBbeyBzdHJlYW0gfV0pO1xuICAgICAgICAgICAgLy8gQWRkaW5nIHRoZSByZW1vdGUgc3RyZWFtIHRvIHRoZSBPcGVuVmlkdSBvYmplY3RcbiAgICAgICAgICAgIHRoaXMub3BlblZpZHUuZ2V0UmVtb3RlU3RyZWFtcygpLnB1c2goc3RyZWFtKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIG9uUGFydGljaXBhbnRKb2luZWQobXNnKSB7XG5cbiAgICAgICAgbGV0IGNvbm5lY3Rpb24gPSBuZXcgQ29ubmVjdGlvbih0aGlzLm9wZW5WaWR1LCBmYWxzZSwgdGhpcywgbXNnKTtcbiAgICAgICAgY29ubmVjdGlvbi5jcmVhdGlvblRpbWUgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcblxuICAgICAgICBsZXQgcGlkID0gY29ubmVjdGlvbi5jb25uZWN0aW9uSWQ7XG4gICAgICAgIGlmICghKHBpZCBpbiB0aGlzLnBhcnRpY2lwYW50cykpIHtcbiAgICAgICAgICAgIHRoaXMucGFydGljaXBhbnRzW3BpZF0gPSBjb25uZWN0aW9uO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy91c2UgZXhpc3Rpbmcgc28gdGhhdCB3ZSBkb24ndCBsb3NlIHN0cmVhbXMgaW5mb1xuICAgICAgICAgICAgY29uc29sZS53YXJuKFwiQ29ubmVjdGlvbiBhbHJlYWR5IGV4aXN0cyBpbiBjb25uZWN0aW9ucyBsaXN0IHdpdGggXCIgK1xuICAgICAgICAgICAgICAgIFwidGhlIHNhbWUgY29ubmVjdGlvbklkLCBvbGQ6XCIsIHRoaXMucGFydGljaXBhbnRzW3BpZF0sIFwiLCBqb2luZWQgbm93OlwiLCBjb25uZWN0aW9uKTtcbiAgICAgICAgICAgIGNvbm5lY3Rpb24gPSB0aGlzLnBhcnRpY2lwYW50c1twaWRdO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3BhcnRpY2lwYW50LWpvaW5lZCcsIFt7XG4gICAgICAgICAgICBjb25uZWN0aW9uOiBjb25uZWN0aW9uXG4gICAgICAgIH1dKTtcblxuICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgnY29ubmVjdGlvbkNyZWF0ZWQnLCBbe1xuICAgICAgICAgICAgY29ubmVjdGlvbjogY29ubmVjdGlvblxuICAgICAgICB9XSk7XG5cbiAgICB9XG5cbiAgICBvblBhcnRpY2lwYW50TGVmdChtc2cpIHtcblxuICAgICAgICBsZXQgY29ubmVjdGlvbiA9IHRoaXMucGFydGljaXBhbnRzW21zZy5uYW1lXTtcblxuICAgICAgICBpZiAoY29ubmVjdGlvbiAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBkZWxldGUgdGhpcy5wYXJ0aWNpcGFudHNbbXNnLm5hbWVdO1xuXG4gICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgncGFydGljaXBhbnQtbGVmdCcsIFt7XG4gICAgICAgICAgICAgICAgY29ubmVjdGlvbjogY29ubmVjdGlvblxuICAgICAgICAgICAgfV0pO1xuXG4gICAgICAgICAgICBsZXQgc3RyZWFtcyA9IGNvbm5lY3Rpb24uZ2V0U3RyZWFtcygpO1xuICAgICAgICAgICAgZm9yIChsZXQga2V5IGluIHN0cmVhbXMpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgnc3RyZWFtRGVzdHJveWVkJywgW3tcbiAgICAgICAgICAgICAgICAgICAgc3RyZWFtOiBzdHJlYW1zW2tleV0sXG4gICAgICAgICAgICAgICAgICAgIHByZXZlbnREZWZhdWx0OiAoKSA9PiB7IHRoaXMuZWUucmVtb3ZlRXZlbnQoJ3N0cmVhbS1kZXN0cm95ZWQtZGVmYXVsdCcpOyB9XG4gICAgICAgICAgICAgICAgfV0pO1xuICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdzdHJlYW0tZGVzdHJveWVkLWRlZmF1bHQnLCBbe1xuICAgICAgICAgICAgICAgICAgICBzdHJlYW06IHN0cmVhbXNba2V5XVxuICAgICAgICAgICAgICAgIH1dKTtcblxuICAgICAgICAgICAgICAgIC8vIERlbGV0aW5nIHRoZSByZW1vdmVkIHN0cmVhbSBmcm9tIHRoZSBPcGVuVmlkdSBvYmplY3RcbiAgICAgICAgICAgICAgICBsZXQgaW5kZXggPSB0aGlzLm9wZW5WaWR1LmdldFJlbW90ZVN0cmVhbXMoKS5pbmRleE9mKHN0cmVhbXNba2V5XSk7XG4gICAgICAgICAgICAgICAgdGhpcy5vcGVuVmlkdS5nZXRSZW1vdGVTdHJlYW1zKCkuc3BsaWNlKGluZGV4LCAxKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29ubmVjdGlvbi5kaXNwb3NlKCk7XG5cbiAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdjb25uZWN0aW9uRGVzdHJveWVkJywgW3tcbiAgICAgICAgICAgICAgICBjb25uZWN0aW9uOiBjb25uZWN0aW9uXG4gICAgICAgICAgICB9XSk7XG5cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbnNvbGUud2FybihcIlBhcnRpY2lwYW50IFwiICsgbXNnLm5hbWVcbiAgICAgICAgICAgICAgICArIFwiIHVua25vd24uIFBhcnRpY2lwYW50czogXCJcbiAgICAgICAgICAgICAgICArIEpTT04uc3RyaW5naWZ5KHRoaXMucGFydGljaXBhbnRzKSk7XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgb25QYXJ0aWNpcGFudEV2aWN0ZWQobXNnKSB7XG4gICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdwYXJ0aWNpcGFudC1ldmljdGVkJywgW3tcbiAgICAgICAgICAgIGxvY2FsUGFydGljaXBhbnQ6IHRoaXMubG9jYWxQYXJ0aWNpcGFudFxuICAgICAgICB9XSk7XG4gICAgfTtcblxuICAgIG9uTmV3TWVzc2FnZShtc2cpIHtcblxuICAgICAgICBjb25zb2xlLmluZm8oXCJOZXcgbWVzc2FnZTogXCIgKyBKU09OLnN0cmluZ2lmeShtc2cpKTtcbiAgICAgICAgbGV0IHJvb20gPSBtc2cucm9vbTtcbiAgICAgICAgbGV0IHVzZXIgPSBtc2cudXNlcjtcbiAgICAgICAgbGV0IG1lc3NhZ2UgPSBtc2cubWVzc2FnZTtcblxuICAgICAgICBpZiAodXNlciAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgnbmV3TWVzc2FnZScsIFt7XG4gICAgICAgICAgICAgICAgcm9vbTogcm9vbSxcbiAgICAgICAgICAgICAgICB1c2VyOiB1c2VyLFxuICAgICAgICAgICAgICAgIG1lc3NhZ2U6IG1lc3NhZ2VcbiAgICAgICAgICAgIH1dKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbnNvbGUud2FybihcIlVzZXIgdW5kZWZpbmVkIGluIG5ldyBtZXNzYWdlOlwiLCBtc2cpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmVjdkljZUNhbmRpZGF0ZShtc2cpIHtcblxuICAgICAgICBsZXQgY2FuZGlkYXRlID0ge1xuICAgICAgICAgICAgY2FuZGlkYXRlOiBtc2cuY2FuZGlkYXRlLFxuICAgICAgICAgICAgc2RwTWlkOiBtc2cuc2RwTWlkLFxuICAgICAgICAgICAgc2RwTUxpbmVJbmRleDogbXNnLnNkcE1MaW5lSW5kZXhcbiAgICAgICAgfVxuXG4gICAgICAgIGxldCBjb25uZWN0aW9uID0gdGhpcy5wYXJ0aWNpcGFudHNbbXNnLmVuZHBvaW50TmFtZV07XG4gICAgICAgIGlmICghY29ubmVjdGlvbikge1xuICAgICAgICAgICAgY29uc29sZS5lcnJvcihcIlBhcnRpY2lwYW50IG5vdCBmb3VuZCBmb3IgZW5kcG9pbnQgXCIgK1xuICAgICAgICAgICAgICAgIG1zZy5lbmRwb2ludE5hbWUgKyBcIi4gSWNlIGNhbmRpZGF0ZSB3aWxsIGJlIGlnbm9yZWQuXCIsXG4gICAgICAgICAgICAgICAgY2FuZGlkYXRlKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGxldCBzdHJlYW1zID0gY29ubmVjdGlvbi5nZXRTdHJlYW1zKCk7XG4gICAgICAgIGZvciAobGV0IGtleSBpbiBzdHJlYW1zKSB7XG4gICAgICAgICAgICBsZXQgc3RyZWFtID0gc3RyZWFtc1trZXldO1xuICAgICAgICAgICAgc3RyZWFtLmdldFdlYlJ0Y1BlZXIoKS5hZGRJY2VDYW5kaWRhdGUoY2FuZGlkYXRlLCBmdW5jdGlvbiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihcIkVycm9yIGFkZGluZyBjYW5kaWRhdGUgZm9yIFwiICsga2V5XG4gICAgICAgICAgICAgICAgICAgICAgICArIFwiIHN0cmVhbSBvZiBlbmRwb2ludCBcIiArIG1zZy5lbmRwb2ludE5hbWVcbiAgICAgICAgICAgICAgICAgICAgICAgICsgXCI6IFwiICsgZXJyb3IpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgb25Sb29tQ2xvc2VkKG1zZykge1xuXG4gICAgICAgIGNvbnNvbGUuaW5mbyhcIlJvb20gY2xvc2VkOiBcIiArIEpTT04uc3RyaW5naWZ5KG1zZykpO1xuICAgICAgICBsZXQgcm9vbSA9IG1zZy5yb29tO1xuICAgICAgICBpZiAocm9vbSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgncm9vbS1jbG9zZWQnLCBbe1xuICAgICAgICAgICAgICAgIHJvb206IHJvb21cbiAgICAgICAgICAgIH1dKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbnNvbGUud2FybihcIlJvb20gdW5kZWZpbmVkIGluIG9uIHJvb20gY2xvc2VkXCIsIG1zZyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBvbkxvc3RDb25uZWN0aW9uKCkge1xuXG4gICAgICAgIGlmICghdGhpcy5jb25uZWN0ZWQpIHtcbiAgICAgICAgICAgIGNvbnNvbGUud2FybignTm90IGNvbm5lY3RlZCB0byByb29tOiBpZiB5b3UgYXJlIG5vdCBkZWJ1Z2dpbmcsIHRoaXMgaXMgcHJvYmFibHkgYSBjZXJ0aWZpY2F0ZSBlcnJvcicpO1xuICAgICAgICAgICAgaWYgKHdpbmRvdy5jb25maXJtKCdJZiB5b3UgYXJlIG5vdCBkZWJ1Z2dpbmcsIHRoaXMgaXMgcHJvYmFibHkgYSBjZXJ0aWZpY2F0ZSBlcnJvciBhdCBcXFwiJyArIHRoaXMub3BlblZpZHUuZ2V0T3BlblZpZHVTZXJ2ZXJVUkwoKSArICdcXFwiXFxuXFxuQ2xpY2sgT0sgdG8gbmF2aWdhdGUgYW5kIGFjY2VwdCBpdCcpKSB7XG4gICAgICAgICAgICAgICAgbG9jYXRpb24uYXNzaWduKHRoaXMub3BlblZpZHUuZ2V0T3BlblZpZHVTZXJ2ZXJVUkwoKSArICcvYWNjZXB0LWNlcnRpZmljYXRlJyk7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc29sZS53YXJuKCdMb3N0IGNvbm5lY3Rpb24gaW4gU2Vzc2lvbiAnICsgdGhpcy5pZCk7XG4gICAgICAgIGxldCByb29tID0gdGhpcy5pZDtcbiAgICAgICAgaWYgKHJvb20gIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ2xvc3QtY29ubmVjdGlvbicsIFt7IHJvb20gfV0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29uc29sZS53YXJuKCdSb29tIHVuZGVmaW5lZCB3aGVuIGxvc3QgY29ubmVjdGlvbicpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgb25NZWRpYUVycm9yKHBhcmFtcykge1xuXG4gICAgICAgIGNvbnNvbGUuZXJyb3IoXCJNZWRpYSBlcnJvcjogXCIgKyBKU09OLnN0cmluZ2lmeShwYXJhbXMpKTtcbiAgICAgICAgbGV0IGVycm9yID0gcGFyYW1zLmVycm9yO1xuICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdlcnJvci1tZWRpYScsIFt7XG4gICAgICAgICAgICAgICAgZXJyb3I6IGVycm9yXG4gICAgICAgICAgICB9XSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zb2xlLndhcm4oXCJSZWNlaXZlZCB1bmRlZmluZWQgbWVkaWEgZXJyb3IuIFBhcmFtczpcIiwgcGFyYW1zKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qXG4gICAgICogZm9yY2VkIG1lYW5zIHRoZSB1c2VyIHdhcyBldmljdGVkLCBubyBuZWVkIHRvIHNlbmQgdGhlICdsZWF2ZVJvb20nIHJlcXVlc3RcbiAgICAgKi9cbiAgICBsZWF2ZShmb3JjZWQsIGpzb25ScGNDbGllbnQpIHtcblxuICAgICAgICBmb3JjZWQgPSAhIWZvcmNlZDtcblxuICAgICAgICBjb25zb2xlLmluZm8oXCJMZWF2aW5nIFNlc3Npb24gKGZvcmNlZD1cIiArIGZvcmNlZCArIFwiKVwiKTtcblxuICAgICAgICBpZiAodGhpcy5jb25uZWN0ZWQgJiYgIWZvcmNlZCkge1xuICAgICAgICAgICAgdGhpcy5vcGVuVmlkdS5zZW5kUmVxdWVzdCgnbGVhdmVSb29tJywgZnVuY3Rpb24gKGVycm9yLCByZXNwb25zZSkge1xuICAgICAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKGVycm9yKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAganNvblJwY0NsaWVudC5jbG9zZSgpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBqc29uUnBjQ2xpZW50LmNsb3NlKCk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5jb25uZWN0ZWQgPSBmYWxzZTtcbiAgICAgICAgaWYgKHRoaXMucGFydGljaXBhbnRzKSB7XG4gICAgICAgICAgICBmb3IgKGxldCBwaWQgaW4gdGhpcy5wYXJ0aWNpcGFudHMpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnBhcnRpY2lwYW50c1twaWRdLmRpc3Bvc2UoKTtcbiAgICAgICAgICAgICAgICBkZWxldGUgdGhpcy5wYXJ0aWNpcGFudHNbcGlkXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIGRpc2Nvbm5lY3Qoc3RyZWFtOiBTdHJlYW0pIHtcblxuICAgICAgICBsZXQgY29ubmVjdGlvbiA9IHN0cmVhbS5nZXRQYXJ0aWNpcGFudCgpO1xuICAgICAgICBpZiAoIWNvbm5lY3Rpb24pIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoXCJTdHJlYW0gdG8gZGlzY29ubmVjdCBoYXMgbm8gcGFydGljaXBhbnRcIiwgc3RyZWFtKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGRlbGV0ZSB0aGlzLnBhcnRpY2lwYW50c1tjb25uZWN0aW9uLmNvbm5lY3Rpb25JZF07XG4gICAgICAgIGNvbm5lY3Rpb24uZGlzcG9zZSgpO1xuXG4gICAgICAgIGlmIChjb25uZWN0aW9uID09PSB0aGlzLmxvY2FsUGFydGljaXBhbnQpIHtcblxuICAgICAgICAgICAgY29uc29sZS5pbmZvKFwiVW5wdWJsaXNoaW5nIG15IG1lZGlhIChJJ20gXCIgKyBjb25uZWN0aW9uLmNvbm5lY3Rpb25JZCArIFwiKVwiKTtcbiAgICAgICAgICAgIGRlbGV0ZSB0aGlzLmxvY2FsUGFydGljaXBhbnQ7XG4gICAgICAgICAgICB0aGlzLm9wZW5WaWR1LnNlbmRSZXF1ZXN0KCd1bnB1Ymxpc2hWaWRlbycsIGZ1bmN0aW9uIChlcnJvciwgcmVzcG9uc2UpIHtcbiAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKFwiTWVkaWEgdW5wdWJsaXNoZWQgY29ycmVjdGx5XCIpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnVuc3VzY3JpYmUoc3RyZWFtKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHVucHVibGlzaChzdHJlYW06IFN0cmVhbSkge1xuXG4gICAgICAgIGxldCBjb25uZWN0aW9uID0gc3RyZWFtLmdldFBhcnRpY2lwYW50KCk7XG4gICAgICAgIGlmICghY29ubmVjdGlvbikge1xuICAgICAgICAgICAgY29uc29sZS5lcnJvcihcIlN0cmVhbSB0byBkaXNjb25uZWN0IGhhcyBubyBwYXJ0aWNpcGFudFwiLCBzdHJlYW0pO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGNvbm5lY3Rpb24gPT09IHRoaXMubG9jYWxQYXJ0aWNpcGFudCkge1xuXG4gICAgICAgICAgICBkZWxldGUgdGhpcy5wYXJ0aWNpcGFudHNbY29ubmVjdGlvbi5jb25uZWN0aW9uSWRdO1xuICAgICAgICAgICAgY29ubmVjdGlvbi5kaXNwb3NlKCk7XG5cbiAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIlVucHVibGlzaGluZyBteSBtZWRpYSAoSSdtIFwiICsgY29ubmVjdGlvbi5jb25uZWN0aW9uSWQgKyBcIilcIik7XG4gICAgICAgICAgICBkZWxldGUgdGhpcy5sb2NhbFBhcnRpY2lwYW50O1xuICAgICAgICAgICAgdGhpcy5vcGVuVmlkdS5zZW5kUmVxdWVzdCgndW5wdWJsaXNoVmlkZW8nLCBmdW5jdGlvbiAoZXJyb3IsIHJlc3BvbnNlKSB7XG4gICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIk1lZGlhIHVucHVibGlzaGVkIGNvcnJlY3RseVwiKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGdldFN0cmVhbXMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnN0cmVhbXM7XG4gICAgfVxuXG4gICAgYWRkUGFydGljaXBhbnRTcGVha2luZyhwYXJ0aWNpcGFudElkKSB7XG4gICAgICAgIHRoaXMucGFydGljaXBhbnRzU3BlYWtpbmcucHVzaChwYXJ0aWNpcGFudElkKTtcbiAgICB9XG5cbiAgICByZW1vdmVQYXJ0aWNpcGFudFNwZWFraW5nKHBhcnRpY2lwYW50SWQpIHtcbiAgICAgICAgbGV0IHBvcyA9IC0xO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMucGFydGljaXBhbnRzU3BlYWtpbmcubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGlmICh0aGlzLnBhcnRpY2lwYW50c1NwZWFraW5nW2ldID09IHBhcnRpY2lwYW50SWQpIHtcbiAgICAgICAgICAgICAgICBwb3MgPSBpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChwb3MgIT0gLTEpIHtcbiAgICAgICAgICAgIHRoaXMucGFydGljaXBhbnRzU3BlYWtpbmcuc3BsaWNlKHBvcywgMSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBzdHJpbmdDbGllbnRNZXRhZGF0YShtZXRhZGF0YSk6IHN0cmluZyB7XG4gICAgICAgIGlmICghKHR5cGVvZiBtZXRhZGF0YSA9PT0gJ3N0cmluZycpKSB7XG4gICAgICAgICAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkobWV0YWRhdGEpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIG1ldGFkYXRhO1xuICAgICAgICB9XG4gICAgfVxuICAgIFxuICAgIHByaXZhdGUgcmFuZG9tVG9rZW4oKTogc3RyaW5nIHtcbiAgICAgICAgcmV0dXJuIE1hdGgucmFuZG9tKCkudG9TdHJpbmcoMzYpLnNsaWNlKDIpICsgTWF0aC5yYW5kb20oKS50b1N0cmluZygzNikuc2xpY2UoMik7XG4gICAgfVxuXG59XG4iLCIvKlxuICogb3B0aW9uczogbmFtZTogWFhYIGRhdGE6IHRydWUgKE1heWJlIHRoaXMgaXMgYmFzZWQgb24gd2VicnRjKSBhdWRpbzogdHJ1ZSxcbiAqIHZpZGVvOiB0cnVlLCB1cmw6IFwiZmlsZTovLy8uLi5cIiA+IFBsYXllciBzY3JlZW46IHRydWUgPiBEZXNrdG9wIChpbXBsaWNpdFxuICogdmlkZW86dHJ1ZSwgYXVkaW86ZmFsc2UpIGF1ZGlvOiB0cnVlLCB2aWRlbzogdHJ1ZSA+IFdlYmNhbVxuICpcbiAqIHN0cmVhbS5oYXNBdWRpbygpOyBzdHJlYW0uaGFzVmlkZW8oKTsgc3RyZWFtLmhhc0RhdGEoKTtcbiAqL1xuaW1wb3J0IHsgQ29ubmVjdGlvbiB9IGZyb20gJy4vQ29ubmVjdGlvbic7XG5pbXBvcnQgeyBTZXNzaW9uSW50ZXJuYWwgfSBmcm9tICcuL1Nlc3Npb25JbnRlcm5hbCc7XG5pbXBvcnQgeyBPcGVuVmlkdUludGVybmFsLCBDYWxsYmFjayB9IGZyb20gJy4vT3BlblZpZHVJbnRlcm5hbCc7XG5pbXBvcnQgRXZlbnRFbWl0dGVyID0gcmVxdWlyZSgnd29sZnk4Ny1ldmVudGVtaXR0ZXInKTtcbmltcG9ydCAqIGFzIGt1cmVudG9VdGlscyBmcm9tICcuLi9LdXJlbnRvVXRpbHMva3VyZW50by11dGlscy1qcyc7XG5cbmltcG9ydCAqIGFzIGFkYXB0ZXIgZnJvbSAnd2VicnRjLWFkYXB0ZXInO1xuZGVjbGFyZSB2YXIgbmF2aWdhdG9yOiBhbnk7XG5kZWNsYXJlIHZhciBSVENTZXNzaW9uRGVzY3JpcHRpb246IGFueTtcblxuaWYgKHdpbmRvdykge1xuICAgIHdpbmRvd1tcImFkYXB0ZXJcIl0gPSBhZGFwdGVyO1xufVxuXG5mdW5jdGlvbiBqcShpZDogc3RyaW5nKTogc3RyaW5nIHtcbiAgICByZXR1cm4gaWQucmVwbGFjZSgvKEB8OnxcXC58XFxbfFxcXXwsKS9nLCBcIlxcXFwkMVwiKTtcbn1cblxuZnVuY3Rpb24gc2hvdyhpZDogc3RyaW5nKSB7XG4gICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoanEoaWQpKSEuc3R5bGUuZGlzcGxheSA9ICdibG9jayc7XG59XG5cbmZ1bmN0aW9uIGhpZGUoaWQ6IHN0cmluZykge1xuICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGpxKGlkKSkhLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgU3RyZWFtT3B0aW9ucyB7XG4gICAgaWQ6IHN0cmluZztcbiAgICBjb25uZWN0aW9uOiBDb25uZWN0aW9uO1xuICAgIHJlY3ZWaWRlbzogYm9vbGVhbjtcbiAgICByZWN2QXVkaW86IGJvb2xlYW47XG4gICAgc2VuZFZpZGVvOiBib29sZWFuO1xuICAgIHNlbmRBdWRpbzogYm9vbGVhbjtcbiAgICBhY3RpdmVBdWRpbzogYm9vbGVhbjtcbiAgICBhY3RpdmVWaWRlbzogYm9vbGVhbjtcbiAgICBkYXRhOiBib29sZWFuO1xuICAgIG1lZGlhQ29uc3RyYWludHM6IGFueTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBWaWRlb09wdGlvbnMge1xuICAgIHRodW1iOiBzdHJpbmc7XG4gICAgdmlkZW86IEhUTUxWaWRlb0VsZW1lbnQ7XG59XG5cbmV4cG9ydCBjbGFzcyBTdHJlYW0ge1xuXG4gICAgcHVibGljIGNvbm5lY3Rpb246IENvbm5lY3Rpb247XG5cbiAgICBwcml2YXRlIGVlID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuICAgIHByaXZhdGUgd3JTdHJlYW06IGFueTtcbiAgICBwcml2YXRlIHdwOiBhbnk7XG4gICAgcHJpdmF0ZSBpZDogc3RyaW5nO1xuICAgIHByaXZhdGUgdmlkZW86IEhUTUxWaWRlb0VsZW1lbnQ7XG4gICAgcHJpdmF0ZSB2aWRlb0VsZW1lbnRzOiBWaWRlb09wdGlvbnNbXSA9IFtdO1xuICAgIHByaXZhdGUgZWxlbWVudHM6IEhUTUxEaXZFbGVtZW50W10gPSBbXTtcbiAgICBwcml2YXRlIHNwZWVjaEV2ZW50OiBhbnk7XG4gICAgcHJpdmF0ZSByZWN2VmlkZW86IGJvb2xlYW47XG4gICAgcHJpdmF0ZSByZWN2QXVkaW86IGJvb2xlYW47XG4gICAgcHJpdmF0ZSBzZW5kVmlkZW86IGJvb2xlYW47XG4gICAgcHJpdmF0ZSBzZW5kQXVkaW86IGJvb2xlYW47XG4gICAgcHJpdmF0ZSBtZWRpYUNvbnN0cmFpbnRzOiBhbnk7XG4gICAgcHJpdmF0ZSBzaG93TXlSZW1vdGUgPSBmYWxzZTtcbiAgICBwcml2YXRlIGxvY2FsTWlycm9yZWQgPSBmYWxzZTtcbiAgICBwcml2YXRlIGNoYW5JZCA9IDA7XG4gICAgcHJpdmF0ZSBkYXRhQ2hhbm5lbDogYm9vbGVhbjtcbiAgICBwcml2YXRlIGRhdGFDaGFubmVsT3BlbmVkID0gZmFsc2U7XG5cbiAgICBwcml2YXRlIGFjdGl2ZUF1ZGlvID0gdHJ1ZTtcbiAgICBwcml2YXRlIGFjdGl2ZVZpZGVvID0gdHJ1ZTtcblxuICAgIHByaXZhdGUgdmlkZW9TcmNPYmplY3Q6IE1lZGlhU3RyZWFtIHwgbnVsbDtcbiAgICBwcml2YXRlIHBhcmVudElkOiBzdHJpbmc7XG4gICAgcHVibGljIGlzUmVhZHk6IGJvb2xlYW4gPSBmYWxzZTtcbiAgICBwdWJsaWMgaXNWaWRlb0VMZW1lbnRDcmVhdGVkOiBib29sZWFuID0gZmFsc2U7XG4gICAgcHVibGljIGFjY2Vzc0lzQWxsb3dlZDogYm9vbGVhbiA9IGZhbHNlO1xuICAgIHB1YmxpYyBhY2Nlc3NJc0RlbmllZDogYm9vbGVhbiA9IGZhbHNlO1xuXG4gICAgY29uc3RydWN0b3IocHJpdmF0ZSBvcGVuVmlkdTogT3BlblZpZHVJbnRlcm5hbCwgcHJpdmF0ZSBsb2NhbDogYm9vbGVhbiwgcHJpdmF0ZSByb29tOiBTZXNzaW9uSW50ZXJuYWwsIG9wdGlvbnM6IFN0cmVhbU9wdGlvbnMpIHtcblxuICAgICAgICBpZiAob3B0aW9ucy5pZCkge1xuICAgICAgICAgICAgdGhpcy5pZCA9IG9wdGlvbnMuaWQ7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmlkID0gXCJ3ZWJjYW1cIjtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuY29ubmVjdGlvbiA9IG9wdGlvbnMuY29ubmVjdGlvbjtcbiAgICAgICAgdGhpcy5yZWN2VmlkZW8gPSBvcHRpb25zLnJlY3ZWaWRlbyB8fCBmYWxzZTtcbiAgICAgICAgdGhpcy5yZWN2QXVkaW8gPSBvcHRpb25zLnJlY3ZBdWRpbyB8fCBmYWxzZTtcbiAgICAgICAgdGhpcy5zZW5kVmlkZW8gPSBvcHRpb25zLnNlbmRWaWRlbztcbiAgICAgICAgdGhpcy5zZW5kQXVkaW8gPSBvcHRpb25zLnNlbmRBdWRpbztcbiAgICAgICAgdGhpcy5hY3RpdmVBdWRpbyA9IG9wdGlvbnMuYWN0aXZlQXVkaW87XG4gICAgICAgIHRoaXMuYWN0aXZlVmlkZW8gPSBvcHRpb25zLmFjdGl2ZVZpZGVvO1xuICAgICAgICB0aGlzLmRhdGFDaGFubmVsID0gb3B0aW9ucy5kYXRhIHx8IGZhbHNlO1xuICAgICAgICB0aGlzLm1lZGlhQ29uc3RyYWludHMgPSBvcHRpb25zLm1lZGlhQ29uc3RyYWludHM7XG5cbiAgICAgICAgdGhpcy5hZGRFdmVudExpc3RlbmVyKCdzcmMtYWRkZWQnLCAoc3JjRXZlbnQpID0+IHtcbiAgICAgICAgICAgIHRoaXMudmlkZW9TcmNPYmplY3QgPSBzcmNFdmVudC5zcmNPYmplY3Q7XG4gICAgICAgICAgICBpZiAodGhpcy52aWRlbykgdGhpcy52aWRlby5zcmNPYmplY3QgPSBzcmNFdmVudC5zcmNPYmplY3Q7XG4gICAgICAgICAgICBjb25zb2xlLmRlYnVnKFwiVmlkZW8gc3JjT2JqZWN0IFtcIiArIHNyY0V2ZW50LnNyY09iamVjdCArIFwiXSBhZGRlZCB0byBzdHJlYW0gW1wiICsgdGhpcy5nZXRJZCgpICsgXCJdXCIpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBlbWl0U3JjRXZlbnQod3JzdHJlYW0pIHtcbiAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3NyYy1hZGRlZCcsIFt7XG4gICAgICAgICAgICBzcmNPYmplY3Q6IHdyc3RyZWFtXG4gICAgICAgIH1dKTtcbiAgICB9XG5cbiAgICBlbWl0U3RyZWFtUmVhZHlFdmVudCgpIHtcbiAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3N0cmVhbS1yZWFkeScpLCBbe31dO1xuICAgIH1cblxuICAgIGdldFZpZGVvU3JjT2JqZWN0KCkge1xuICAgICAgICByZXR1cm4gdGhpcy52aWRlb1NyY09iamVjdDtcbiAgICB9XG5cbiAgICByZW1vdmVWaWRlbyhwYXJlbnRFbGVtZW50OiBzdHJpbmcpO1xuICAgIHJlbW92ZVZpZGVvKHBhcmVudEVsZW1lbnQ6IEVsZW1lbnQpO1xuICAgIHJlbW92ZVZpZGVvKCk7XG5cbiAgICByZW1vdmVWaWRlbyhwYXJlbnRFbGVtZW50Pykge1xuICAgICAgICBpZiAodHlwZW9mIHBhcmVudEVsZW1lbnQgPT09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKHBhcmVudEVsZW1lbnQpIS5yZW1vdmVDaGlsZCh0aGlzLnZpZGVvKTtcbiAgICAgICAgfSBlbHNlIGlmIChwYXJlbnRFbGVtZW50IGluc3RhbmNlb2YgRWxlbWVudCkge1xuICAgICAgICAgICAgcGFyZW50RWxlbWVudC5yZW1vdmVDaGlsZCh0aGlzLnZpZGVvKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICghcGFyZW50RWxlbWVudCkge1xuICAgICAgICAgICAgaWYgKGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKHRoaXMucGFyZW50SWQpKSB7XG4gICAgICAgICAgICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQodGhpcy5wYXJlbnRJZCkhLnJlbW92ZUNoaWxkKHRoaXMudmlkZW8pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgZ2V0VmlkZW9FbGVtZW50KCk6IEhUTUxWaWRlb0VsZW1lbnQge1xuICAgICAgICByZXR1cm4gdGhpcy52aWRlbztcbiAgICB9XG5cbiAgICBzZXRWaWRlb0VsZW1lbnQodmlkZW86IEhUTUxWaWRlb0VsZW1lbnQpIHtcbiAgICAgICAgdGhpcy52aWRlbyA9IHZpZGVvO1xuICAgIH1cblxuXG5cblxuXG5cbiAgICBnZXRSZWN2VmlkZW8oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnJlY3ZWaWRlbztcbiAgICB9XG5cbiAgICBnZXRSZWN2QXVkaW8oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnJlY3ZBdWRpbztcbiAgICB9XG5cblxuICAgIHN1YnNjcmliZVRvTXlSZW1vdGUoKSB7XG4gICAgICAgIHRoaXMuc2hvd015UmVtb3RlID0gdHJ1ZTtcbiAgICB9XG5cbiAgICBkaXNwbGF5TXlSZW1vdGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnNob3dNeVJlbW90ZTtcbiAgICB9XG5cbiAgICBtaXJyb3JMb2NhbFN0cmVhbSh3cikge1xuICAgICAgICB0aGlzLnNob3dNeVJlbW90ZSA9IHRydWU7XG4gICAgICAgIHRoaXMubG9jYWxNaXJyb3JlZCA9IHRydWU7XG4gICAgICAgIGlmICh3cikge1xuICAgICAgICAgICAgdGhpcy53clN0cmVhbSA9IHdyO1xuICAgICAgICAgICAgdGhpcy5lbWl0U3JjRXZlbnQodGhpcy53clN0cmVhbSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBpc0xvY2FsTWlycm9yZWQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmxvY2FsTWlycm9yZWQ7XG4gICAgfVxuXG4gICAgZ2V0Q2hhbm5lbE5hbWUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldElkKCkgKyAnXycgKyB0aGlzLmNoYW5JZCsrO1xuICAgIH1cblxuXG4gICAgaXNEYXRhQ2hhbm5lbEVuYWJsZWQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmRhdGFDaGFubmVsO1xuICAgIH1cblxuXG4gICAgaXNEYXRhQ2hhbm5lbE9wZW5lZCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZGF0YUNoYW5uZWxPcGVuZWQ7XG4gICAgfVxuXG4gICAgb25EYXRhQ2hhbm5lbE9wZW4oZXZlbnQpIHtcbiAgICAgICAgY29uc29sZS5kZWJ1ZygnRGF0YSBjaGFubmVsIGlzIG9wZW5lZCcpO1xuICAgICAgICB0aGlzLmRhdGFDaGFubmVsT3BlbmVkID0gdHJ1ZTtcbiAgICB9XG5cbiAgICBvbkRhdGFDaGFubmVsQ2xvc2VkKGV2ZW50KSB7XG4gICAgICAgIGNvbnNvbGUuZGVidWcoJ0RhdGEgY2hhbm5lbCBpcyBjbG9zZWQnKTtcbiAgICAgICAgdGhpcy5kYXRhQ2hhbm5lbE9wZW5lZCA9IGZhbHNlO1xuICAgIH1cblxuICAgIHNlbmREYXRhKGRhdGEpIHtcbiAgICAgICAgaWYgKHRoaXMud3AgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdXZWJSVEMgcGVlciBoYXMgbm90IGJlZW4gY3JlYXRlZCB5ZXQnKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIXRoaXMuZGF0YUNoYW5uZWxPcGVuZWQpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignRGF0YSBjaGFubmVsIGlzIG5vdCBvcGVuZWQnKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zb2xlLmluZm8oXCJTZW5kaW5nIHRocm91Z2ggZGF0YSBjaGFubmVsOiBcIiArIGRhdGEpO1xuICAgICAgICB0aGlzLndwLnNlbmQoZGF0YSk7XG4gICAgfVxuXG4gICAgZ2V0V3JTdHJlYW0oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLndyU3RyZWFtO1xuICAgIH1cblxuICAgIGdldFdlYlJ0Y1BlZXIoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLndwO1xuICAgIH1cblxuICAgIGFkZEV2ZW50TGlzdGVuZXIoZXZlbnROYW1lOiBzdHJpbmcsIGxpc3RlbmVyOiBhbnkpIHtcbiAgICAgICAgdGhpcy5lZS5hZGRMaXN0ZW5lcihldmVudE5hbWUsIGxpc3RlbmVyKTtcbiAgICB9XG5cbiAgICBhZGRPbmNlRXZlbnRMaXN0ZW5lcihldmVudE5hbWU6IHN0cmluZywgbGlzdGVuZXI6IGFueSkge1xuICAgICAgICB0aGlzLmVlLmFkZE9uY2VMaXN0ZW5lcihldmVudE5hbWUsIGxpc3RlbmVyKTtcbiAgICB9XG5cbiAgICByZW1vdmVMaXN0ZW5lcihldmVudE5hbWUpIHtcbiAgICAgICAgdGhpcy5lZS5yZW1vdmVBbGxMaXN0ZW5lcnMoZXZlbnROYW1lKTtcbiAgICB9XG5cbiAgICBzaG93U3Bpbm5lcihzcGlubmVyUGFyZW50SWQ6IHN0cmluZykge1xuICAgICAgICBsZXQgcHJvZ3Jlc3MgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgICAgcHJvZ3Jlc3MuaWQgPSAncHJvZ3Jlc3MtJyArIHRoaXMuZ2V0SWQoKTtcbiAgICAgICAgcHJvZ3Jlc3Muc3R5bGUuYmFja2dyb3VuZCA9IFwiY2VudGVyIHRyYW5zcGFyZW50IHVybCgnaW1nL3NwaW5uZXIuZ2lmJykgbm8tcmVwZWF0XCI7XG4gICAgICAgIGxldCBzcGlubmVyUGFyZW50ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoc3Bpbm5lclBhcmVudElkKTtcbiAgICAgICAgaWYgKHNwaW5uZXJQYXJlbnQpIHtcbiAgICAgICAgICAgIHNwaW5uZXJQYXJlbnQuYXBwZW5kQ2hpbGQocHJvZ3Jlc3MpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgaGlkZVNwaW5uZXIoc3Bpbm5lcklkPzogc3RyaW5nKSB7XG4gICAgICAgIHNwaW5uZXJJZCA9IChzcGlubmVySWQgPT09IHVuZGVmaW5lZCkgPyB0aGlzLmdldElkKCkgOiBzcGlubmVySWQ7XG4gICAgICAgIGhpZGUoJ3Byb2dyZXNzLScgKyBzcGlubmVySWQpO1xuICAgIH1cblxuICAgIHBsYXlPbmx5VmlkZW8ocGFyZW50RWxlbWVudCwgdGh1bWJuYWlsSWQpIHtcblxuICAgICAgICAvLyBUTy1ETzogY2hlY2sgc29tZWhvdyBpZiB0aGUgc3RyZWFtIGlzIGF1ZGlvIG9ubHksIHNvIHRoZSBlbGVtZW50IGNyZWF0ZWQgaXMgPGF1ZGlvPiBpbnN0ZWFkIG9mIDx2aWRlbz5cblxuICAgICAgICB0aGlzLnZpZGVvID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgndmlkZW8nKTtcblxuICAgICAgICB0aGlzLnZpZGVvLmlkID0gKHRoaXMubG9jYWwgPyAnbG9jYWwtJyA6ICdyZW1vdGUtJykgKyAndmlkZW8tJyArIHRoaXMuZ2V0SWQoKTtcbiAgICAgICAgdGhpcy52aWRlby5hdXRvcGxheSA9IHRydWU7XG4gICAgICAgIHRoaXMudmlkZW8uY29udHJvbHMgPSBmYWxzZTtcbiAgICAgICAgdGhpcy52aWRlby5zcmNPYmplY3QgPSB0aGlzLnZpZGVvU3JjT2JqZWN0O1xuXG4gICAgICAgIHRoaXMudmlkZW9FbGVtZW50cy5wdXNoKHtcbiAgICAgICAgICAgIHRodW1iOiB0aHVtYm5haWxJZCxcbiAgICAgICAgICAgIHZpZGVvOiB0aGlzLnZpZGVvXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGlmICh0aGlzLmxvY2FsICYmICF0aGlzLmRpc3BsYXlNeVJlbW90ZSgpKSB7XG4gICAgICAgICAgICB0aGlzLnZpZGVvLm11dGVkID0gdHJ1ZTtcbiAgICAgICAgICAgIHRoaXMudmlkZW8ub25wbGF5aW5nID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIkxvY2FsICdTdHJlYW0nIHdpdGggaWQgW1wiICsgdGhpcy5nZXRJZCgpICsgXCJdIHZpZGVvIGlzIG5vdyBwbGF5aW5nXCIpO1xuICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCd2aWRlby1pcy1wbGF5aW5nJywgW3tcbiAgICAgICAgICAgICAgICAgICAgZWxlbWVudDogdGhpcy52aWRlb1xuICAgICAgICAgICAgICAgIH1dKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnZpZGVvLnRpdGxlID0gdGhpcy5nZXRJZCgpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHR5cGVvZiBwYXJlbnRFbGVtZW50ID09PSBcInN0cmluZ1wiKSB7XG4gICAgICAgICAgICB0aGlzLnBhcmVudElkID0gcGFyZW50RWxlbWVudDtcblxuICAgICAgICAgICAgbGV0IHBhcmVudEVsZW1lbnREb20gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChwYXJlbnRFbGVtZW50KTtcbiAgICAgICAgICAgIGlmIChwYXJlbnRFbGVtZW50RG9tKSB7XG4gICAgICAgICAgICAgICAgdGhpcy52aWRlbyA9IHBhcmVudEVsZW1lbnREb20uYXBwZW5kQ2hpbGQodGhpcy52aWRlbyk7XG4gICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3ZpZGVvLWVsZW1lbnQtY3JlYXRlZC1ieS1zdHJlYW0nLCBbe1xuICAgICAgICAgICAgICAgICAgICBlbGVtZW50OiB0aGlzLnZpZGVvXG4gICAgICAgICAgICAgICAgfV0pO1xuICAgICAgICAgICAgICAgIHRoaXMuaXNWaWRlb0VMZW1lbnRDcmVhdGVkID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMucGFyZW50SWQgPSBwYXJlbnRFbGVtZW50LmlkO1xuICAgICAgICAgICAgdGhpcy52aWRlbyA9IHBhcmVudEVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy52aWRlbyk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgnc3RyZWFtLWNyZWF0ZWQtYnktcHVibGlzaGVyJyk7XG5cbiAgICAgICAgdGhpcy5pc1JlYWR5ID0gdHJ1ZTtcblxuICAgICAgICByZXR1cm4gdGhpcy52aWRlbztcbiAgICB9XG5cbiAgICBwbGF5VGh1bWJuYWlsKHRodW1ibmFpbElkKSB7XG5cbiAgICAgICAgbGV0IGNvbnRhaW5lciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgICBjb250YWluZXIuY2xhc3NOYW1lID0gXCJwYXJ0aWNpcGFudFwiO1xuICAgICAgICBjb250YWluZXIuaWQgPSB0aGlzLmdldElkKCk7XG4gICAgICAgIGxldCB0aHVtYm5haWwgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCh0aHVtYm5haWxJZCk7XG4gICAgICAgIGlmICh0aHVtYm5haWwpIHtcbiAgICAgICAgICAgIHRodW1ibmFpbC5hcHBlbmRDaGlsZChjb250YWluZXIpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5lbGVtZW50cy5wdXNoKGNvbnRhaW5lcik7XG5cbiAgICAgICAgbGV0IG5hbWUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgICAgY29udGFpbmVyLmFwcGVuZENoaWxkKG5hbWUpO1xuICAgICAgICBsZXQgdXNlck5hbWUgPSB0aGlzLmdldElkKCkucmVwbGFjZSgnX3dlYmNhbScsICcnKTtcbiAgICAgICAgaWYgKHVzZXJOYW1lLmxlbmd0aCA+PSAxNikge1xuICAgICAgICAgICAgdXNlck5hbWUgPSB1c2VyTmFtZS5zdWJzdHJpbmcoMCwgMTYpICsgXCIuLi5cIjtcbiAgICAgICAgfVxuICAgICAgICBuYW1lLmFwcGVuZENoaWxkKGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKHVzZXJOYW1lKSk7XG4gICAgICAgIG5hbWUuaWQgPSBcIm5hbWUtXCIgKyB0aGlzLmdldElkKCk7XG4gICAgICAgIG5hbWUuY2xhc3NOYW1lID0gXCJuYW1lXCI7XG4gICAgICAgIG5hbWUudGl0bGUgPSB0aGlzLmdldElkKCk7XG5cbiAgICAgICAgdGhpcy5zaG93U3Bpbm5lcih0aHVtYm5haWxJZCk7XG5cbiAgICAgICAgcmV0dXJuIHRoaXMucGxheU9ubHlWaWRlbyhjb250YWluZXIsIHRodW1ibmFpbElkKTtcbiAgICB9XG5cbiAgICBnZXRJZEluUGFydGljaXBhbnQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmlkO1xuICAgIH1cblxuICAgIGdldFBhcnRpY2lwYW50KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5jb25uZWN0aW9uO1xuICAgIH1cblxuICAgIGdldElkKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5jb25uZWN0aW9uLmNvbm5lY3Rpb25JZCArIFwiX1wiICsgdGhpcy5pZDtcbiAgICB9XG5cbiAgICBnZXRSVENQZWVyQ29ubmVjdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0V2ViUnRjUGVlcigpLnBlZXJDb25uZWN0aW9uO1xuICAgIH1cblxuICAgIHJlcXVlc3RDYW1lcmFBY2Nlc3MoY2FsbGJhY2s6IENhbGxiYWNrPFN0cmVhbT4pIHtcblxuICAgICAgICB0aGlzLmNvbm5lY3Rpb24uYWRkU3RyZWFtKHRoaXMpO1xuXG4gICAgICAgIGxldCBjb25zdHJhaW50cyA9IHRoaXMubWVkaWFDb25zdHJhaW50cztcblxuICAgICAgICAvKmxldCBjb25zdHJhaW50czIgPSB7XG4gICAgICAgICAgICBhdWRpbzogdHJ1ZSxcbiAgICAgICAgICAgIHZpZGVvOiB7XG4gICAgICAgICAgICAgICAgd2lkdGg6IHtcbiAgICAgICAgICAgICAgICAgICAgaWRlYWw6IDEyODBcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIGZyYW1lUmF0ZToge1xuICAgICAgICAgICAgICAgICAgICBpZGVhbDogMTVcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH07Ki9cblxuICAgICAgICB0aGlzLnVzZXJNZWRpYUhhc1ZpZGVvKChoYXNWaWRlbykgPT4ge1xuICAgICAgICAgICAgaWYgKCFoYXNWaWRlbykge1xuICAgICAgICAgICAgICAgIGNvbnN0cmFpbnRzLnZpZGVvID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgdGhpcy5zZW5kVmlkZW8gPSBmYWxzZTtcbiAgICAgICAgICAgICAgICB0aGlzLnJlcXVlc3RDYW1lcmFBY2Nlc0F1eChjb25zdHJhaW50cywgY2FsbGJhY2spO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLnJlcXVlc3RDYW1lcmFBY2Nlc0F1eChjb25zdHJhaW50cywgY2FsbGJhY2spO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHJlcXVlc3RDYW1lcmFBY2Nlc0F1eChjb25zdHJhaW50cywgY2FsbGJhY2spIHtcbiAgICAgICAgbmF2aWdhdG9yLm1lZGlhRGV2aWNlcy5nZXRVc2VyTWVkaWEoY29uc3RyYWludHMpXG4gICAgICAgICAgICAudGhlbih1c2VyU3RyZWFtID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmNhbWVyYUFjY2Vzc1N1Y2Nlc3ModXNlclN0cmVhbSwgY2FsbGJhY2spO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgLyovLyAgVHJ5IHRvIGFzayBmb3IgbWljcm9waG9uZSBvbmx5XG4gICAgICAgICAgICAgICAgbmF2aWdhdG9yLm1lZGlhRGV2aWNlcy5nZXRVc2VyTWVkaWEoeyBhdWRpbzogdHJ1ZSwgdmlkZW86IGZhbHNlIH0pXG4gICAgICAgICAgICAgICAgICAgIC50aGVuKHVzZXJTdHJlYW0gPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3RyYWludHMudmlkZW8gPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2VuZFZpZGVvID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNlbmRBdWRpbyA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNhbWVyYUFjY2Vzc1N1Y2Nlc3ModXNlclN0cmVhbSwgY2FsbGJhY2spO1xuICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4geyovXG4gICAgICAgICAgICAgICAgdGhpcy5hY2Nlc3NJc0RlbmllZCA9IHRydWU7XG4gICAgICAgICAgICAgICAgdGhpcy5hY2Nlc3NJc0FsbG93ZWQgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgnYWNjZXNzLWRlbmllZC1ieS1wdWJsaXNoZXInKTtcblxuICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoXCJBY2Nlc3MgZGVuaWVkXCIsIGVycm9yKTtcbiAgICAgICAgICAgICAgICBjYWxsYmFjayhlcnJvciwgdGhpcyk7XG4gICAgICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGNhbWVyYUFjY2Vzc1N1Y2Nlc3ModXNlclN0cmVhbSwgY2FsbGJhY2spIHtcbiAgICAgICAgdGhpcy5hY2Nlc3NJc0FsbG93ZWQgPSB0cnVlO1xuICAgICAgICB0aGlzLmFjY2Vzc0lzRGVuaWVkID0gZmFsc2U7XG4gICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdhY2Nlc3MtYWxsb3dlZC1ieS1wdWJsaXNoZXInKTtcblxuICAgICAgICBpZiAodXNlclN0cmVhbS5nZXRBdWRpb1RyYWNrcygpWzBdICE9IG51bGwpIHtcbiAgICAgICAgICAgIHVzZXJTdHJlYW0uZ2V0QXVkaW9UcmFja3MoKVswXS5lbmFibGVkID0gdGhpcy5hY3RpdmVBdWRpbztcbiAgICAgICAgfVxuICAgICAgICBpZiAodXNlclN0cmVhbS5nZXRWaWRlb1RyYWNrcygpWzBdICE9IG51bGwpIHtcbiAgICAgICAgICAgIHVzZXJTdHJlYW0uZ2V0VmlkZW9UcmFja3MoKVswXS5lbmFibGVkID0gdGhpcy5hY3RpdmVWaWRlbztcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMud3JTdHJlYW0gPSB1c2VyU3RyZWFtO1xuICAgICAgICB0aGlzLmVtaXRTcmNFdmVudCh0aGlzLndyU3RyZWFtKTtcblxuICAgICAgICBjYWxsYmFjayh1bmRlZmluZWQsIHRoaXMpO1xuICAgIH1cblxuICAgIHByaXZhdGUgdXNlck1lZGlhSGFzVmlkZW8oY2FsbGJhY2spIHtcbiAgICAgICAgbmF2aWdhdG9yLm1lZGlhRGV2aWNlcy5lbnVtZXJhdGVEZXZpY2VzKCkudGhlbihmdW5jdGlvbiAobWVkaWFEZXZpY2VzKSB7XG4gICAgICAgICAgICB2YXIgdmlkZW9JbnB1dCA9IG1lZGlhRGV2aWNlcy5maWx0ZXIoZnVuY3Rpb24gKGRldmljZUluZm8pIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZGV2aWNlSW5mby5raW5kID09PSAndmlkZW9pbnB1dCc7XG4gICAgICAgICAgICB9KVswXTtcbiAgICAgICAgICAgIGNhbGxiYWNrKHZpZGVvSW5wdXQgIT0gbnVsbCk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHB1Ymxpc2hWaWRlb0NhbGxiYWNrKGVycm9yLCBzZHBPZmZlclBhcmFtLCB3cCkge1xuXG4gICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgcmV0dXJuIGNvbnNvbGUuZXJyb3IoXCIocHVibGlzaCkgU0RQIG9mZmVyIGVycm9yOiBcIlxuICAgICAgICAgICAgICAgICsgSlNPTi5zdHJpbmdpZnkoZXJyb3IpKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnNvbGUuZGVidWcoXCJTZW5kaW5nIFNEUCBvZmZlciB0byBwdWJsaXNoIGFzIFwiXG4gICAgICAgICAgICArIHRoaXMuZ2V0SWQoKSwgc2RwT2ZmZXJQYXJhbSk7XG5cbiAgICAgICAgdGhpcy5vcGVuVmlkdS5zZW5kUmVxdWVzdChcInB1Ymxpc2hWaWRlb1wiLCB7XG4gICAgICAgICAgICBzZHBPZmZlcjogc2RwT2ZmZXJQYXJhbSxcbiAgICAgICAgICAgIGRvTG9vcGJhY2s6IHRoaXMuZGlzcGxheU15UmVtb3RlKCkgfHwgZmFsc2UsXG4gICAgICAgICAgICBhdWRpb0FjdGl2ZTogdGhpcy5zZW5kQXVkaW8sXG4gICAgICAgICAgICB2aWRlb0FjdGl2ZTogdGhpcy5zZW5kVmlkZW9cbiAgICAgICAgfSwgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihcIkVycm9yIG9uIHB1Ymxpc2hWaWRlbzogXCIgKyBKU09OLnN0cmluZ2lmeShlcnJvcikpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLnByb2Nlc3NTZHBBbnN3ZXIocmVzcG9uc2Uuc2RwQW5zd2VyKTtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCInUHVibGlzaGVyJyBzdWNjZXNmdWxseSBwdWJsaXNoZWQgdG8gc2Vzc2lvblwiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgc3RhcnRWaWRlb0NhbGxiYWNrKGVycm9yLCBzZHBPZmZlclBhcmFtLCB3cCkge1xuICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgIHJldHVybiBjb25zb2xlLmVycm9yKFwiKHN1YnNjcmliZSkgU0RQIG9mZmVyIGVycm9yOiBcIlxuICAgICAgICAgICAgICAgICsgSlNPTi5zdHJpbmdpZnkoZXJyb3IpKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zb2xlLmRlYnVnKFwiU2VuZGluZyBTRFAgb2ZmZXIgdG8gc3Vic2NyaWJlIHRvIFwiXG4gICAgICAgICAgICArIHRoaXMuZ2V0SWQoKSwgc2RwT2ZmZXJQYXJhbSk7XG4gICAgICAgIHRoaXMub3BlblZpZHUuc2VuZFJlcXVlc3QoXCJyZWNlaXZlVmlkZW9Gcm9tXCIsIHtcbiAgICAgICAgICAgIHNlbmRlcjogdGhpcy5nZXRJZCgpLFxuICAgICAgICAgICAgc2RwT2ZmZXI6IHNkcE9mZmVyUGFyYW1cbiAgICAgICAgfSwgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihcIkVycm9yIG9uIHJlY3ZWaWRlb0Zyb206IFwiICsgSlNPTi5zdHJpbmdpZnkoZXJyb3IpKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5wcm9jZXNzU2RwQW5zd2VyKHJlc3BvbnNlLnNkcEFuc3dlcik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHByaXZhdGUgaW5pdFdlYlJ0Y1BlZXIoc2RwT2ZmZXJDYWxsYmFjaykge1xuICAgICAgICBpZiAodGhpcy5sb2NhbCkge1xuXG4gICAgICAgICAgICBsZXQgdXNlck1lZGlhQ29uc3RyYWludHMgPSB7XG4gICAgICAgICAgICAgICAgYXVkaW86IHRoaXMuc2VuZEF1ZGlvLFxuICAgICAgICAgICAgICAgIHZpZGVvOiB0aGlzLnNlbmRWaWRlb1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBsZXQgb3B0aW9uczogYW55ID0ge1xuICAgICAgICAgICAgICAgIHZpZGVvU3RyZWFtOiB0aGlzLndyU3RyZWFtLFxuICAgICAgICAgICAgICAgIG1lZGlhQ29uc3RyYWludHM6IHVzZXJNZWRpYUNvbnN0cmFpbnRzLFxuICAgICAgICAgICAgICAgIG9uaWNlY2FuZGlkYXRlOiB0aGlzLmNvbm5lY3Rpb24uc2VuZEljZUNhbmRpZGF0ZS5iaW5kKHRoaXMuY29ubmVjdGlvbiksXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmICh0aGlzLmRhdGFDaGFubmVsKSB7XG4gICAgICAgICAgICAgICAgb3B0aW9ucy5kYXRhQ2hhbm5lbENvbmZpZyA9IHtcbiAgICAgICAgICAgICAgICAgICAgaWQ6IHRoaXMuZ2V0Q2hhbm5lbE5hbWUoKSxcbiAgICAgICAgICAgICAgICAgICAgb25vcGVuOiB0aGlzLm9uRGF0YUNoYW5uZWxPcGVuLFxuICAgICAgICAgICAgICAgICAgICBvbmNsb3NlOiB0aGlzLm9uRGF0YUNoYW5uZWxDbG9zZWRcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIG9wdGlvbnMuZGF0YUNoYW5uZWxzID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKHRoaXMuZGlzcGxheU15UmVtb3RlKCkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLndwID0ga3VyZW50b1V0aWxzLldlYlJ0Y1BlZXIuV2ViUnRjUGVlclNlbmRyZWN2KG9wdGlvbnMsIGVycm9yID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgdGhpcy53cC5nZW5lcmF0ZU9mZmVyKHNkcE9mZmVyQ2FsbGJhY2suYmluZCh0aGlzKSk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMud3AgPSBrdXJlbnRvVXRpbHMuV2ViUnRjUGVlci5XZWJSdGNQZWVyU2VuZG9ubHkob3B0aW9ucywgZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBjb25zb2xlLmVycm9yKGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB0aGlzLndwLmdlbmVyYXRlT2ZmZXIoc2RwT2ZmZXJDYWxsYmFjay5iaW5kKHRoaXMpKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGxldCBvZmZlckNvbnN0cmFpbnRzID0ge1xuICAgICAgICAgICAgICAgIGF1ZGlvOiB0aGlzLnJlY3ZBdWRpbyxcbiAgICAgICAgICAgICAgICB2aWRlbzogdGhpcy5yZWN2VmlkZW9cbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBjb25zb2xlLmRlYnVnKFwiJ1Nlc3Npb24uc3Vic2NyaWJlKFN0cmVhbSknIGNhbGxlZC4gQ29uc3RyYWludHMgb2YgZ2VuZXJhdGUgU0RQIG9mZmVyXCIsXG4gICAgICAgICAgICAgICAgb2ZmZXJDb25zdHJhaW50cyk7XG4gICAgICAgICAgICBsZXQgb3B0aW9ucyA9IHtcbiAgICAgICAgICAgICAgICBvbmljZWNhbmRpZGF0ZTogdGhpcy5jb25uZWN0aW9uLnNlbmRJY2VDYW5kaWRhdGUuYmluZCh0aGlzLmNvbm5lY3Rpb24pLFxuICAgICAgICAgICAgICAgIG1lZGlhQ29uc3RyYWludHM6IG9mZmVyQ29uc3RyYWludHNcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMud3AgPSBrdXJlbnRvVXRpbHMuV2ViUnRjUGVlci5XZWJSdGNQZWVyUmVjdm9ubHkob3B0aW9ucywgZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMud3AuZ2VuZXJhdGVPZmZlcihzZHBPZmZlckNhbGxiYWNrLmJpbmQodGhpcykpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc29sZS5kZWJ1ZyhcIldhaXRpbmcgZm9yIFNEUCBvZmZlciB0byBiZSBnZW5lcmF0ZWQgKFwiXG4gICAgICAgICAgICArICh0aGlzLmxvY2FsID8gXCJsb2NhbFwiIDogXCJyZW1vdGVcIikgKyBcIiAnU3RyZWFtJzogXCIgKyB0aGlzLmdldElkKCkgKyBcIilcIik7XG4gICAgfVxuXG4gICAgcHVibGlzaCgpIHtcblxuICAgICAgICAvLyBGSVhNRTogVGhyb3cgZXJyb3Igd2hlbiBzdHJlYW0gaXMgbm90IGxvY2FsXG4gICAgICAgIGlmICh0aGlzLmlzUmVhZHkpIHtcbiAgICAgICAgICAgIHRoaXMuaW5pdFdlYlJ0Y1BlZXIodGhpcy5wdWJsaXNoVmlkZW9DYWxsYmFjayk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmVlLm9uY2UoJ3N0cmVhbS1yZWFkeScsIHN0cmVhbUV2ZW50ID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLnB1Ymxpc2goKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gRklYTUU6IE5vdyB3ZSBoYXZlIGNvdXBsZWQgY29ubmVjdGluZyB0byBhIHJvb20gYW5kIGFkZGluZyBhXG4gICAgICAgIC8vIHN0cmVhbSB0byB0aGlzIHJvb20uIEJ1dCBpbiB0aGUgbmV3IEFQSSwgdGhlcmUgYXJlIHR3byBzdGVwcy5cbiAgICAgICAgLy8gVGhpcyBpcyB0aGUgc2Vjb25kIHN0ZXAuIEZvciBub3csIGl0IGRvIG5vdGhpbmcuXG5cbiAgICB9XG5cbiAgICBzdWJzY3JpYmUoKSB7XG5cbiAgICAgICAgLy8gRklYTUU6IEluIHRoZSBjdXJyZW50IGltcGxlbWVudGF0aW9uIGFsbCBwYXJ0aWNpcGFudHMgYXJlIHN1YnNjcmliZWRcbiAgICAgICAgLy8gYXV0b21hdGljYWxseSB0byBhbGwgb3RoZXIgcGFydGljaXBhbnRzLiBXZSB1c2UgdGhpcyBtZXRob2Qgb25seSB0b1xuICAgICAgICAvLyBuZWdvdGlhdGUgU0RQXG5cbiAgICAgICAgdGhpcy5pbml0V2ViUnRjUGVlcih0aGlzLnN0YXJ0VmlkZW9DYWxsYmFjayk7XG4gICAgfVxuXG4gICAgcHJvY2Vzc1NkcEFuc3dlcihzZHBBbnN3ZXIpIHtcblxuICAgICAgICBsZXQgYW5zd2VyID0gbmV3IFJUQ1Nlc3Npb25EZXNjcmlwdGlvbih7XG4gICAgICAgICAgICB0eXBlOiAnYW5zd2VyJyxcbiAgICAgICAgICAgIHNkcDogc2RwQW5zd2VyLFxuICAgICAgICB9KTtcbiAgICAgICAgY29uc29sZS5kZWJ1Zyh0aGlzLmdldElkKCkgKyBcIjogc2V0IHBlZXIgY29ubmVjdGlvbiB3aXRoIHJlY3ZkIFNEUCBhbnN3ZXJcIixcbiAgICAgICAgICAgIHNkcEFuc3dlcik7XG4gICAgICAgIGxldCBwYXJ0aWNpcGFudElkID0gdGhpcy5nZXRJZCgpO1xuICAgICAgICBsZXQgcGMgPSB0aGlzLndwLnBlZXJDb25uZWN0aW9uO1xuICAgICAgICBwYy5zZXRSZW1vdGVEZXNjcmlwdGlvbihhbnN3ZXIsICgpID0+IHtcbiAgICAgICAgICAgIC8vIEF2b2lkcyB0byBzdWJzY3JpYmUgdG8geW91ciBvd24gc3RyZWFtIHJlbW90ZWx5IFxuICAgICAgICAgICAgLy8gZXhjZXB0IHdoZW4gc2hvd015UmVtb3RlIGlzIHRydWVcbiAgICAgICAgICAgIGlmICghdGhpcy5sb2NhbCB8fCB0aGlzLmRpc3BsYXlNeVJlbW90ZSgpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy53clN0cmVhbSA9IHBjLmdldFJlbW90ZVN0cmVhbXMoKVswXTtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmRlYnVnKFwiUGVlciByZW1vdGUgc3RyZWFtXCIsIHRoaXMud3JTdHJlYW0pO1xuXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMud3JTdHJlYW0gIT0gdW5kZWZpbmVkKSB7XG5cbiAgICAgICAgICAgICAgICAgICAgdGhpcy5lbWl0U3JjRXZlbnQodGhpcy53clN0cmVhbSk7XG5cbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zcGVlY2hFdmVudCA9IGt1cmVudG9VdGlscy5XZWJSdGNQZWVyLmhhcmsodGhpcy53clN0cmVhbSwgeyB0aHJlc2hvbGQ6IHRoaXMucm9vbS50aHJlc2hvbGRTcGVha2VyIH0pO1xuXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQub24oJ3NwZWFraW5nJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5yb29tLmFkZFBhcnRpY2lwYW50U3BlYWtpbmcocGFydGljaXBhbnRJZCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnJvb20uZW1pdEV2ZW50KCdzdHJlYW0tc3BlYWtpbmcnLCBbe1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcnRpY2lwYW50SWQ6IHBhcnRpY2lwYW50SWRcbiAgICAgICAgICAgICAgICAgICAgICAgIH1dKTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zcGVlY2hFdmVudC5vbignc3RvcHBlZF9zcGVha2luZycsICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucm9vbS5yZW1vdmVQYXJ0aWNpcGFudFNwZWFraW5nKHBhcnRpY2lwYW50SWQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5yb29tLmVtaXRFdmVudCgnc3RyZWFtLXN0b3BwZWQtc3BlYWtpbmcnLCBbe1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcnRpY2lwYW50SWQ6IHBhcnRpY2lwYW50SWRcbiAgICAgICAgICAgICAgICAgICAgICAgIH1dKTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGZvciAobGV0IHZpZGVvRWxlbWVudCBvZiB0aGlzLnZpZGVvRWxlbWVudHMpIHtcbiAgICAgICAgICAgICAgICAgICAgbGV0IHRodW1ibmFpbElkID0gdmlkZW9FbGVtZW50LnRodW1iO1xuICAgICAgICAgICAgICAgICAgICBsZXQgdmlkZW8gPSB2aWRlb0VsZW1lbnQudmlkZW87XG4gICAgICAgICAgICAgICAgICAgIHZpZGVvLnNyY09iamVjdCA9IHRoaXMud3JTdHJlYW07XG4gICAgICAgICAgICAgICAgICAgIHZpZGVvLm9ucGxheWluZyA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLmxvY2FsICYmIHRoaXMuZGlzcGxheU15UmVtb3RlKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJZb3VyIG93biByZW1vdGUgJ1N0cmVhbScgd2l0aCBpZCBbXCIgKyB0aGlzLmdldElkKCkgKyBcIl0gdmlkZW8gaXMgbm93IHBsYXlpbmdcIik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3JlbW90ZS12aWRlby1pcy1wbGF5aW5nJywgW3tcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxlbWVudDogdGhpcy52aWRlb1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1dKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoIXRoaXMubG9jYWwgJiYgIXRoaXMuZGlzcGxheU15UmVtb3RlKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJSZW1vdGUgJ1N0cmVhbScgd2l0aCBpZCBbXCIgKyB0aGlzLmdldElkKCkgKyBcIl0gdmlkZW8gaXMgbm93IHBsYXlpbmdcIik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3ZpZGVvLWlzLXBsYXlpbmcnLCBbe1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbGVtZW50OiB0aGlzLnZpZGVvXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfV0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgLy9zaG93KHRodW1ibmFpbElkKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vdGhpcy5oaWRlU3Bpbm5lcih0aGlzLmdldElkKCkpO1xuICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aGlzLnJvb20uZW1pdEV2ZW50KCdzdHJlYW0tc3Vic2NyaWJlZCcsIFt7XG4gICAgICAgICAgICAgICAgICAgIHN0cmVhbTogdGhpc1xuICAgICAgICAgICAgICAgIH1dKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSwgZXJyb3IgPT4ge1xuICAgICAgICAgICAgY29uc29sZS5lcnJvcih0aGlzLmdldElkKCkgKyBcIjogRXJyb3Igc2V0dGluZyBTRFAgdG8gdGhlIHBlZXIgY29ubmVjdGlvbjogXCJcbiAgICAgICAgICAgICAgICArIEpTT04uc3RyaW5naWZ5KGVycm9yKSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHVucHVibGlzaCgpIHtcbiAgICAgICAgaWYgKHRoaXMud3ApIHtcbiAgICAgICAgICAgIHRoaXMud3AuZGlzcG9zZSgpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaWYgKHRoaXMud3JTdHJlYW0pIHtcbiAgICAgICAgICAgICAgICB0aGlzLndyU3RyZWFtLmdldEF1ZGlvVHJhY2tzKCkuZm9yRWFjaChmdW5jdGlvbiAodHJhY2spIHtcbiAgICAgICAgICAgICAgICAgICAgdHJhY2suc3RvcCAmJiB0cmFjay5zdG9wKClcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIHRoaXMud3JTdHJlYW0uZ2V0VmlkZW9UcmFja3MoKS5mb3JFYWNoKGZ1bmN0aW9uICh0cmFjaykge1xuICAgICAgICAgICAgICAgICAgICB0cmFjay5zdG9wICYmIHRyYWNrLnN0b3AoKVxuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5zcGVlY2hFdmVudCkge1xuICAgICAgICAgICAgdGhpcy5zcGVlY2hFdmVudC5zdG9wKCk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zb2xlLmluZm8odGhpcy5nZXRJZCgpICsgXCI6IFN0cmVhbSAnXCIgKyB0aGlzLmlkICsgXCInIHVucHVibGlzaGVkXCIpO1xuICAgIH1cblxuICAgIGRpc3Bvc2UoKSB7XG5cbiAgICAgICAgZnVuY3Rpb24gZGlzcG9zZUVsZW1lbnQoZWxlbWVudCkge1xuICAgICAgICAgICAgaWYgKGVsZW1lbnQgJiYgZWxlbWVudC5wYXJlbnROb2RlKSB7XG4gICAgICAgICAgICAgICAgZWxlbWVudC5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKGVsZW1lbnQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5lbGVtZW50cy5mb3JFYWNoKGUgPT4gZGlzcG9zZUVsZW1lbnQoZSkpO1xuXG4gICAgICAgIC8vdGhpcy52aWRlb0VsZW1lbnRzLmZvckVhY2godmUgPT4gZGlzcG9zZUVsZW1lbnQodmUudmlkZW8pKTtcblxuICAgICAgICBkaXNwb3NlRWxlbWVudChcInByb2dyZXNzLVwiICsgdGhpcy5nZXRJZCgpKTtcblxuICAgICAgICBpZiAodGhpcy53cCkge1xuICAgICAgICAgICAgdGhpcy53cC5kaXNwb3NlKCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpZiAodGhpcy53clN0cmVhbSkge1xuICAgICAgICAgICAgICAgIHRoaXMud3JTdHJlYW0uZ2V0QXVkaW9UcmFja3MoKS5mb3JFYWNoKGZ1bmN0aW9uICh0cmFjaykge1xuICAgICAgICAgICAgICAgICAgICB0cmFjay5zdG9wICYmIHRyYWNrLnN0b3AoKVxuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgdGhpcy53clN0cmVhbS5nZXRWaWRlb1RyYWNrcygpLmZvckVhY2goZnVuY3Rpb24gKHRyYWNrKSB7XG4gICAgICAgICAgICAgICAgICAgIHRyYWNrLnN0b3AgJiYgdHJhY2suc3RvcCgpXG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLnNwZWVjaEV2ZW50KSB7XG4gICAgICAgICAgICB0aGlzLnNwZWVjaEV2ZW50LnN0b3AoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnNvbGUuaW5mbygodGhpcy5sb2NhbCA/IFwiTG9jYWwgXCIgOiBcIlJlbW90ZSBcIikgKyBcIidTdHJlYW0nIHdpdGggaWQgW1wiICsgdGhpcy5nZXRJZCgpICsgXCJdJyBoYXMgYmVlbiBzdWNjZXNmdWxseSBkaXNwb3NlZFwiKTtcbiAgICB9XG59XG4iXX0= +},{"../KurentoUtils/kurento-utils-js":43,"webrtc-adapter":21,"wolfy87-eventemitter":32}]},{},[44]) +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL25vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvZXZlbnRzL2V2ZW50cy5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9mcmVlaWNlL2luZGV4LmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL2ZyZWVpY2Uvc3R1bi5qc29uIiwiLi4vLi4vbm9kZV9tb2R1bGVzL2ZyZWVpY2UvdHVybi5qc29uIiwiLi4vLi4vbm9kZV9tb2R1bGVzL2hhcmsvaGFyay5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9pbmhlcml0cy9pbmhlcml0c19icm93c2VyLmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL21lcmdlL21lcmdlLmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL25vcm1hbGljZS9pbmRleC5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9zZHAtdHJhbnNmb3JtL2xpYi9ncmFtbWFyLmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL3NkcC10cmFuc2Zvcm0vbGliL2luZGV4LmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL3NkcC10cmFuc2Zvcm0vbGliL3BhcnNlci5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9zZHAtdHJhbnNmb3JtL2xpYi93cml0ZXIuanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvc2RwLXRyYW5zbGF0b3IvbGliL2FycmF5LWVxdWFscy5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9zZHAtdHJhbnNsYXRvci9saWIvaW5kZXguanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvc2RwLXRyYW5zbGF0b3IvbGliL2ludGVyb3AuanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvc2RwLXRyYW5zbGF0b3IvbGliL3RyYW5zZm9ybS5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9zZHAvc2RwLmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL3VhLXBhcnNlci1qcy9zcmMvdWEtcGFyc2VyLmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL3V1aWQvcm5nLWJyb3dzZXIuanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvdXVpZC91dWlkLmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL3dlYnJ0Yy1hZGFwdGVyL3NyYy9qcy9hZGFwdGVyX2NvcmUuanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvd2VicnRjLWFkYXB0ZXIvc3JjL2pzL2Nocm9tZS9jaHJvbWVfc2hpbS5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy93ZWJydGMtYWRhcHRlci9zcmMvanMvY2hyb21lL2dldHVzZXJtZWRpYS5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy93ZWJydGMtYWRhcHRlci9zcmMvanMvZWRnZS9lZGdlX3NoaW0uanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvd2VicnRjLWFkYXB0ZXIvc3JjL2pzL2VkZ2UvZ2V0dXNlcm1lZGlhLmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL3dlYnJ0Yy1hZGFwdGVyL3NyYy9qcy9lZGdlL3J0Y3BlZXJjb25uZWN0aW9uX3NoaW0uanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvd2VicnRjLWFkYXB0ZXIvc3JjL2pzL2ZpcmVmb3gvZmlyZWZveF9zaGltLmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL3dlYnJ0Yy1hZGFwdGVyL3NyYy9qcy9maXJlZm94L2dldHVzZXJtZWRpYS5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy93ZWJydGMtYWRhcHRlci9zcmMvanMvc2FmYXJpL3NhZmFyaV9zaGltLmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL3dlYnJ0Yy1hZGFwdGVyL3NyYy9qcy91dGlscy5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy93aWxkZW1pdHRlci93aWxkZW1pdHRlci5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy93b2xmeTg3LWV2ZW50ZW1pdHRlci9FdmVudEVtaXR0ZXIuanMiLCIuLi9LdXJlbnRvVXRpbHMva3VyZW50by1qc29ucnBjL01hcHBlci5qcyIsIi4uL0t1cmVudG9VdGlscy9rdXJlbnRvLWpzb25ycGMvY2xpZW50cy9pbmRleC5qcyIsIi4uL0t1cmVudG9VdGlscy9rdXJlbnRvLWpzb25ycGMvY2xpZW50cy9qc29ucnBjY2xpZW50LmpzIiwiLi4vS3VyZW50b1V0aWxzL2t1cmVudG8tanNvbnJwYy9jbGllbnRzL3RyYW5zcG9ydHMvaW5kZXguanMiLCIuLi9LdXJlbnRvVXRpbHMva3VyZW50by1qc29ucnBjL2NsaWVudHMvdHJhbnNwb3J0cy93ZWJTb2NrZXRXaXRoUmVjb25uZWN0aW9uLmpzIiwiLi4vS3VyZW50b1V0aWxzL2t1cmVudG8tanNvbnJwYy9pbmRleC5qcyIsIi4uL0t1cmVudG9VdGlscy9rdXJlbnRvLWpzb25ycGMvcGFja2Vycy9Kc29uUlBDLmpzIiwiLi4vS3VyZW50b1V0aWxzL2t1cmVudG8tanNvbnJwYy9wYWNrZXJzL1htbFJQQy5qcyIsIi4uL0t1cmVudG9VdGlscy9rdXJlbnRvLWpzb25ycGMvcGFja2Vycy9pbmRleC5qcyIsIi4uL0t1cmVudG9VdGlscy9rdXJlbnRvLXV0aWxzLWpzL1dlYlJ0Y1BlZXIuanMiLCIuLi9LdXJlbnRvVXRpbHMva3VyZW50by11dGlscy1qcy9pbmRleC5qcyIsIk1haW4udHMiLCJPcGVuVmlkdS50cyIsIlB1Ymxpc2hlci50cyIsIlNlc3Npb24udHMiLCJTdWJzY3JpYmVyLnRzIiwiLi4vT3BlblZpZHVJbnRlcm5hbC9Db25uZWN0aW9uLnRzIiwiLi4vT3BlblZpZHVJbnRlcm5hbC9PcGVuVmlkdUludGVybmFsLnRzIiwiLi4vT3BlblZpZHVJbnRlcm5hbC9TZXNzaW9uSW50ZXJuYWwudHMiLCIuLi9PcGVuVmlkdUludGVybmFsL1N0cmVhbS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtBQ0FBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5U0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaEJBO0FBQ0E7O0FDREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNySUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5S0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNURBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqUUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzdGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsSEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbjNCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5bEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQ3pnQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDaENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZMQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbEdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4VkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFOQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN3ZDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzlMQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsS0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdktBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FB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ZWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlc0NvbnRlbnQiOlsiKGZ1bmN0aW9uIGUodCxuLHIpe2Z1bmN0aW9uIHMobyx1KXtpZighbltvXSl7aWYoIXRbb10pe3ZhciBhPXR5cGVvZiByZXF1aXJlPT1cImZ1bmN0aW9uXCImJnJlcXVpcmU7aWYoIXUmJmEpcmV0dXJuIGEobywhMCk7aWYoaSlyZXR1cm4gaShvLCEwKTt2YXIgZj1uZXcgRXJyb3IoXCJDYW5ub3QgZmluZCBtb2R1bGUgJ1wiK28rXCInXCIpO3Rocm93IGYuY29kZT1cIk1PRFVMRV9OT1RfRk9VTkRcIixmfXZhciBsPW5bb109e2V4cG9ydHM6e319O3Rbb11bMF0uY2FsbChsLmV4cG9ydHMsZnVuY3Rpb24oZSl7dmFyIG49dFtvXVsxXVtlXTtyZXR1cm4gcyhuP246ZSl9LGwsbC5leHBvcnRzLGUsdCxuLHIpfXJldHVybiBuW29dLmV4cG9ydHN9dmFyIGk9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtmb3IodmFyIG89MDtvPHIubGVuZ3RoO28rKylzKHJbb10pO3JldHVybiBzfSkiLCIvLyBDb3B5cmlnaHQgSm95ZW50LCBJbmMuIGFuZCBvdGhlciBOb2RlIGNvbnRyaWJ1dG9ycy5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYVxuLy8gY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZVxuLy8gXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nXG4vLyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsXG4vLyBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0XG4vLyBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGVcbi8vIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkXG4vLyBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTXG4vLyBPUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GXG4vLyBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOXG4vLyBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSxcbi8vIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUlxuLy8gT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRVxuLy8gVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS5cblxuZnVuY3Rpb24gRXZlbnRFbWl0dGVyKCkge1xuICB0aGlzLl9ldmVudHMgPSB0aGlzLl9ldmVudHMgfHwge307XG4gIHRoaXMuX21heExpc3RlbmVycyA9IHRoaXMuX21heExpc3RlbmVycyB8fCB1bmRlZmluZWQ7XG59XG5tb2R1bGUuZXhwb3J0cyA9IEV2ZW50RW1pdHRlcjtcblxuLy8gQmFja3dhcmRzLWNvbXBhdCB3aXRoIG5vZGUgMC4xMC54XG5FdmVudEVtaXR0ZXIuRXZlbnRFbWl0dGVyID0gRXZlbnRFbWl0dGVyO1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLl9ldmVudHMgPSB1bmRlZmluZWQ7XG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLl9tYXhMaXN0ZW5lcnMgPSB1bmRlZmluZWQ7XG5cbi8vIEJ5IGRlZmF1bHQgRXZlbnRFbWl0dGVycyB3aWxsIHByaW50IGEgd2FybmluZyBpZiBtb3JlIHRoYW4gMTAgbGlzdGVuZXJzIGFyZVxuLy8gYWRkZWQgdG8gaXQuIFRoaXMgaXMgYSB1c2VmdWwgZGVmYXVsdCB3aGljaCBoZWxwcyBmaW5kaW5nIG1lbW9yeSBsZWFrcy5cbkV2ZW50RW1pdHRlci5kZWZhdWx0TWF4TGlzdGVuZXJzID0gMTA7XG5cbi8vIE9idmlvdXNseSBub3QgYWxsIEVtaXR0ZXJzIHNob3VsZCBiZSBsaW1pdGVkIHRvIDEwLiBUaGlzIGZ1bmN0aW9uIGFsbG93c1xuLy8gdGhhdCB0byBiZSBpbmNyZWFzZWQuIFNldCB0byB6ZXJvIGZvciB1bmxpbWl0ZWQuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLnNldE1heExpc3RlbmVycyA9IGZ1bmN0aW9uKG4pIHtcbiAgaWYgKCFpc051bWJlcihuKSB8fCBuIDwgMCB8fCBpc05hTihuKSlcbiAgICB0aHJvdyBUeXBlRXJyb3IoJ24gbXVzdCBiZSBhIHBvc2l0aXZlIG51bWJlcicpO1xuICB0aGlzLl9tYXhMaXN0ZW5lcnMgPSBuO1xuICByZXR1cm4gdGhpcztcbn07XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuZW1pdCA9IGZ1bmN0aW9uKHR5cGUpIHtcbiAgdmFyIGVyLCBoYW5kbGVyLCBsZW4sIGFyZ3MsIGksIGxpc3RlbmVycztcblxuICBpZiAoIXRoaXMuX2V2ZW50cylcbiAgICB0aGlzLl9ldmVudHMgPSB7fTtcblxuICAvLyBJZiB0aGVyZSBpcyBubyAnZXJyb3InIGV2ZW50IGxpc3RlbmVyIHRoZW4gdGhyb3cuXG4gIGlmICh0eXBlID09PSAnZXJyb3InKSB7XG4gICAgaWYgKCF0aGlzLl9ldmVudHMuZXJyb3IgfHxcbiAgICAgICAgKGlzT2JqZWN0KHRoaXMuX2V2ZW50cy5lcnJvcikgJiYgIXRoaXMuX2V2ZW50cy5lcnJvci5sZW5ndGgpKSB7XG4gICAgICBlciA9IGFyZ3VtZW50c1sxXTtcbiAgICAgIGlmIChlciBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICAgIHRocm93IGVyOyAvLyBVbmhhbmRsZWQgJ2Vycm9yJyBldmVudFxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gQXQgbGVhc3QgZ2l2ZSBzb21lIGtpbmQgb2YgY29udGV4dCB0byB0aGUgdXNlclxuICAgICAgICB2YXIgZXJyID0gbmV3IEVycm9yKCdVbmNhdWdodCwgdW5zcGVjaWZpZWQgXCJlcnJvclwiIGV2ZW50LiAoJyArIGVyICsgJyknKTtcbiAgICAgICAgZXJyLmNvbnRleHQgPSBlcjtcbiAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGhhbmRsZXIgPSB0aGlzLl9ldmVudHNbdHlwZV07XG5cbiAgaWYgKGlzVW5kZWZpbmVkKGhhbmRsZXIpKVxuICAgIHJldHVybiBmYWxzZTtcblxuICBpZiAoaXNGdW5jdGlvbihoYW5kbGVyKSkge1xuICAgIHN3aXRjaCAoYXJndW1lbnRzLmxlbmd0aCkge1xuICAgICAgLy8gZmFzdCBjYXNlc1xuICAgICAgY2FzZSAxOlxuICAgICAgICBoYW5kbGVyLmNhbGwodGhpcyk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAyOlxuICAgICAgICBoYW5kbGVyLmNhbGwodGhpcywgYXJndW1lbnRzWzFdKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDM6XG4gICAgICAgIGhhbmRsZXIuY2FsbCh0aGlzLCBhcmd1bWVudHNbMV0sIGFyZ3VtZW50c1syXSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgLy8gc2xvd2VyXG4gICAgICBkZWZhdWx0OlxuICAgICAgICBhcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKTtcbiAgICAgICAgaGFuZGxlci5hcHBseSh0aGlzLCBhcmdzKTtcbiAgICB9XG4gIH0gZWxzZSBpZiAoaXNPYmplY3QoaGFuZGxlcikpIHtcbiAgICBhcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKTtcbiAgICBsaXN0ZW5lcnMgPSBoYW5kbGVyLnNsaWNlKCk7XG4gICAgbGVuID0gbGlzdGVuZXJzLmxlbmd0aDtcbiAgICBmb3IgKGkgPSAwOyBpIDwgbGVuOyBpKyspXG4gICAgICBsaXN0ZW5lcnNbaV0uYXBwbHkodGhpcywgYXJncyk7XG4gIH1cblxuICByZXR1cm4gdHJ1ZTtcbn07XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuYWRkTGlzdGVuZXIgPSBmdW5jdGlvbih0eXBlLCBsaXN0ZW5lcikge1xuICB2YXIgbTtcblxuICBpZiAoIWlzRnVuY3Rpb24obGlzdGVuZXIpKVxuICAgIHRocm93IFR5cGVFcnJvcignbGlzdGVuZXIgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG5cbiAgaWYgKCF0aGlzLl9ldmVudHMpXG4gICAgdGhpcy5fZXZlbnRzID0ge307XG5cbiAgLy8gVG8gYXZvaWQgcmVjdXJzaW9uIGluIHRoZSBjYXNlIHRoYXQgdHlwZSA9PT0gXCJuZXdMaXN0ZW5lclwiISBCZWZvcmVcbiAgLy8gYWRkaW5nIGl0IHRvIHRoZSBsaXN0ZW5lcnMsIGZpcnN0IGVtaXQgXCJuZXdMaXN0ZW5lclwiLlxuICBpZiAodGhpcy5fZXZlbnRzLm5ld0xpc3RlbmVyKVxuICAgIHRoaXMuZW1pdCgnbmV3TGlzdGVuZXInLCB0eXBlLFxuICAgICAgICAgICAgICBpc0Z1bmN0aW9uKGxpc3RlbmVyLmxpc3RlbmVyKSA/XG4gICAgICAgICAgICAgIGxpc3RlbmVyLmxpc3RlbmVyIDogbGlzdGVuZXIpO1xuXG4gIGlmICghdGhpcy5fZXZlbnRzW3R5cGVdKVxuICAgIC8vIE9wdGltaXplIHRoZSBjYXNlIG9mIG9uZSBsaXN0ZW5lci4gRG9uJ3QgbmVlZCB0aGUgZXh0cmEgYXJyYXkgb2JqZWN0LlxuICAgIHRoaXMuX2V2ZW50c1t0eXBlXSA9IGxpc3RlbmVyO1xuICBlbHNlIGlmIChpc09iamVjdCh0aGlzLl9ldmVudHNbdHlwZV0pKVxuICAgIC8vIElmIHdlJ3ZlIGFscmVhZHkgZ290IGFuIGFycmF5LCBqdXN0IGFwcGVuZC5cbiAgICB0aGlzLl9ldmVudHNbdHlwZV0ucHVzaChsaXN0ZW5lcik7XG4gIGVsc2VcbiAgICAvLyBBZGRpbmcgdGhlIHNlY29uZCBlbGVtZW50LCBuZWVkIHRvIGNoYW5nZSB0byBhcnJheS5cbiAgICB0aGlzLl9ldmVudHNbdHlwZV0gPSBbdGhpcy5fZXZlbnRzW3R5cGVdLCBsaXN0ZW5lcl07XG5cbiAgLy8gQ2hlY2sgZm9yIGxpc3RlbmVyIGxlYWtcbiAgaWYgKGlzT2JqZWN0KHRoaXMuX2V2ZW50c1t0eXBlXSkgJiYgIXRoaXMuX2V2ZW50c1t0eXBlXS53YXJuZWQpIHtcbiAgICBpZiAoIWlzVW5kZWZpbmVkKHRoaXMuX21heExpc3RlbmVycykpIHtcbiAgICAgIG0gPSB0aGlzLl9tYXhMaXN0ZW5lcnM7XG4gICAgfSBlbHNlIHtcbiAgICAgIG0gPSBFdmVudEVtaXR0ZXIuZGVmYXVsdE1heExpc3RlbmVycztcbiAgICB9XG5cbiAgICBpZiAobSAmJiBtID4gMCAmJiB0aGlzLl9ldmVudHNbdHlwZV0ubGVuZ3RoID4gbSkge1xuICAgICAgdGhpcy5fZXZlbnRzW3R5cGVdLndhcm5lZCA9IHRydWU7XG4gICAgICBjb25zb2xlLmVycm9yKCcobm9kZSkgd2FybmluZzogcG9zc2libGUgRXZlbnRFbWl0dGVyIG1lbW9yeSAnICtcbiAgICAgICAgICAgICAgICAgICAgJ2xlYWsgZGV0ZWN0ZWQuICVkIGxpc3RlbmVycyBhZGRlZC4gJyArXG4gICAgICAgICAgICAgICAgICAgICdVc2UgZW1pdHRlci5zZXRNYXhMaXN0ZW5lcnMoKSB0byBpbmNyZWFzZSBsaW1pdC4nLFxuICAgICAgICAgICAgICAgICAgICB0aGlzLl9ldmVudHNbdHlwZV0ubGVuZ3RoKTtcbiAgICAgIGlmICh0eXBlb2YgY29uc29sZS50cmFjZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAvLyBub3Qgc3VwcG9ydGVkIGluIElFIDEwXG4gICAgICAgIGNvbnNvbGUudHJhY2UoKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gdGhpcztcbn07XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUub24gPSBFdmVudEVtaXR0ZXIucHJvdG90eXBlLmFkZExpc3RlbmVyO1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLm9uY2UgPSBmdW5jdGlvbih0eXBlLCBsaXN0ZW5lcikge1xuICBpZiAoIWlzRnVuY3Rpb24obGlzdGVuZXIpKVxuICAgIHRocm93IFR5cGVFcnJvcignbGlzdGVuZXIgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG5cbiAgdmFyIGZpcmVkID0gZmFsc2U7XG5cbiAgZnVuY3Rpb24gZygpIHtcbiAgICB0aGlzLnJlbW92ZUxpc3RlbmVyKHR5cGUsIGcpO1xuXG4gICAgaWYgKCFmaXJlZCkge1xuICAgICAgZmlyZWQgPSB0cnVlO1xuICAgICAgbGlzdGVuZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICB9XG4gIH1cblxuICBnLmxpc3RlbmVyID0gbGlzdGVuZXI7XG4gIHRoaXMub24odHlwZSwgZyk7XG5cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vLyBlbWl0cyBhICdyZW1vdmVMaXN0ZW5lcicgZXZlbnQgaWZmIHRoZSBsaXN0ZW5lciB3YXMgcmVtb3ZlZFxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5yZW1vdmVMaXN0ZW5lciA9IGZ1bmN0aW9uKHR5cGUsIGxpc3RlbmVyKSB7XG4gIHZhciBsaXN0LCBwb3NpdGlvbiwgbGVuZ3RoLCBpO1xuXG4gIGlmICghaXNGdW5jdGlvbihsaXN0ZW5lcikpXG4gICAgdGhyb3cgVHlwZUVycm9yKCdsaXN0ZW5lciBtdXN0IGJlIGEgZnVuY3Rpb24nKTtcblxuICBpZiAoIXRoaXMuX2V2ZW50cyB8fCAhdGhpcy5fZXZlbnRzW3R5cGVdKVxuICAgIHJldHVybiB0aGlzO1xuXG4gIGxpc3QgPSB0aGlzLl9ldmVudHNbdHlwZV07XG4gIGxlbmd0aCA9IGxpc3QubGVuZ3RoO1xuICBwb3NpdGlvbiA9IC0xO1xuXG4gIGlmIChsaXN0ID09PSBsaXN0ZW5lciB8fFxuICAgICAgKGlzRnVuY3Rpb24obGlzdC5saXN0ZW5lcikgJiYgbGlzdC5saXN0ZW5lciA9PT0gbGlzdGVuZXIpKSB7XG4gICAgZGVsZXRlIHRoaXMuX2V2ZW50c1t0eXBlXTtcbiAgICBpZiAodGhpcy5fZXZlbnRzLnJlbW92ZUxpc3RlbmVyKVxuICAgICAgdGhpcy5lbWl0KCdyZW1vdmVMaXN0ZW5lcicsIHR5cGUsIGxpc3RlbmVyKTtcblxuICB9IGVsc2UgaWYgKGlzT2JqZWN0KGxpc3QpKSB7XG4gICAgZm9yIChpID0gbGVuZ3RoOyBpLS0gPiAwOykge1xuICAgICAgaWYgKGxpc3RbaV0gPT09IGxpc3RlbmVyIHx8XG4gICAgICAgICAgKGxpc3RbaV0ubGlzdGVuZXIgJiYgbGlzdFtpXS5saXN0ZW5lciA9PT0gbGlzdGVuZXIpKSB7XG4gICAgICAgIHBvc2l0aW9uID0gaTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHBvc2l0aW9uIDwgMClcbiAgICAgIHJldHVybiB0aGlzO1xuXG4gICAgaWYgKGxpc3QubGVuZ3RoID09PSAxKSB7XG4gICAgICBsaXN0Lmxlbmd0aCA9IDA7XG4gICAgICBkZWxldGUgdGhpcy5fZXZlbnRzW3R5cGVdO1xuICAgIH0gZWxzZSB7XG4gICAgICBsaXN0LnNwbGljZShwb3NpdGlvbiwgMSk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuX2V2ZW50cy5yZW1vdmVMaXN0ZW5lcilcbiAgICAgIHRoaXMuZW1pdCgncmVtb3ZlTGlzdGVuZXInLCB0eXBlLCBsaXN0ZW5lcik7XG4gIH1cblxuICByZXR1cm4gdGhpcztcbn07XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUucmVtb3ZlQWxsTGlzdGVuZXJzID0gZnVuY3Rpb24odHlwZSkge1xuICB2YXIga2V5LCBsaXN0ZW5lcnM7XG5cbiAgaWYgKCF0aGlzLl9ldmVudHMpXG4gICAgcmV0dXJuIHRoaXM7XG5cbiAgLy8gbm90IGxpc3RlbmluZyBmb3IgcmVtb3ZlTGlzdGVuZXIsIG5vIG5lZWQgdG8gZW1pdFxuICBpZiAoIXRoaXMuX2V2ZW50cy5yZW1vdmVMaXN0ZW5lcikge1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAwKVxuICAgICAgdGhpcy5fZXZlbnRzID0ge307XG4gICAgZWxzZSBpZiAodGhpcy5fZXZlbnRzW3R5cGVdKVxuICAgICAgZGVsZXRlIHRoaXMuX2V2ZW50c1t0eXBlXTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8vIGVtaXQgcmVtb3ZlTGlzdGVuZXIgZm9yIGFsbCBsaXN0ZW5lcnMgb24gYWxsIGV2ZW50c1xuICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMCkge1xuICAgIGZvciAoa2V5IGluIHRoaXMuX2V2ZW50cykge1xuICAgICAgaWYgKGtleSA9PT0gJ3JlbW92ZUxpc3RlbmVyJykgY29udGludWU7XG4gICAgICB0aGlzLnJlbW92ZUFsbExpc3RlbmVycyhrZXkpO1xuICAgIH1cbiAgICB0aGlzLnJlbW92ZUFsbExpc3RlbmVycygncmVtb3ZlTGlzdGVuZXInKTtcbiAgICB0aGlzLl9ldmVudHMgPSB7fTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIGxpc3RlbmVycyA9IHRoaXMuX2V2ZW50c1t0eXBlXTtcblxuICBpZiAoaXNGdW5jdGlvbihsaXN0ZW5lcnMpKSB7XG4gICAgdGhpcy5yZW1vdmVMaXN0ZW5lcih0eXBlLCBsaXN0ZW5lcnMpO1xuICB9IGVsc2UgaWYgKGxpc3RlbmVycykge1xuICAgIC8vIExJRk8gb3JkZXJcbiAgICB3aGlsZSAobGlzdGVuZXJzLmxlbmd0aClcbiAgICAgIHRoaXMucmVtb3ZlTGlzdGVuZXIodHlwZSwgbGlzdGVuZXJzW2xpc3RlbmVycy5sZW5ndGggLSAxXSk7XG4gIH1cbiAgZGVsZXRlIHRoaXMuX2V2ZW50c1t0eXBlXTtcblxuICByZXR1cm4gdGhpcztcbn07XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUubGlzdGVuZXJzID0gZnVuY3Rpb24odHlwZSkge1xuICB2YXIgcmV0O1xuICBpZiAoIXRoaXMuX2V2ZW50cyB8fCAhdGhpcy5fZXZlbnRzW3R5cGVdKVxuICAgIHJldCA9IFtdO1xuICBlbHNlIGlmIChpc0Z1bmN0aW9uKHRoaXMuX2V2ZW50c1t0eXBlXSkpXG4gICAgcmV0ID0gW3RoaXMuX2V2ZW50c1t0eXBlXV07XG4gIGVsc2VcbiAgICByZXQgPSB0aGlzLl9ldmVudHNbdHlwZV0uc2xpY2UoKTtcbiAgcmV0dXJuIHJldDtcbn07XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUubGlzdGVuZXJDb3VudCA9IGZ1bmN0aW9uKHR5cGUpIHtcbiAgaWYgKHRoaXMuX2V2ZW50cykge1xuICAgIHZhciBldmxpc3RlbmVyID0gdGhpcy5fZXZlbnRzW3R5cGVdO1xuXG4gICAgaWYgKGlzRnVuY3Rpb24oZXZsaXN0ZW5lcikpXG4gICAgICByZXR1cm4gMTtcbiAgICBlbHNlIGlmIChldmxpc3RlbmVyKVxuICAgICAgcmV0dXJuIGV2bGlzdGVuZXIubGVuZ3RoO1xuICB9XG4gIHJldHVybiAwO1xufTtcblxuRXZlbnRFbWl0dGVyLmxpc3RlbmVyQ291bnQgPSBmdW5jdGlvbihlbWl0dGVyLCB0eXBlKSB7XG4gIHJldHVybiBlbWl0dGVyLmxpc3RlbmVyQ291bnQodHlwZSk7XG59O1xuXG5mdW5jdGlvbiBpc0Z1bmN0aW9uKGFyZykge1xuICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gJ2Z1bmN0aW9uJztcbn1cblxuZnVuY3Rpb24gaXNOdW1iZXIoYXJnKSB7XG4gIHJldHVybiB0eXBlb2YgYXJnID09PSAnbnVtYmVyJztcbn1cblxuZnVuY3Rpb24gaXNPYmplY3QoYXJnKSB7XG4gIHJldHVybiB0eXBlb2YgYXJnID09PSAnb2JqZWN0JyAmJiBhcmcgIT09IG51bGw7XG59XG5cbmZ1bmN0aW9uIGlzVW5kZWZpbmVkKGFyZykge1xuICByZXR1cm4gYXJnID09PSB2b2lkIDA7XG59XG4iLCIvKiBqc2hpbnQgbm9kZTogdHJ1ZSAqL1xuJ3VzZSBzdHJpY3QnO1xuXG52YXIgbm9ybWFsaWNlID0gcmVxdWlyZSgnbm9ybWFsaWNlJyk7XG5cbi8qKlxuICAjIGZyZWVpY2VcblxuICBUaGUgYGZyZWVpY2VgIG1vZHVsZSBpcyBhIHNpbXBsZSB3YXkgb2YgZ2V0dGluZyByYW5kb20gU1RVTiBvciBUVVJOIHNlcnZlclxuICBmb3IgeW91ciBXZWJSVEMgYXBwbGljYXRpb24uICBUaGUgbGlzdCBvZiBzZXJ2ZXJzIChqdXN0IFNUVU4gYXQgdGhpcyBzdGFnZSlcbiAgd2VyZSBzb3VyY2VkIGZyb20gdGhpcyBbZ2lzdF0oaHR0cHM6Ly9naXN0LmdpdGh1Yi5jb20venppdW5pLzM3NDE5MzMpLlxuXG4gICMjIEV4YW1wbGUgVXNlXG5cbiAgVGhlIGZvbGxvd2luZyBkZW1vbnN0cmF0ZXMgaG93IHlvdSBjYW4gdXNlIGBmcmVlaWNlYCB3aXRoXG4gIFtydGMtcXVpY2tjb25uZWN0XShodHRwczovL2dpdGh1Yi5jb20vcnRjLWlvL3J0Yy1xdWlja2Nvbm5lY3QpOlxuXG4gIDw8PCBleGFtcGxlcy9xdWlja2Nvbm5lY3QuanNcblxuICBBcyB0aGUgYGZyZWVpY2VgIG1vZHVsZSBnZW5lcmF0ZXMgaWNlIHNlcnZlcnMgaW4gYSBsaXN0IGNvbXBsaWFudCB3aXRoIHRoZVxuICBXZWJSVEMgc3BlYyB5b3Ugd2lsbCBiZSBhYmxlIHRvIHVzZSBpdCB3aXRoIHJhdyBgUlRDUGVlckNvbm5lY3Rpb25gXG4gIGNvbnN0cnVjdG9ycyBhbmQgb3RoZXIgV2ViUlRDIGxpYnJhcmllcy5cblxuICAjIyBIZXksIGRvbid0IHVzZSBteSBTVFVOL1RVUk4gc2VydmVyIVxuXG4gIElmIGZvciBzb21lIHJlYXNvbiB5b3VyIGZyZWUgU1RVTiBvciBUVVJOIHNlcnZlciBlbmRzIHVwIGluIHRoZVxuICBsaXN0IG9mIHNlcnZlcnMgKFtzdHVuXShodHRwczovL2dpdGh1Yi5jb20vRGFtb25PZWhsbWFuL2ZyZWVpY2UvYmxvYi9tYXN0ZXIvc3R1bi5qc29uKSBvclxuICBbdHVybl0oaHR0cHM6Ly9naXRodWIuY29tL0RhbW9uT2VobG1hbi9mcmVlaWNlL2Jsb2IvbWFzdGVyL3R1cm4uanNvbikpXG4gIHRoYXQgaXMgdXNlZCBpbiB0aGlzIG1vZHVsZSwgeW91IGNhbiBmZWVsXG4gIGZyZWUgdG8gb3BlbiBhbiBpc3N1ZSBvbiB0aGlzIHJlcG9zaXRvcnkgYW5kIHRob3NlIHNlcnZlcnMgd2lsbCBiZSByZW1vdmVkXG4gIHdpdGhpbiAyNCBob3VycyAob3Igc29vbmVyKS4gIFRoaXMgaXMgdGhlIHF1aWNrZXN0IGFuZCBwcm9iYWJseSB0aGUgbW9zdFxuICBwb2xpdGUgd2F5IHRvIGhhdmUgc29tZXRoaW5nIHJlbW92ZWQgKGFuZCBwcm92aWRlcyB1cyBzb21lIHZpc2liaWxpdHlcbiAgaWYgc29tZW9uZSBvcGVucyBhIHB1bGwgcmVxdWVzdCByZXF1ZXN0aW5nIHRoYXQgYSBzZXJ2ZXIgaXMgYWRkZWQpLlxuXG4gICMjIFBsZWFzZSBhZGQgbXkgc2VydmVyIVxuXG4gIElmIHlvdSBoYXZlIGEgc2VydmVyIHRoYXQgeW91IHdpc2ggdG8gYWRkIHRvIHRoZSBsaXN0LCB0aGF0J3MgYXdlc29tZSEgSSdtXG4gIHN1cmUgSSBzcGVhayBvbiBiZWhhbGYgb2YgYSB3aG9sZSBwaWxlIG9mIFdlYlJUQyBkZXZlbG9wZXJzIHdobyBzYXkgdGhhbmtzLlxuICBUbyBnZXQgaXQgaW50byB0aGUgbGlzdCwgZmVlbCBmcmVlIHRvIGVpdGhlciBvcGVuIGEgcHVsbCByZXF1ZXN0IG9yIGlmIHlvdVxuICBmaW5kIHRoYXQgcHJvY2VzcyBhIGJpdCBkYXVudGluZyB0aGVuIGp1c3QgY3JlYXRlIGFuIGlzc3VlIHJlcXVlc3RpbmdcbiAgdGhlIGFkZGl0aW9uIG9mIHRoZSBzZXJ2ZXIgKG1ha2Ugc3VyZSB5b3UgcHJvdmlkZSBhbGwgdGhlIGRldGFpbHMsIGFuZCBpZlxuICB5b3UgaGF2ZSBhIFRlcm1zIG9mIFNlcnZpY2UgdGhlbiBpbmNsdWRpbmcgdGhhdCBpbiB0aGUgUFIvaXNzdWUgd291bGQgYmVcbiAgYXdlc29tZSkuXG5cbiAgIyMgSSBrbm93IG9mIGEgZnJlZSBzZXJ2ZXIsIGNhbiBJIGFkZCBpdD9cblxuICBTdXJlLCBpZiB5b3UgZG8geW91ciBob21ld29yayBhbmQgbWFrZSBzdXJlIGl0IGlzIG9rIHRvIHVzZSAoSSdtIGN1cnJlbnRseVxuICBpbiB0aGUgcHJvY2VzcyBvZiByZXZpZXdpbmcgdGhlIHRlcm1zIG9mIHRob3NlIFNUVU4gc2VydmVycyBpbmNsdWRlZCBmcm9tXG4gIHRoZSBvcmlnaW5hbCBsaXN0KS4gIElmIGl0J3Mgb2sgdG8gZ28sIHRoZW4gcGxlYXNlIHNlZSB0aGUgcHJldmlvdXMgZW50cnlcbiAgZm9yIGhvdyB0byBhZGQgaXQuXG5cbiAgIyMgQ3VycmVudCBMaXN0IG9mIFNlcnZlcnNcblxuICAqIGN1cnJlbnQgYXMgYXQgdGhlIHRpbWUgb2YgbGFzdCBgUkVBRE1FLm1kYCBmaWxlIGdlbmVyYXRpb25cblxuICAjIyMgU1RVTlxuXG4gIDw8PCBzdHVuLmpzb25cblxuICAjIyMgVFVSTlxuXG4gIDw8PCB0dXJuLmpzb25cblxuKiovXG5cbnZhciBmcmVlaWNlID0gbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihvcHRzKSB7XG4gIC8vIGlmIGEgbGlzdCBvZiBzZXJ2ZXJzIGhhcyBiZWVuIHByb3ZpZGVkLCB0aGVuIHVzZSBpdCBpbnN0ZWFkIG9mIGRlZmF1bHRzXG4gIHZhciBzZXJ2ZXJzID0ge1xuICAgIHN0dW46IChvcHRzIHx8IHt9KS5zdHVuIHx8IHJlcXVpcmUoJy4vc3R1bi5qc29uJyksXG4gICAgdHVybjogKG9wdHMgfHwge30pLnR1cm4gfHwgcmVxdWlyZSgnLi90dXJuLmpzb24nKVxuICB9O1xuXG4gIHZhciBzdHVuQ291bnQgPSAob3B0cyB8fCB7fSkuc3R1bkNvdW50IHx8IDI7XG4gIHZhciB0dXJuQ291bnQgPSAob3B0cyB8fCB7fSkudHVybkNvdW50IHx8IDA7XG4gIHZhciBzZWxlY3RlZDtcblxuICBmdW5jdGlvbiBnZXRTZXJ2ZXJzKHR5cGUsIGNvdW50KSB7XG4gICAgdmFyIG91dCA9IFtdO1xuICAgIHZhciBpbnB1dCA9IFtdLmNvbmNhdChzZXJ2ZXJzW3R5cGVdKTtcbiAgICB2YXIgaWR4O1xuXG4gICAgd2hpbGUgKGlucHV0Lmxlbmd0aCAmJiBvdXQubGVuZ3RoIDwgY291bnQpIHtcbiAgICAgIGlkeCA9IChNYXRoLnJhbmRvbSgpICogaW5wdXQubGVuZ3RoKSB8IDA7XG4gICAgICBvdXQgPSBvdXQuY29uY2F0KGlucHV0LnNwbGljZShpZHgsIDEpKTtcbiAgICB9XG5cbiAgICByZXR1cm4gb3V0Lm1hcChmdW5jdGlvbih1cmwpIHtcbiAgICAgICAgLy9JZiBpdCdzIGEgbm90IGEgc3RyaW5nLCBkb24ndCB0cnkgdG8gXCJub3JtYWxpY2VcIiBpdCBvdGhlcndpc2UgdXNpbmcgdHlwZTp1cmwgd2lsbCBzY3JldyBpdCB1cFxuICAgICAgICBpZiAoKHR5cGVvZiB1cmwgIT09ICdzdHJpbmcnKSAmJiAoISAodXJsIGluc3RhbmNlb2YgU3RyaW5nKSkpIHtcbiAgICAgICAgICAgIHJldHVybiB1cmw7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gbm9ybWFsaWNlKHR5cGUgKyAnOicgKyB1cmwpO1xuICAgICAgICB9XG4gICAgfSk7XG4gIH1cblxuICAvLyBhZGQgc3R1biBzZXJ2ZXJzXG4gIHNlbGVjdGVkID0gW10uY29uY2F0KGdldFNlcnZlcnMoJ3N0dW4nLCBzdHVuQ291bnQpKTtcblxuICBpZiAodHVybkNvdW50KSB7XG4gICAgc2VsZWN0ZWQgPSBzZWxlY3RlZC5jb25jYXQoZ2V0U2VydmVycygndHVybicsIHR1cm5Db3VudCkpO1xuICB9XG5cbiAgcmV0dXJuIHNlbGVjdGVkO1xufTtcbiIsIm1vZHVsZS5leHBvcnRzPVtcbiAgXCJzdHVuLmwuZ29vZ2xlLmNvbToxOTMwMlwiLFxuICBcInN0dW4xLmwuZ29vZ2xlLmNvbToxOTMwMlwiLFxuICBcInN0dW4yLmwuZ29vZ2xlLmNvbToxOTMwMlwiLFxuICBcInN0dW4zLmwuZ29vZ2xlLmNvbToxOTMwMlwiLFxuICBcInN0dW40LmwuZ29vZ2xlLmNvbToxOTMwMlwiLFxuICBcInN0dW4uZWtpZ2EubmV0XCIsXG4gIFwic3R1bi5pZGVhc2lwLmNvbVwiLFxuICBcInN0dW4uc2NobHVuZC5kZVwiLFxuICBcInN0dW4uc3R1bnByb3RvY29sLm9yZzozNDc4XCIsXG4gIFwic3R1bi52b2lwYXJvdW5kLmNvbVwiLFxuICBcInN0dW4udm9pcGJ1c3Rlci5jb21cIixcbiAgXCJzdHVuLnZvaXBzdHVudC5jb21cIixcbiAgXCJzdHVuLnZveGdyYXRpYS5vcmdcIixcbiAgXCJzdHVuLnNlcnZpY2VzLm1vemlsbGEuY29tXCJcbl1cbiIsIm1vZHVsZS5leHBvcnRzPVtdXG4iLCJ2YXIgV2lsZEVtaXR0ZXIgPSByZXF1aXJlKCd3aWxkZW1pdHRlcicpO1xuXG5mdW5jdGlvbiBnZXRNYXhWb2x1bWUgKGFuYWx5c2VyLCBmZnRCaW5zKSB7XG4gIHZhciBtYXhWb2x1bWUgPSAtSW5maW5pdHk7XG4gIGFuYWx5c2VyLmdldEZsb2F0RnJlcXVlbmN5RGF0YShmZnRCaW5zKTtcblxuICBmb3IodmFyIGk9NCwgaWk9ZmZ0Qmlucy5sZW5ndGg7IGkgPCBpaTsgaSsrKSB7XG4gICAgaWYgKGZmdEJpbnNbaV0gPiBtYXhWb2x1bWUgJiYgZmZ0Qmluc1tpXSA8IDApIHtcbiAgICAgIG1heFZvbHVtZSA9IGZmdEJpbnNbaV07XG4gICAgfVxuICB9O1xuXG4gIHJldHVybiBtYXhWb2x1bWU7XG59XG5cblxudmFyIGF1ZGlvQ29udGV4dFR5cGU7XG5pZiAodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgYXVkaW9Db250ZXh0VHlwZSA9IHdpbmRvdy5BdWRpb0NvbnRleHQgfHwgd2luZG93LndlYmtpdEF1ZGlvQ29udGV4dDtcbn1cbi8vIHVzZSBhIHNpbmdsZSBhdWRpbyBjb250ZXh0IGR1ZSB0byBoYXJkd2FyZSBsaW1pdHNcbnZhciBhdWRpb0NvbnRleHQgPSBudWxsO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihzdHJlYW0sIG9wdGlvbnMpIHtcbiAgdmFyIGhhcmtlciA9IG5ldyBXaWxkRW1pdHRlcigpO1xuXG5cbiAgLy8gbWFrZSBpdCBub3QgYnJlYWsgaW4gbm9uLXN1cHBvcnRlZCBicm93c2Vyc1xuICBpZiAoIWF1ZGlvQ29udGV4dFR5cGUpIHJldHVybiBoYXJrZXI7XG5cbiAgLy9Db25maWdcbiAgdmFyIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9LFxuICAgICAgc21vb3RoaW5nID0gKG9wdGlvbnMuc21vb3RoaW5nIHx8IDAuMSksXG4gICAgICBpbnRlcnZhbCA9IChvcHRpb25zLmludGVydmFsIHx8IDUwKSxcbiAgICAgIHRocmVzaG9sZCA9IG9wdGlvbnMudGhyZXNob2xkLFxuICAgICAgcGxheSA9IG9wdGlvbnMucGxheSxcbiAgICAgIGhpc3RvcnkgPSBvcHRpb25zLmhpc3RvcnkgfHwgMTAsXG4gICAgICBydW5uaW5nID0gdHJ1ZTtcblxuICAvL1NldHVwIEF1ZGlvIENvbnRleHRcbiAgaWYgKCFhdWRpb0NvbnRleHQpIHtcbiAgICBhdWRpb0NvbnRleHQgPSBuZXcgYXVkaW9Db250ZXh0VHlwZSgpO1xuICB9XG4gIHZhciBzb3VyY2VOb2RlLCBmZnRCaW5zLCBhbmFseXNlcjtcblxuICBhbmFseXNlciA9IGF1ZGlvQ29udGV4dC5jcmVhdGVBbmFseXNlcigpO1xuICBhbmFseXNlci5mZnRTaXplID0gNTEyO1xuICBhbmFseXNlci5zbW9vdGhpbmdUaW1lQ29uc3RhbnQgPSBzbW9vdGhpbmc7XG4gIGZmdEJpbnMgPSBuZXcgRmxvYXQzMkFycmF5KGFuYWx5c2VyLmZyZXF1ZW5jeUJpbkNvdW50KTtcblxuICBpZiAoc3RyZWFtLmpxdWVyeSkgc3RyZWFtID0gc3RyZWFtWzBdO1xuICBpZiAoc3RyZWFtIGluc3RhbmNlb2YgSFRNTEF1ZGlvRWxlbWVudCB8fCBzdHJlYW0gaW5zdGFuY2VvZiBIVE1MVmlkZW9FbGVtZW50KSB7XG4gICAgLy9BdWRpbyBUYWdcbiAgICBzb3VyY2VOb2RlID0gYXVkaW9Db250ZXh0LmNyZWF0ZU1lZGlhRWxlbWVudFNvdXJjZShzdHJlYW0pO1xuICAgIGlmICh0eXBlb2YgcGxheSA9PT0gJ3VuZGVmaW5lZCcpIHBsYXkgPSB0cnVlO1xuICAgIHRocmVzaG9sZCA9IHRocmVzaG9sZCB8fCAtNTA7XG4gIH0gZWxzZSB7XG4gICAgLy9XZWJSVEMgU3RyZWFtXG4gICAgc291cmNlTm9kZSA9IGF1ZGlvQ29udGV4dC5jcmVhdGVNZWRpYVN0cmVhbVNvdXJjZShzdHJlYW0pO1xuICAgIHRocmVzaG9sZCA9IHRocmVzaG9sZCB8fCAtNTA7XG4gIH1cblxuICBzb3VyY2VOb2RlLmNvbm5lY3QoYW5hbHlzZXIpO1xuICBpZiAocGxheSkgYW5hbHlzZXIuY29ubmVjdChhdWRpb0NvbnRleHQuZGVzdGluYXRpb24pO1xuXG4gIGhhcmtlci5zcGVha2luZyA9IGZhbHNlO1xuXG4gIGhhcmtlci5zZXRUaHJlc2hvbGQgPSBmdW5jdGlvbih0KSB7XG4gICAgdGhyZXNob2xkID0gdDtcbiAgfTtcblxuICBoYXJrZXIuc2V0SW50ZXJ2YWwgPSBmdW5jdGlvbihpKSB7XG4gICAgaW50ZXJ2YWwgPSBpO1xuICB9O1xuXG4gIGhhcmtlci5zdG9wID0gZnVuY3Rpb24oKSB7XG4gICAgcnVubmluZyA9IGZhbHNlO1xuICAgIGhhcmtlci5lbWl0KCd2b2x1bWVfY2hhbmdlJywgLTEwMCwgdGhyZXNob2xkKTtcbiAgICBpZiAoaGFya2VyLnNwZWFraW5nKSB7XG4gICAgICBoYXJrZXIuc3BlYWtpbmcgPSBmYWxzZTtcbiAgICAgIGhhcmtlci5lbWl0KCdzdG9wcGVkX3NwZWFraW5nJyk7XG4gICAgfVxuICAgIGFuYWx5c2VyLmRpc2Nvbm5lY3QoKTtcbiAgICBzb3VyY2VOb2RlLmRpc2Nvbm5lY3QoKTtcbiAgfTtcbiAgaGFya2VyLnNwZWFraW5nSGlzdG9yeSA9IFtdO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGhpc3Rvcnk7IGkrKykge1xuICAgICAgaGFya2VyLnNwZWFraW5nSGlzdG9yeS5wdXNoKDApO1xuICB9XG5cbiAgLy8gUG9sbCB0aGUgYW5hbHlzZXIgbm9kZSB0byBkZXRlcm1pbmUgaWYgc3BlYWtpbmdcbiAgLy8gYW5kIGVtaXQgZXZlbnRzIGlmIGNoYW5nZWRcbiAgdmFyIGxvb3BlciA9IGZ1bmN0aW9uKCkge1xuICAgIHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7XG5cbiAgICAgIC8vY2hlY2sgaWYgc3RvcCBoYXMgYmVlbiBjYWxsZWRcbiAgICAgIGlmKCFydW5uaW5nKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgdmFyIGN1cnJlbnRWb2x1bWUgPSBnZXRNYXhWb2x1bWUoYW5hbHlzZXIsIGZmdEJpbnMpO1xuXG4gICAgICBoYXJrZXIuZW1pdCgndm9sdW1lX2NoYW5nZScsIGN1cnJlbnRWb2x1bWUsIHRocmVzaG9sZCk7XG5cbiAgICAgIHZhciBoaXN0b3J5ID0gMDtcbiAgICAgIGlmIChjdXJyZW50Vm9sdW1lID4gdGhyZXNob2xkICYmICFoYXJrZXIuc3BlYWtpbmcpIHtcbiAgICAgICAgLy8gdHJpZ2dlciBxdWlja2x5LCBzaG9ydCBoaXN0b3J5XG4gICAgICAgIGZvciAodmFyIGkgPSBoYXJrZXIuc3BlYWtpbmdIaXN0b3J5Lmxlbmd0aCAtIDM7IGkgPCBoYXJrZXIuc3BlYWtpbmdIaXN0b3J5Lmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgaGlzdG9yeSArPSBoYXJrZXIuc3BlYWtpbmdIaXN0b3J5W2ldO1xuICAgICAgICB9XG4gICAgICAgIGlmIChoaXN0b3J5ID49IDIpIHtcbiAgICAgICAgICBoYXJrZXIuc3BlYWtpbmcgPSB0cnVlO1xuICAgICAgICAgIGhhcmtlci5lbWl0KCdzcGVha2luZycpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKGN1cnJlbnRWb2x1bWUgPCB0aHJlc2hvbGQgJiYgaGFya2VyLnNwZWFraW5nKSB7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgaGFya2VyLnNwZWFraW5nSGlzdG9yeS5sZW5ndGg7IGkrKykge1xuICAgICAgICAgIGhpc3RvcnkgKz0gaGFya2VyLnNwZWFraW5nSGlzdG9yeVtpXTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoaGlzdG9yeSA9PSAwKSB7XG4gICAgICAgICAgaGFya2VyLnNwZWFraW5nID0gZmFsc2U7XG4gICAgICAgICAgaGFya2VyLmVtaXQoJ3N0b3BwZWRfc3BlYWtpbmcnKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaGFya2VyLnNwZWFraW5nSGlzdG9yeS5zaGlmdCgpO1xuICAgICAgaGFya2VyLnNwZWFraW5nSGlzdG9yeS5wdXNoKDAgKyAoY3VycmVudFZvbHVtZSA+IHRocmVzaG9sZCkpO1xuXG4gICAgICBsb29wZXIoKTtcbiAgICB9LCBpbnRlcnZhbCk7XG4gIH07XG4gIGxvb3BlcigpO1xuXG5cbiAgcmV0dXJuIGhhcmtlcjtcbn1cbiIsImlmICh0eXBlb2YgT2JqZWN0LmNyZWF0ZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAvLyBpbXBsZW1lbnRhdGlvbiBmcm9tIHN0YW5kYXJkIG5vZGUuanMgJ3V0aWwnIG1vZHVsZVxuICBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGluaGVyaXRzKGN0b3IsIHN1cGVyQ3Rvcikge1xuICAgIGN0b3Iuc3VwZXJfID0gc3VwZXJDdG9yXG4gICAgY3Rvci5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKHN1cGVyQ3Rvci5wcm90b3R5cGUsIHtcbiAgICAgIGNvbnN0cnVjdG9yOiB7XG4gICAgICAgIHZhbHVlOiBjdG9yLFxuICAgICAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICAgICAgd3JpdGFibGU6IHRydWUsXG4gICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZVxuICAgICAgfVxuICAgIH0pO1xuICB9O1xufSBlbHNlIHtcbiAgLy8gb2xkIHNjaG9vbCBzaGltIGZvciBvbGQgYnJvd3NlcnNcbiAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBpbmhlcml0cyhjdG9yLCBzdXBlckN0b3IpIHtcbiAgICBjdG9yLnN1cGVyXyA9IHN1cGVyQ3RvclxuICAgIHZhciBUZW1wQ3RvciA9IGZ1bmN0aW9uICgpIHt9XG4gICAgVGVtcEN0b3IucHJvdG90eXBlID0gc3VwZXJDdG9yLnByb3RvdHlwZVxuICAgIGN0b3IucHJvdG90eXBlID0gbmV3IFRlbXBDdG9yKClcbiAgICBjdG9yLnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IGN0b3JcbiAgfVxufVxuIiwiLyohXHJcbiAqIEBuYW1lIEphdmFTY3JpcHQvTm9kZUpTIE1lcmdlIHYxLjIuMFxyXG4gKiBAYXV0aG9yIHllaWtvc1xyXG4gKiBAcmVwb3NpdG9yeSBodHRwczovL2dpdGh1Yi5jb20veWVpa29zL2pzLm1lcmdlXHJcblxyXG4gKiBDb3B5cmlnaHQgMjAxNCB5ZWlrb3MgLSBNSVQgbGljZW5zZVxyXG4gKiBodHRwczovL3Jhdy5naXRodWIuY29tL3llaWtvcy9qcy5tZXJnZS9tYXN0ZXIvTElDRU5TRVxyXG4gKi9cclxuXHJcbjsoZnVuY3Rpb24oaXNOb2RlKSB7XHJcblxyXG5cdC8qKlxyXG5cdCAqIE1lcmdlIG9uZSBvciBtb3JlIG9iamVjdHMgXHJcblx0ICogQHBhcmFtIGJvb2w/IGNsb25lXHJcblx0ICogQHBhcmFtIG1peGVkLC4uLiBhcmd1bWVudHNcclxuXHQgKiBAcmV0dXJuIG9iamVjdFxyXG5cdCAqL1xyXG5cclxuXHR2YXIgUHVibGljID0gZnVuY3Rpb24oY2xvbmUpIHtcclxuXHJcblx0XHRyZXR1cm4gbWVyZ2UoY2xvbmUgPT09IHRydWUsIGZhbHNlLCBhcmd1bWVudHMpO1xyXG5cclxuXHR9LCBwdWJsaWNOYW1lID0gJ21lcmdlJztcclxuXHJcblx0LyoqXHJcblx0ICogTWVyZ2UgdHdvIG9yIG1vcmUgb2JqZWN0cyByZWN1cnNpdmVseSBcclxuXHQgKiBAcGFyYW0gYm9vbD8gY2xvbmVcclxuXHQgKiBAcGFyYW0gbWl4ZWQsLi4uIGFyZ3VtZW50c1xyXG5cdCAqIEByZXR1cm4gb2JqZWN0XHJcblx0ICovXHJcblxyXG5cdFB1YmxpYy5yZWN1cnNpdmUgPSBmdW5jdGlvbihjbG9uZSkge1xyXG5cclxuXHRcdHJldHVybiBtZXJnZShjbG9uZSA9PT0gdHJ1ZSwgdHJ1ZSwgYXJndW1lbnRzKTtcclxuXHJcblx0fTtcclxuXHJcblx0LyoqXHJcblx0ICogQ2xvbmUgdGhlIGlucHV0IHJlbW92aW5nIGFueSByZWZlcmVuY2VcclxuXHQgKiBAcGFyYW0gbWl4ZWQgaW5wdXRcclxuXHQgKiBAcmV0dXJuIG1peGVkXHJcblx0ICovXHJcblxyXG5cdFB1YmxpYy5jbG9uZSA9IGZ1bmN0aW9uKGlucHV0KSB7XHJcblxyXG5cdFx0dmFyIG91dHB1dCA9IGlucHV0LFxyXG5cdFx0XHR0eXBlID0gdHlwZU9mKGlucHV0KSxcclxuXHRcdFx0aW5kZXgsIHNpemU7XHJcblxyXG5cdFx0aWYgKHR5cGUgPT09ICdhcnJheScpIHtcclxuXHJcblx0XHRcdG91dHB1dCA9IFtdO1xyXG5cdFx0XHRzaXplID0gaW5wdXQubGVuZ3RoO1xyXG5cclxuXHRcdFx0Zm9yIChpbmRleD0wO2luZGV4PHNpemU7KytpbmRleClcclxuXHJcblx0XHRcdFx0b3V0cHV0W2luZGV4XSA9IFB1YmxpYy5jbG9uZShpbnB1dFtpbmRleF0pO1xyXG5cclxuXHRcdH0gZWxzZSBpZiAodHlwZSA9PT0gJ29iamVjdCcpIHtcclxuXHJcblx0XHRcdG91dHB1dCA9IHt9O1xyXG5cclxuXHRcdFx0Zm9yIChpbmRleCBpbiBpbnB1dClcclxuXHJcblx0XHRcdFx0b3V0cHV0W2luZGV4XSA9IFB1YmxpYy5jbG9uZShpbnB1dFtpbmRleF0pO1xyXG5cclxuXHRcdH1cclxuXHJcblx0XHRyZXR1cm4gb3V0cHV0O1xyXG5cclxuXHR9O1xyXG5cclxuXHQvKipcclxuXHQgKiBNZXJnZSB0d28gb2JqZWN0cyByZWN1cnNpdmVseVxyXG5cdCAqIEBwYXJhbSBtaXhlZCBpbnB1dFxyXG5cdCAqIEBwYXJhbSBtaXhlZCBleHRlbmRcclxuXHQgKiBAcmV0dXJuIG1peGVkXHJcblx0ICovXHJcblxyXG5cdGZ1bmN0aW9uIG1lcmdlX3JlY3Vyc2l2ZShiYXNlLCBleHRlbmQpIHtcclxuXHJcblx0XHRpZiAodHlwZU9mKGJhc2UpICE9PSAnb2JqZWN0JylcclxuXHJcblx0XHRcdHJldHVybiBleHRlbmQ7XHJcblxyXG5cdFx0Zm9yICh2YXIga2V5IGluIGV4dGVuZCkge1xyXG5cclxuXHRcdFx0aWYgKHR5cGVPZihiYXNlW2tleV0pID09PSAnb2JqZWN0JyAmJiB0eXBlT2YoZXh0ZW5kW2tleV0pID09PSAnb2JqZWN0Jykge1xyXG5cclxuXHRcdFx0XHRiYXNlW2tleV0gPSBtZXJnZV9yZWN1cnNpdmUoYmFzZVtrZXldLCBleHRlbmRba2V5XSk7XHJcblxyXG5cdFx0XHR9IGVsc2Uge1xyXG5cclxuXHRcdFx0XHRiYXNlW2tleV0gPSBleHRlbmRba2V5XTtcclxuXHJcblx0XHRcdH1cclxuXHJcblx0XHR9XHJcblxyXG5cdFx0cmV0dXJuIGJhc2U7XHJcblxyXG5cdH1cclxuXHJcblx0LyoqXHJcblx0ICogTWVyZ2UgdHdvIG9yIG1vcmUgb2JqZWN0c1xyXG5cdCAqIEBwYXJhbSBib29sIGNsb25lXHJcblx0ICogQHBhcmFtIGJvb2wgcmVjdXJzaXZlXHJcblx0ICogQHBhcmFtIGFycmF5IGFyZ3ZcclxuXHQgKiBAcmV0dXJuIG9iamVjdFxyXG5cdCAqL1xyXG5cclxuXHRmdW5jdGlvbiBtZXJnZShjbG9uZSwgcmVjdXJzaXZlLCBhcmd2KSB7XHJcblxyXG5cdFx0dmFyIHJlc3VsdCA9IGFyZ3ZbMF0sXHJcblx0XHRcdHNpemUgPSBhcmd2Lmxlbmd0aDtcclxuXHJcblx0XHRpZiAoY2xvbmUgfHwgdHlwZU9mKHJlc3VsdCkgIT09ICdvYmplY3QnKVxyXG5cclxuXHRcdFx0cmVzdWx0ID0ge307XHJcblxyXG5cdFx0Zm9yICh2YXIgaW5kZXg9MDtpbmRleDxzaXplOysraW5kZXgpIHtcclxuXHJcblx0XHRcdHZhciBpdGVtID0gYXJndltpbmRleF0sXHJcblxyXG5cdFx0XHRcdHR5cGUgPSB0eXBlT2YoaXRlbSk7XHJcblxyXG5cdFx0XHRpZiAodHlwZSAhPT0gJ29iamVjdCcpIGNvbnRpbnVlO1xyXG5cclxuXHRcdFx0Zm9yICh2YXIga2V5IGluIGl0ZW0pIHtcclxuXHJcblx0XHRcdFx0dmFyIHNpdGVtID0gY2xvbmUgPyBQdWJsaWMuY2xvbmUoaXRlbVtrZXldKSA6IGl0ZW1ba2V5XTtcclxuXHJcblx0XHRcdFx0aWYgKHJlY3Vyc2l2ZSkge1xyXG5cclxuXHRcdFx0XHRcdHJlc3VsdFtrZXldID0gbWVyZ2VfcmVjdXJzaXZlKHJlc3VsdFtrZXldLCBzaXRlbSk7XHJcblxyXG5cdFx0XHRcdH0gZWxzZSB7XHJcblxyXG5cdFx0XHRcdFx0cmVzdWx0W2tleV0gPSBzaXRlbTtcclxuXHJcblx0XHRcdFx0fVxyXG5cclxuXHRcdFx0fVxyXG5cclxuXHRcdH1cclxuXHJcblx0XHRyZXR1cm4gcmVzdWx0O1xyXG5cclxuXHR9XHJcblxyXG5cdC8qKlxyXG5cdCAqIEdldCB0eXBlIG9mIHZhcmlhYmxlXHJcblx0ICogQHBhcmFtIG1peGVkIGlucHV0XHJcblx0ICogQHJldHVybiBzdHJpbmdcclxuXHQgKlxyXG5cdCAqIEBzZWUgaHR0cDovL2pzcGVyZi5jb20vdHlwZW9mdmFyXHJcblx0ICovXHJcblxyXG5cdGZ1bmN0aW9uIHR5cGVPZihpbnB1dCkge1xyXG5cclxuXHRcdHJldHVybiAoe30pLnRvU3RyaW5nLmNhbGwoaW5wdXQpLnNsaWNlKDgsIC0xKS50b0xvd2VyQ2FzZSgpO1xyXG5cclxuXHR9XHJcblxyXG5cdGlmIChpc05vZGUpIHtcclxuXHJcblx0XHRtb2R1bGUuZXhwb3J0cyA9IFB1YmxpYztcclxuXHJcblx0fSBlbHNlIHtcclxuXHJcblx0XHR3aW5kb3dbcHVibGljTmFtZV0gPSBQdWJsaWM7XHJcblxyXG5cdH1cclxuXHJcbn0pKHR5cGVvZiBtb2R1bGUgPT09ICdvYmplY3QnICYmIG1vZHVsZSAmJiB0eXBlb2YgbW9kdWxlLmV4cG9ydHMgPT09ICdvYmplY3QnICYmIG1vZHVsZS5leHBvcnRzKTsiLCIvKipcbiAgIyBub3JtYWxpY2VcblxuICBOb3JtYWxpemUgYW4gaWNlIHNlcnZlciBjb25maWd1cmF0aW9uIG9iamVjdCAob3IgcGxhaW4gb2xkIHN0cmluZykgaW50byBhIGZvcm1hdFxuICB0aGF0IGlzIHVzYWJsZSBpbiBhbGwgYnJvd3NlcnMgc3VwcG9ydGluZyBXZWJSVEMuICBQcmltYXJpbHkgdGhpcyBtb2R1bGUgaXMgZGVzaWduZWRcbiAgdG8gaGVscCB3aXRoIHRoZSB0cmFuc2l0aW9uIG9mIHRoZSBgdXJsYCBhdHRyaWJ1dGUgb2YgdGhlIGNvbmZpZ3VyYXRpb24gb2JqZWN0IHRvXG4gIHRoZSBgdXJsc2AgYXR0cmlidXRlLlxuXG4gICMjIEV4YW1wbGUgVXNhZ2VcblxuICA8PDwgZXhhbXBsZXMvc2ltcGxlLmpzXG5cbioqL1xuXG52YXIgcHJvdG9jb2xzID0gW1xuICAnc3R1bjonLFxuICAndHVybjonXG5dO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGlucHV0KSB7XG4gIHZhciB1cmwgPSAoaW5wdXQgfHwge30pLnVybCB8fCBpbnB1dDtcbiAgdmFyIHByb3RvY29sO1xuICB2YXIgcGFydHM7XG4gIHZhciBvdXRwdXQgPSB7fTtcblxuICAvLyBpZiB3ZSBkb24ndCBoYXZlIGEgc3RyaW5nIHVybCwgdGhlbiBhbGxvdyB0aGUgaW5wdXQgdG8gcGFzc3Rocm91Z2hcbiAgaWYgKHR5cGVvZiB1cmwgIT0gJ3N0cmluZycgJiYgKCEgKHVybCBpbnN0YW5jZW9mIFN0cmluZykpKSB7XG4gICAgcmV0dXJuIGlucHV0O1xuICB9XG5cbiAgLy8gdHJpbSB0aGUgdXJsIHN0cmluZywgYW5kIGNvbnZlcnQgdG8gYW4gYXJyYXlcbiAgdXJsID0gdXJsLnRyaW0oKTtcblxuICAvLyBpZiB0aGUgcHJvdG9jb2wgaXMgbm90IGtub3duLCB0aGVuIHBhc3N0aHJvdWdoXG4gIHByb3RvY29sID0gcHJvdG9jb2xzW3Byb3RvY29scy5pbmRleE9mKHVybC5zbGljZSgwLCA1KSldO1xuICBpZiAoISBwcm90b2NvbCkge1xuICAgIHJldHVybiBpbnB1dDtcbiAgfVxuXG4gIC8vIG5vdyBsZXQncyBhdHRhY2sgdGhlIHJlbWFpbmluZyB1cmwgcGFydHNcbiAgdXJsID0gdXJsLnNsaWNlKDUpO1xuICBwYXJ0cyA9IHVybC5zcGxpdCgnQCcpO1xuXG4gIG91dHB1dC51c2VybmFtZSA9IGlucHV0LnVzZXJuYW1lO1xuICBvdXRwdXQuY3JlZGVudGlhbCA9IGlucHV0LmNyZWRlbnRpYWw7XG4gIC8vIGlmIHdlIGhhdmUgYW4gYXV0aGVudGljYXRpb24gcGFydCwgdGhlbiBzZXQgdGhlIGNyZWRlbnRpYWxzXG4gIGlmIChwYXJ0cy5sZW5ndGggPiAxKSB7XG4gICAgdXJsID0gcGFydHNbMV07XG4gICAgcGFydHMgPSBwYXJ0c1swXS5zcGxpdCgnOicpO1xuXG4gICAgLy8gYWRkIHRoZSBvdXRwdXQgY3JlZGVudGlhbCBhbmQgdXNlcm5hbWVcbiAgICBvdXRwdXQudXNlcm5hbWUgPSBwYXJ0c1swXTtcbiAgICBvdXRwdXQuY3JlZGVudGlhbCA9IChpbnB1dCB8fCB7fSkuY3JlZGVudGlhbCB8fCBwYXJ0c1sxXSB8fCAnJztcbiAgfVxuXG4gIG91dHB1dC51cmwgPSBwcm90b2NvbCArIHVybDtcbiAgb3V0cHV0LnVybHMgPSBbIG91dHB1dC51cmwgXTtcblxuICByZXR1cm4gb3V0cHV0O1xufTtcbiIsInZhciBncmFtbWFyID0gbW9kdWxlLmV4cG9ydHMgPSB7XG4gIHY6IFt7XG4gICAgICBuYW1lOiAndmVyc2lvbicsXG4gICAgICByZWc6IC9eKFxcZCopJC9cbiAgfV0sXG4gIG86IFt7IC8vbz0tIDIwNTE4IDAgSU4gSVA0IDIwMy4wLjExMy4xXG4gICAgLy8gTkI6IHNlc3Npb25JZCB3aWxsIGJlIGEgU3RyaW5nIGluIG1vc3QgY2FzZXMgYmVjYXVzZSBpdCBpcyBodWdlXG4gICAgbmFtZTogJ29yaWdpbicsXG4gICAgcmVnOiAvXihcXFMqKSAoXFxkKikgKFxcZCopIChcXFMqKSBJUChcXGQpIChcXFMqKS8sXG4gICAgbmFtZXM6IFsndXNlcm5hbWUnLCAnc2Vzc2lvbklkJywgJ3Nlc3Npb25WZXJzaW9uJywgJ25ldFR5cGUnLCAnaXBWZXInLCAnYWRkcmVzcyddLFxuICAgIGZvcm1hdDogXCIlcyAlcyAlZCAlcyBJUCVkICVzXCJcbiAgfV0sXG4gIC8vIGRlZmF1bHQgcGFyc2luZyBvZiB0aGVzZSBvbmx5ICh0aG91Z2ggc29tZSBvZiB0aGVzZSBmZWVsIG91dGRhdGVkKVxuICBzOiBbeyBuYW1lOiAnbmFtZScgfV0sXG4gIGk6IFt7IG5hbWU6ICdkZXNjcmlwdGlvbicgfV0sXG4gIHU6IFt7IG5hbWU6ICd1cmknIH1dLFxuICBlOiBbeyBuYW1lOiAnZW1haWwnIH1dLFxuICBwOiBbeyBuYW1lOiAncGhvbmUnIH1dLFxuICB6OiBbeyBuYW1lOiAndGltZXpvbmVzJyB9XSwgLy8gVE9ETzogdGhpcyBvbmUgY2FuIGFjdHVhbGx5IGJlIHBhcnNlZCBwcm9wZXJseS4uXG4gIHI6IFt7IG5hbWU6ICdyZXBlYXRzJyB9XSwgICAvLyBUT0RPOiB0aGlzIG9uZSBjYW4gYWxzbyBiZSBwYXJzZWQgcHJvcGVybHlcbiAgLy9rOiBbe31dLCAvLyBvdXRkYXRlZCB0aGluZyBpZ25vcmVkXG4gIHQ6IFt7IC8vdD0wIDBcbiAgICBuYW1lOiAndGltaW5nJyxcbiAgICByZWc6IC9eKFxcZCopIChcXGQqKS8sXG4gICAgbmFtZXM6IFsnc3RhcnQnLCAnc3RvcCddLFxuICAgIGZvcm1hdDogXCIlZCAlZFwiXG4gIH1dLFxuICBjOiBbeyAvL2M9SU4gSVA0IDEwLjQ3LjE5Ny4yNlxuICAgICAgbmFtZTogJ2Nvbm5lY3Rpb24nLFxuICAgICAgcmVnOiAvXklOIElQKFxcZCkgKFxcUyopLyxcbiAgICAgIG5hbWVzOiBbJ3ZlcnNpb24nLCAnaXAnXSxcbiAgICAgIGZvcm1hdDogXCJJTiBJUCVkICVzXCJcbiAgfV0sXG4gIGI6IFt7IC8vYj1BUzo0MDAwXG4gICAgICBwdXNoOiAnYmFuZHdpZHRoJyxcbiAgICAgIHJlZzogL14oVElBU3xBU3xDVHxSUnxSUyk6KFxcZCopLyxcbiAgICAgIG5hbWVzOiBbJ3R5cGUnLCAnbGltaXQnXSxcbiAgICAgIGZvcm1hdDogXCIlczolc1wiXG4gIH1dLFxuICBtOiBbeyAvL209dmlkZW8gNTE3NDQgUlRQL0FWUCAxMjYgOTcgOTggMzQgMzFcbiAgICAgIC8vIE5COiBzcGVjaWFsIC0gcHVzaGVzIHRvIHNlc3Npb25cbiAgICAgIC8vIFRPRE86IHJ0cC9mbXRwIHNob3VsZCBiZSBmaWx0ZXJlZCBieSB0aGUgcGF5bG9hZHMgZm91bmQgaGVyZT9cbiAgICAgIHJlZzogL14oXFx3KikgKFxcZCopIChbXFx3XFwvXSopKD86ICguKikpPy8sXG4gICAgICBuYW1lczogWyd0eXBlJywgJ3BvcnQnLCAncHJvdG9jb2wnLCAncGF5bG9hZHMnXSxcbiAgICAgIGZvcm1hdDogXCIlcyAlZCAlcyAlc1wiXG4gIH1dLFxuICBhOiBbXG4gICAgeyAvL2E9cnRwbWFwOjExMCBvcHVzLzQ4MDAwLzJcbiAgICAgIHB1c2g6ICdydHAnLFxuICAgICAgcmVnOiAvXnJ0cG1hcDooXFxkKikgKFtcXHdcXC1dKikoPzpcXHMqXFwvKFxcZCopKD86XFxzKlxcLyhcXFMqKSk/KT8vLFxuICAgICAgbmFtZXM6IFsncGF5bG9hZCcsICdjb2RlYycsICdyYXRlJywgJ2VuY29kaW5nJ10sXG4gICAgICBmb3JtYXQ6IGZ1bmN0aW9uIChvKSB7XG4gICAgICAgIHJldHVybiAoby5lbmNvZGluZykgP1xuICAgICAgICAgIFwicnRwbWFwOiVkICVzLyVzLyVzXCI6XG4gICAgICAgICAgby5yYXRlID9cbiAgICAgICAgICBcInJ0cG1hcDolZCAlcy8lc1wiOlxuICAgICAgICAgIFwicnRwbWFwOiVkICVzXCI7XG4gICAgICB9XG4gICAgfSxcbiAgICB7XG4gICAgICAvL2E9Zm10cDoxMDggcHJvZmlsZS1sZXZlbC1pZD0yNDtvYmplY3Q9MjM7Yml0cmF0ZT02NDAwMFxuICAgICAgLy9hPWZtdHA6MTExIG1pbnB0aW1lPTEwOyB1c2VpbmJhbmRmZWM9MVxuICAgICAgcHVzaDogJ2ZtdHAnLFxuICAgICAgcmVnOiAvXmZtdHA6KFxcZCopIChbXFxTfCBdKikvLFxuICAgICAgbmFtZXM6IFsncGF5bG9hZCcsICdjb25maWcnXSxcbiAgICAgIGZvcm1hdDogXCJmbXRwOiVkICVzXCJcbiAgICB9LFxuICAgIHsgLy9hPWNvbnRyb2w6c3RyZWFtaWQ9MFxuICAgICAgICBuYW1lOiAnY29udHJvbCcsXG4gICAgICAgIHJlZzogL15jb250cm9sOiguKikvLFxuICAgICAgICBmb3JtYXQ6IFwiY29udHJvbDolc1wiXG4gICAgfSxcbiAgICB7IC8vYT1ydGNwOjY1MTc5IElOIElQNCAxOTMuODQuNzcuMTk0XG4gICAgICBuYW1lOiAncnRjcCcsXG4gICAgICByZWc6IC9ecnRjcDooXFxkKikoPzogKFxcUyopIElQKFxcZCkgKFxcUyopKT8vLFxuICAgICAgbmFtZXM6IFsncG9ydCcsICduZXRUeXBlJywgJ2lwVmVyJywgJ2FkZHJlc3MnXSxcbiAgICAgIGZvcm1hdDogZnVuY3Rpb24gKG8pIHtcbiAgICAgICAgcmV0dXJuIChvLmFkZHJlc3MgIT0gbnVsbCkgP1xuICAgICAgICAgIFwicnRjcDolZCAlcyBJUCVkICVzXCI6XG4gICAgICAgICAgXCJydGNwOiVkXCI7XG4gICAgICB9XG4gICAgfSxcbiAgICB7IC8vYT1ydGNwLWZiOjk4IHRyci1pbnQgMTAwXG4gICAgICBwdXNoOiAncnRjcEZiVHJySW50JyxcbiAgICAgIHJlZzogL15ydGNwLWZiOihcXCp8XFxkKikgdHJyLWludCAoXFxkKikvLFxuICAgICAgbmFtZXM6IFsncGF5bG9hZCcsICd2YWx1ZSddLFxuICAgICAgZm9ybWF0OiBcInJ0Y3AtZmI6JWQgdHJyLWludCAlZFwiXG4gICAgfSxcbiAgICB7IC8vYT1ydGNwLWZiOjk4IG5hY2sgcnBzaVxuICAgICAgcHVzaDogJ3J0Y3BGYicsXG4gICAgICByZWc6IC9ecnRjcC1mYjooXFwqfFxcZCopIChbXFx3LV9dKikoPzogKFtcXHctX10qKSk/LyxcbiAgICAgIG5hbWVzOiBbJ3BheWxvYWQnLCAndHlwZScsICdzdWJ0eXBlJ10sXG4gICAgICBmb3JtYXQ6IGZ1bmN0aW9uIChvKSB7XG4gICAgICAgIHJldHVybiAoby5zdWJ0eXBlICE9IG51bGwpID9cbiAgICAgICAgICBcInJ0Y3AtZmI6JXMgJXMgJXNcIjpcbiAgICAgICAgICBcInJ0Y3AtZmI6JXMgJXNcIjtcbiAgICAgIH1cbiAgICB9LFxuICAgIHsgLy9hPWV4dG1hcDoyIHVybjppZXRmOnBhcmFtczpydHAtaGRyZXh0OnRvZmZzZXRcbiAgICAgIC8vYT1leHRtYXA6MS9yZWN2b25seSBVUkktZ3BzLXN0cmluZ1xuICAgICAgcHVzaDogJ2V4dCcsXG4gICAgICByZWc6IC9eZXh0bWFwOihbXFx3X1xcL10qKSAoXFxTKikoPzogKFxcUyopKT8vLFxuICAgICAgbmFtZXM6IFsndmFsdWUnLCAndXJpJywgJ2NvbmZpZyddLCAvLyB2YWx1ZSBtYXkgaW5jbHVkZSBcIi9kaXJlY3Rpb25cIiBzdWZmaXhcbiAgICAgIGZvcm1hdDogZnVuY3Rpb24gKG8pIHtcbiAgICAgICAgcmV0dXJuIChvLmNvbmZpZyAhPSBudWxsKSA/XG4gICAgICAgICAgXCJleHRtYXA6JXMgJXMgJXNcIjpcbiAgICAgICAgICBcImV4dG1hcDolcyAlc1wiO1xuICAgICAgfVxuICAgIH0sXG4gICAge1xuICAgICAgLy9hPWNyeXB0bzoxIEFFU19DTV8xMjhfSE1BQ19TSEExXzgwIGlubGluZTpQUzF1UUNWZWVDRkNhblZtY2prcFB5d2pOV2hjWUQwbVhYdHhhVkJSfDJeMjB8MTozMlxuICAgICAgcHVzaDogJ2NyeXB0bycsXG4gICAgICByZWc6IC9eY3J5cHRvOihcXGQqKSAoW1xcd19dKikgKFxcUyopKD86IChcXFMqKSk/LyxcbiAgICAgIG5hbWVzOiBbJ2lkJywgJ3N1aXRlJywgJ2NvbmZpZycsICdzZXNzaW9uQ29uZmlnJ10sXG4gICAgICBmb3JtYXQ6IGZ1bmN0aW9uIChvKSB7XG4gICAgICAgIHJldHVybiAoby5zZXNzaW9uQ29uZmlnICE9IG51bGwpID9cbiAgICAgICAgICBcImNyeXB0bzolZCAlcyAlcyAlc1wiOlxuICAgICAgICAgIFwiY3J5cHRvOiVkICVzICVzXCI7XG4gICAgICB9XG4gICAgfSxcbiAgICB7IC8vYT1zZXR1cDphY3RwYXNzXG4gICAgICBuYW1lOiAnc2V0dXAnLFxuICAgICAgcmVnOiAvXnNldHVwOihcXHcqKS8sXG4gICAgICBmb3JtYXQ6IFwic2V0dXA6JXNcIlxuICAgIH0sXG4gICAgeyAvL2E9bWlkOjFcbiAgICAgIG5hbWU6ICdtaWQnLFxuICAgICAgcmVnOiAvXm1pZDooW15cXHNdKikvLFxuICAgICAgZm9ybWF0OiBcIm1pZDolc1wiXG4gICAgfSxcbiAgICB7IC8vYT1tc2lkOjBjOGIwNjRkLWQ4MDctNDNiNC1iNDM0LWY5MmE4ODlkODU4NyA5ODE3ODY4NS1kNDA5LTQ2ZTAtOGUxNi03ZWYwZGIwZGI2NGFcbiAgICAgIG5hbWU6ICdtc2lkJyxcbiAgICAgIHJlZzogL15tc2lkOiguKikvLFxuICAgICAgZm9ybWF0OiBcIm1zaWQ6JXNcIlxuICAgIH0sXG4gICAgeyAvL2E9cHRpbWU6MjBcbiAgICAgIG5hbWU6ICdwdGltZScsXG4gICAgICByZWc6IC9ecHRpbWU6KFxcZCopLyxcbiAgICAgIGZvcm1hdDogXCJwdGltZTolZFwiXG4gICAgfSxcbiAgICB7IC8vYT1tYXhwdGltZTo2MFxuICAgICAgbmFtZTogJ21heHB0aW1lJyxcbiAgICAgIHJlZzogL15tYXhwdGltZTooXFxkKikvLFxuICAgICAgZm9ybWF0OiBcIm1heHB0aW1lOiVkXCJcbiAgICB9LFxuICAgIHsgLy9hPXNlbmRyZWN2XG4gICAgICBuYW1lOiAnZGlyZWN0aW9uJyxcbiAgICAgIHJlZzogL14oc2VuZHJlY3Z8cmVjdm9ubHl8c2VuZG9ubHl8aW5hY3RpdmUpL1xuICAgIH0sXG4gICAgeyAvL2E9aWNlLWxpdGVcbiAgICAgIG5hbWU6ICdpY2VsaXRlJyxcbiAgICAgIHJlZzogL14oaWNlLWxpdGUpL1xuICAgIH0sXG4gICAgeyAvL2E9aWNlLXVmcmFnOkY3Z0lcbiAgICAgIG5hbWU6ICdpY2VVZnJhZycsXG4gICAgICByZWc6IC9eaWNlLXVmcmFnOihcXFMqKS8sXG4gICAgICBmb3JtYXQ6IFwiaWNlLXVmcmFnOiVzXCJcbiAgICB9LFxuICAgIHsgLy9hPWljZS1wd2Q6eDljbWwvWXppY2hWMitYbGhpTXU4Z1xuICAgICAgbmFtZTogJ2ljZVB3ZCcsXG4gICAgICByZWc6IC9eaWNlLXB3ZDooXFxTKikvLFxuICAgICAgZm9ybWF0OiBcImljZS1wd2Q6JXNcIlxuICAgIH0sXG4gICAgeyAvL2E9ZmluZ2VycHJpbnQ6U0hBLTEgMDA6MTE6MjI6MzM6NDQ6NTU6NjY6Nzc6ODg6OTk6QUE6QkI6Q0M6REQ6RUU6RkY6MDA6MTE6MjI6MzNcbiAgICAgIG5hbWU6ICdmaW5nZXJwcmludCcsXG4gICAgICByZWc6IC9eZmluZ2VycHJpbnQ6KFxcUyopIChcXFMqKS8sXG4gICAgICBuYW1lczogWyd0eXBlJywgJ2hhc2gnXSxcbiAgICAgIGZvcm1hdDogXCJmaW5nZXJwcmludDolcyAlc1wiXG4gICAgfSxcbiAgICB7XG4gICAgICAvL2E9Y2FuZGlkYXRlOjAgMSBVRFAgMjExMzY2NzMyNyAyMDMuMC4xMTMuMSA1NDQwMCB0eXAgaG9zdFxuICAgICAgLy9hPWNhbmRpZGF0ZToxMTYyODc1MDgxIDEgdWRwIDIxMTM5MzcxNTEgMTkyLjE2OC4zNC43NSA2MDAxNyB0eXAgaG9zdCBnZW5lcmF0aW9uIDBcbiAgICAgIC8vYT1jYW5kaWRhdGU6MzI4OTkxMjk1NyAyIHVkcCAxODQ1NTAxNjk1IDE5My44NC43Ny4xOTQgNjAwMTcgdHlwIHNyZmx4IHJhZGRyIDE5Mi4xNjguMzQuNzUgcnBvcnQgNjAwMTcgZ2VuZXJhdGlvbiAwXG4gICAgICAvL2E9Y2FuZGlkYXRlOjIyOTgxNTYyMCAxIHRjcCAxNTE4MjgwNDQ3IDE5Mi4xNjguMTUwLjE5IDYwMDE3IHR5cCBob3N0IHRjcHR5cGUgYWN0aXZlIGdlbmVyYXRpb24gMFxuICAgICAgLy9hPWNhbmRpZGF0ZTozMjg5OTEyOTU3IDIgdGNwIDE4NDU1MDE2OTUgMTkzLjg0Ljc3LjE5NCA2MDAxNyB0eXAgc3JmbHggcmFkZHIgMTkyLjE2OC4zNC43NSBycG9ydCA2MDAxNyB0Y3B0eXBlIHBhc3NpdmUgZ2VuZXJhdGlvbiAwXG4gICAgICBwdXNoOidjYW5kaWRhdGVzJyxcbiAgICAgIHJlZzogL15jYW5kaWRhdGU6KFxcUyopIChcXGQqKSAoXFxTKikgKFxcZCopIChcXFMqKSAoXFxkKikgdHlwIChcXFMqKSg/OiByYWRkciAoXFxTKikgcnBvcnQgKFxcZCopKT8oPzogdGNwdHlwZSAoXFxTKikpPyg/OiBnZW5lcmF0aW9uIChcXGQqKSk/LyxcbiAgICAgIG5hbWVzOiBbJ2ZvdW5kYXRpb24nLCAnY29tcG9uZW50JywgJ3RyYW5zcG9ydCcsICdwcmlvcml0eScsICdpcCcsICdwb3J0JywgJ3R5cGUnLCAncmFkZHInLCAncnBvcnQnLCAndGNwdHlwZScsICdnZW5lcmF0aW9uJ10sXG4gICAgICBmb3JtYXQ6IGZ1bmN0aW9uIChvKSB7XG4gICAgICAgIHZhciBzdHIgPSBcImNhbmRpZGF0ZTolcyAlZCAlcyAlZCAlcyAlZCB0eXAgJXNcIjtcblxuICAgICAgICBzdHIgKz0gKG8ucmFkZHIgIT0gbnVsbCkgPyBcIiByYWRkciAlcyBycG9ydCAlZFwiIDogXCIldiV2XCI7XG5cbiAgICAgICAgLy8gTkI6IGNhbmRpZGF0ZSBoYXMgdGhyZWUgb3B0aW9uYWwgY2h1bmtzLCBzbyAldm9pZCBtaWRkbGVzIG9uZSBpZiBpdCdzIG1pc3NpbmdcbiAgICAgICAgc3RyICs9IChvLnRjcHR5cGUgIT0gbnVsbCkgPyBcIiB0Y3B0eXBlICVzXCIgOiBcIiV2XCI7XG5cbiAgICAgICAgaWYgKG8uZ2VuZXJhdGlvbiAhPSBudWxsKSB7XG4gICAgICAgICAgc3RyICs9IFwiIGdlbmVyYXRpb24gJWRcIjtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gc3RyO1xuICAgICAgfVxuICAgIH0sXG4gICAgeyAvL2E9ZW5kLW9mLWNhbmRpZGF0ZXMgKGtlZXAgYWZ0ZXIgdGhlIGNhbmRpZGF0ZXMgbGluZSBmb3IgcmVhZGFiaWxpdHkpXG4gICAgICBuYW1lOiAnZW5kT2ZDYW5kaWRhdGVzJyxcbiAgICAgIHJlZzogL14oZW5kLW9mLWNhbmRpZGF0ZXMpL1xuICAgIH0sXG4gICAgeyAvL2E9cmVtb3RlLWNhbmRpZGF0ZXM6MSAyMDMuMC4xMTMuMSA1NDQwMCAyIDIwMy4wLjExMy4xIDU0NDAxIC4uLlxuICAgICAgbmFtZTogJ3JlbW90ZUNhbmRpZGF0ZXMnLFxuICAgICAgcmVnOiAvXnJlbW90ZS1jYW5kaWRhdGVzOiguKikvLFxuICAgICAgZm9ybWF0OiBcInJlbW90ZS1jYW5kaWRhdGVzOiVzXCJcbiAgICB9LFxuICAgIHsgLy9hPWljZS1vcHRpb25zOmdvb2dsZS1pY2VcbiAgICAgIG5hbWU6ICdpY2VPcHRpb25zJyxcbiAgICAgIHJlZzogL15pY2Utb3B0aW9uczooXFxTKikvLFxuICAgICAgZm9ybWF0OiBcImljZS1vcHRpb25zOiVzXCJcbiAgICB9LFxuICAgIHsgLy9hPXNzcmM6MjU2NjEwNzU2OSBjbmFtZTp0OVlVOE0xVXhURjhZMUExXG4gICAgICBwdXNoOiBcInNzcmNzXCIsXG4gICAgICByZWc6IC9ec3NyYzooXFxkKikgKFtcXHdfXSopOiguKikvLFxuICAgICAgbmFtZXM6IFsnaWQnLCAnYXR0cmlidXRlJywgJ3ZhbHVlJ10sXG4gICAgICBmb3JtYXQ6IFwic3NyYzolZCAlczolc1wiXG4gICAgfSxcbiAgICB7IC8vYT1zc3JjLWdyb3VwOkZFQyAxIDJcbiAgICAgIHB1c2g6IFwic3NyY0dyb3Vwc1wiLFxuICAgICAgcmVnOiAvXnNzcmMtZ3JvdXA6KFxcdyopICguKikvLFxuICAgICAgbmFtZXM6IFsnc2VtYW50aWNzJywgJ3NzcmNzJ10sXG4gICAgICBmb3JtYXQ6IFwic3NyYy1ncm91cDolcyAlc1wiXG4gICAgfSxcbiAgICB7IC8vYT1tc2lkLXNlbWFudGljOiBXTVMgSnZsYW01WDNTWDFPUDZwbjIweldvZ3ZhS0p6NUhqZjlPbmxWXG4gICAgICBuYW1lOiBcIm1zaWRTZW1hbnRpY1wiLFxuICAgICAgcmVnOiAvXm1zaWQtc2VtYW50aWM6XFxzPyhcXHcqKSAoXFxTKikvLFxuICAgICAgbmFtZXM6IFsnc2VtYW50aWMnLCAndG9rZW4nXSxcbiAgICAgIGZvcm1hdDogXCJtc2lkLXNlbWFudGljOiAlcyAlc1wiIC8vIHNwYWNlIGFmdGVyIFwiOlwiIGlzIG5vdCBhY2NpZGVudGFsXG4gICAgfSxcbiAgICB7IC8vYT1ncm91cDpCVU5ETEUgYXVkaW8gdmlkZW9cbiAgICAgIHB1c2g6ICdncm91cHMnLFxuICAgICAgcmVnOiAvXmdyb3VwOihcXHcqKSAoLiopLyxcbiAgICAgIG5hbWVzOiBbJ3R5cGUnLCAnbWlkcyddLFxuICAgICAgZm9ybWF0OiBcImdyb3VwOiVzICVzXCJcbiAgICB9LFxuICAgIHsgLy9hPXJ0Y3AtbXV4XG4gICAgICBuYW1lOiAncnRjcE11eCcsXG4gICAgICByZWc6IC9eKHJ0Y3AtbXV4KS9cbiAgICB9LFxuICAgIHsgLy9hPXJ0Y3AtcnNpemVcbiAgICAgIG5hbWU6ICdydGNwUnNpemUnLFxuICAgICAgcmVnOiAvXihydGNwLXJzaXplKS9cbiAgICB9LFxuICAgIHsgLy8gYW55IGE9IHRoYXQgd2UgZG9uJ3QgdW5kZXJzdGFuZCBpcyBrZXB0cyB2ZXJiYXRpbSBvbiBtZWRpYS5pbnZhbGlkXG4gICAgICBwdXNoOiAnaW52YWxpZCcsXG4gICAgICBuYW1lczogW1widmFsdWVcIl1cbiAgICB9XG4gIF1cbn07XG5cbi8vIHNldCBzZW5zaWJsZSBkZWZhdWx0cyB0byBhdm9pZCBwb2xsdXRpbmcgdGhlIGdyYW1tYXIgd2l0aCBib3JpbmcgZGV0YWlsc1xuT2JqZWN0LmtleXMoZ3JhbW1hcikuZm9yRWFjaChmdW5jdGlvbiAoa2V5KSB7XG4gIHZhciBvYmpzID0gZ3JhbW1hcltrZXldO1xuICBvYmpzLmZvckVhY2goZnVuY3Rpb24gKG9iaikge1xuICAgIGlmICghb2JqLnJlZykge1xuICAgICAgb2JqLnJlZyA9IC8oLiopLztcbiAgICB9XG4gICAgaWYgKCFvYmouZm9ybWF0KSB7XG4gICAgICBvYmouZm9ybWF0ID0gXCIlc1wiO1xuICAgIH1cbiAgfSk7XG59KTtcbiIsInZhciBwYXJzZXIgPSByZXF1aXJlKCcuL3BhcnNlcicpO1xudmFyIHdyaXRlciA9IHJlcXVpcmUoJy4vd3JpdGVyJyk7XG5cbmV4cG9ydHMud3JpdGUgPSB3cml0ZXI7XG5leHBvcnRzLnBhcnNlID0gcGFyc2VyLnBhcnNlO1xuZXhwb3J0cy5wYXJzZUZtdHBDb25maWcgPSBwYXJzZXIucGFyc2VGbXRwQ29uZmlnO1xuZXhwb3J0cy5wYXJzZVBheWxvYWRzID0gcGFyc2VyLnBhcnNlUGF5bG9hZHM7XG5leHBvcnRzLnBhcnNlUmVtb3RlQ2FuZGlkYXRlcyA9IHBhcnNlci5wYXJzZVJlbW90ZUNhbmRpZGF0ZXM7XG4iLCJ2YXIgdG9JbnRJZkludCA9IGZ1bmN0aW9uICh2KSB7XG4gIHJldHVybiBTdHJpbmcoTnVtYmVyKHYpKSA9PT0gdiA/IE51bWJlcih2KSA6IHY7XG59O1xuXG52YXIgYXR0YWNoUHJvcGVydGllcyA9IGZ1bmN0aW9uIChtYXRjaCwgbG9jYXRpb24sIG5hbWVzLCByYXdOYW1lKSB7XG4gIGlmIChyYXdOYW1lICYmICFuYW1lcykge1xuICAgIGxvY2F0aW9uW3Jhd05hbWVdID0gdG9JbnRJZkludChtYXRjaFsxXSk7XG4gIH1cbiAgZWxzZSB7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBuYW1lcy5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgaWYgKG1hdGNoW2krMV0gIT0gbnVsbCkge1xuICAgICAgICBsb2NhdGlvbltuYW1lc1tpXV0gPSB0b0ludElmSW50KG1hdGNoW2krMV0pO1xuICAgICAgfVxuICAgIH1cbiAgfVxufTtcblxudmFyIHBhcnNlUmVnID0gZnVuY3Rpb24gKG9iaiwgbG9jYXRpb24sIGNvbnRlbnQpIHtcbiAgdmFyIG5lZWRzQmxhbmsgPSBvYmoubmFtZSAmJiBvYmoubmFtZXM7XG4gIGlmIChvYmoucHVzaCAmJiAhbG9jYXRpb25bb2JqLnB1c2hdKSB7XG4gICAgbG9jYXRpb25bb2JqLnB1c2hdID0gW107XG4gIH1cbiAgZWxzZSBpZiAobmVlZHNCbGFuayAmJiAhbG9jYXRpb25bb2JqLm5hbWVdKSB7XG4gICAgbG9jYXRpb25bb2JqLm5hbWVdID0ge307XG4gIH1cbiAgdmFyIGtleUxvY2F0aW9uID0gb2JqLnB1c2ggP1xuICAgIHt9IDogIC8vIGJsYW5rIG9iamVjdCB0aGF0IHdpbGwgYmUgcHVzaGVkXG4gICAgbmVlZHNCbGFuayA/IGxvY2F0aW9uW29iai5uYW1lXSA6IGxvY2F0aW9uOyAvLyBvdGhlcndpc2UsIG5hbWVkIGxvY2F0aW9uIG9yIHJvb3RcblxuICBhdHRhY2hQcm9wZXJ0aWVzKGNvbnRlbnQubWF0Y2gob2JqLnJlZyksIGtleUxvY2F0aW9uLCBvYmoubmFtZXMsIG9iai5uYW1lKTtcblxuICBpZiAob2JqLnB1c2gpIHtcbiAgICBsb2NhdGlvbltvYmoucHVzaF0ucHVzaChrZXlMb2NhdGlvbik7XG4gIH1cbn07XG5cbnZhciBncmFtbWFyID0gcmVxdWlyZSgnLi9ncmFtbWFyJyk7XG52YXIgdmFsaWRMaW5lID0gUmVnRXhwLnByb3RvdHlwZS50ZXN0LmJpbmQoL14oW2Etel0pPSguKikvKTtcblxuZXhwb3J0cy5wYXJzZSA9IGZ1bmN0aW9uIChzZHApIHtcbiAgdmFyIHNlc3Npb24gPSB7fVxuICAgICwgbWVkaWEgPSBbXVxuICAgICwgbG9jYXRpb24gPSBzZXNzaW9uOyAvLyBwb2ludHMgYXQgd2hlcmUgcHJvcGVydGllcyBnbyB1bmRlciAob25lIG9mIHRoZSBhYm92ZSlcblxuICAvLyBwYXJzZSBsaW5lcyB3ZSB1bmRlcnN0YW5kXG4gIHNkcC5zcGxpdCgvKFxcclxcbnxcXHJ8XFxuKS8pLmZpbHRlcih2YWxpZExpbmUpLmZvckVhY2goZnVuY3Rpb24gKGwpIHtcbiAgICB2YXIgdHlwZSA9IGxbMF07XG4gICAgdmFyIGNvbnRlbnQgPSBsLnNsaWNlKDIpO1xuICAgIGlmICh0eXBlID09PSAnbScpIHtcbiAgICAgIG1lZGlhLnB1c2goe3J0cDogW10sIGZtdHA6IFtdfSk7XG4gICAgICBsb2NhdGlvbiA9IG1lZGlhW21lZGlhLmxlbmd0aC0xXTsgLy8gcG9pbnQgYXQgbGF0ZXN0IG1lZGlhIGxpbmVcbiAgICB9XG5cbiAgICBmb3IgKHZhciBqID0gMDsgaiA8IChncmFtbWFyW3R5cGVdIHx8IFtdKS5sZW5ndGg7IGogKz0gMSkge1xuICAgICAgdmFyIG9iaiA9IGdyYW1tYXJbdHlwZV1bal07XG4gICAgICBpZiAob2JqLnJlZy50ZXN0KGNvbnRlbnQpKSB7XG4gICAgICAgIHJldHVybiBwYXJzZVJlZyhvYmosIGxvY2F0aW9uLCBjb250ZW50KTtcbiAgICAgIH1cbiAgICB9XG4gIH0pO1xuXG4gIHNlc3Npb24ubWVkaWEgPSBtZWRpYTsgLy8gbGluayBpdCB1cFxuICByZXR1cm4gc2Vzc2lvbjtcbn07XG5cbnZhciBmbXRwUmVkdWNlciA9IGZ1bmN0aW9uIChhY2MsIGV4cHIpIHtcbiAgdmFyIHMgPSBleHByLnNwbGl0KCc9Jyk7XG4gIGlmIChzLmxlbmd0aCA9PT0gMikge1xuICAgIGFjY1tzWzBdXSA9IHRvSW50SWZJbnQoc1sxXSk7XG4gIH1cbiAgcmV0dXJuIGFjYztcbn07XG5cbmV4cG9ydHMucGFyc2VGbXRwQ29uZmlnID0gZnVuY3Rpb24gKHN0cikge1xuICByZXR1cm4gc3RyLnNwbGl0KC9cXDtcXHM/LykucmVkdWNlKGZtdHBSZWR1Y2VyLCB7fSk7XG59O1xuXG5leHBvcnRzLnBhcnNlUGF5bG9hZHMgPSBmdW5jdGlvbiAoc3RyKSB7XG4gIHJldHVybiBzdHIuc3BsaXQoJyAnKS5tYXAoTnVtYmVyKTtcbn07XG5cbmV4cG9ydHMucGFyc2VSZW1vdGVDYW5kaWRhdGVzID0gZnVuY3Rpb24gKHN0cikge1xuICB2YXIgY2FuZGlkYXRlcyA9IFtdO1xuICB2YXIgcGFydHMgPSBzdHIuc3BsaXQoJyAnKS5tYXAodG9JbnRJZkludCk7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgcGFydHMubGVuZ3RoOyBpICs9IDMpIHtcbiAgICBjYW5kaWRhdGVzLnB1c2goe1xuICAgICAgY29tcG9uZW50OiBwYXJ0c1tpXSxcbiAgICAgIGlwOiBwYXJ0c1tpICsgMV0sXG4gICAgICBwb3J0OiBwYXJ0c1tpICsgMl1cbiAgICB9KTtcbiAgfVxuICByZXR1cm4gY2FuZGlkYXRlcztcbn07XG4iLCJ2YXIgZ3JhbW1hciA9IHJlcXVpcmUoJy4vZ3JhbW1hcicpO1xuXG4vLyBjdXN0b21pemVkIHV0aWwuZm9ybWF0IC0gZGlzY2FyZHMgZXhjZXNzIGFyZ3VtZW50cyBhbmQgY2FuIHZvaWQgbWlkZGxlIG9uZXNcbnZhciBmb3JtYXRSZWdFeHAgPSAvJVtzZHYlXS9nO1xudmFyIGZvcm1hdCA9IGZ1bmN0aW9uIChmb3JtYXRTdHIpIHtcbiAgdmFyIGkgPSAxO1xuICB2YXIgYXJncyA9IGFyZ3VtZW50cztcbiAgdmFyIGxlbiA9IGFyZ3MubGVuZ3RoO1xuICByZXR1cm4gZm9ybWF0U3RyLnJlcGxhY2UoZm9ybWF0UmVnRXhwLCBmdW5jdGlvbiAoeCkge1xuICAgIGlmIChpID49IGxlbikge1xuICAgICAgcmV0dXJuIHg7IC8vIG1pc3NpbmcgYXJndW1lbnRcbiAgICB9XG4gICAgdmFyIGFyZyA9IGFyZ3NbaV07XG4gICAgaSArPSAxO1xuICAgIHN3aXRjaCAoeCkge1xuICAgICAgY2FzZSAnJSUnOlxuICAgICAgICByZXR1cm4gJyUnO1xuICAgICAgY2FzZSAnJXMnOlxuICAgICAgICByZXR1cm4gU3RyaW5nKGFyZyk7XG4gICAgICBjYXNlICclZCc6XG4gICAgICAgIHJldHVybiBOdW1iZXIoYXJnKTtcbiAgICAgIGNhc2UgJyV2JzpcbiAgICAgICAgcmV0dXJuICcnO1xuICAgIH1cbiAgfSk7XG4gIC8vIE5COiB3ZSBkaXNjYXJkIGV4Y2VzcyBhcmd1bWVudHMgLSB0aGV5IGFyZSB0eXBpY2FsbHkgdW5kZWZpbmVkIGZyb20gbWFrZUxpbmVcbn07XG5cbnZhciBtYWtlTGluZSA9IGZ1bmN0aW9uICh0eXBlLCBvYmosIGxvY2F0aW9uKSB7XG4gIHZhciBzdHIgPSBvYmouZm9ybWF0IGluc3RhbmNlb2YgRnVuY3Rpb24gP1xuICAgIChvYmouZm9ybWF0KG9iai5wdXNoID8gbG9jYXRpb24gOiBsb2NhdGlvbltvYmoubmFtZV0pKSA6XG4gICAgb2JqLmZvcm1hdDtcblxuICB2YXIgYXJncyA9IFt0eXBlICsgJz0nICsgc3RyXTtcbiAgaWYgKG9iai5uYW1lcykge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgb2JqLm5hbWVzLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICB2YXIgbiA9IG9iai5uYW1lc1tpXTtcbiAgICAgIGlmIChvYmoubmFtZSkge1xuICAgICAgICBhcmdzLnB1c2gobG9jYXRpb25bb2JqLm5hbWVdW25dKTtcbiAgICAgIH1cbiAgICAgIGVsc2UgeyAvLyBmb3IgbUxpbmUgYW5kIHB1c2ggYXR0cmlidXRlc1xuICAgICAgICBhcmdzLnB1c2gobG9jYXRpb25bb2JqLm5hbWVzW2ldXSk7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIGVsc2Uge1xuICAgIGFyZ3MucHVzaChsb2NhdGlvbltvYmoubmFtZV0pO1xuICB9XG4gIHJldHVybiBmb3JtYXQuYXBwbHkobnVsbCwgYXJncyk7XG59O1xuXG4vLyBSRkMgc3BlY2lmaWVkIG9yZGVyXG4vLyBUT0RPOiBleHRlbmQgdGhpcyB3aXRoIGFsbCB0aGUgcmVzdFxudmFyIGRlZmF1bHRPdXRlck9yZGVyID0gW1xuICAndicsICdvJywgJ3MnLCAnaScsXG4gICd1JywgJ2UnLCAncCcsICdjJyxcbiAgJ2InLCAndCcsICdyJywgJ3onLCAnYSdcbl07XG52YXIgZGVmYXVsdElubmVyT3JkZXIgPSBbJ2knLCAnYycsICdiJywgJ2EnXTtcblxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChzZXNzaW9uLCBvcHRzKSB7XG4gIG9wdHMgPSBvcHRzIHx8IHt9O1xuICAvLyBlbnN1cmUgY2VydGFpbiBwcm9wZXJ0aWVzIGV4aXN0XG4gIGlmIChzZXNzaW9uLnZlcnNpb24gPT0gbnVsbCkge1xuICAgIHNlc3Npb24udmVyc2lvbiA9IDA7IC8vIFwidj0wXCIgbXVzdCBiZSB0aGVyZSAob25seSBkZWZpbmVkIHZlcnNpb24gYXRtKVxuICB9XG4gIGlmIChzZXNzaW9uLm5hbWUgPT0gbnVsbCkge1xuICAgIHNlc3Npb24ubmFtZSA9IFwiIFwiOyAvLyBcInM9IFwiIG11c3QgYmUgdGhlcmUgaWYgbm8gbWVhbmluZ2Z1bCBuYW1lIHNldFxuICB9XG4gIHNlc3Npb24ubWVkaWEuZm9yRWFjaChmdW5jdGlvbiAobUxpbmUpIHtcbiAgICBpZiAobUxpbmUucGF5bG9hZHMgPT0gbnVsbCkge1xuICAgICAgbUxpbmUucGF5bG9hZHMgPSBcIlwiO1xuICAgIH1cbiAgfSk7XG5cbiAgdmFyIG91dGVyT3JkZXIgPSBvcHRzLm91dGVyT3JkZXIgfHwgZGVmYXVsdE91dGVyT3JkZXI7XG4gIHZhciBpbm5lck9yZGVyID0gb3B0cy5pbm5lck9yZGVyIHx8IGRlZmF1bHRJbm5lck9yZGVyO1xuICB2YXIgc2RwID0gW107XG5cbiAgLy8gbG9vcCB0aHJvdWdoIG91dGVyT3JkZXIgZm9yIG1hdGNoaW5nIHByb3BlcnRpZXMgb24gc2Vzc2lvblxuICBvdXRlck9yZGVyLmZvckVhY2goZnVuY3Rpb24gKHR5cGUpIHtcbiAgICBncmFtbWFyW3R5cGVdLmZvckVhY2goZnVuY3Rpb24gKG9iaikge1xuICAgICAgaWYgKG9iai5uYW1lIGluIHNlc3Npb24gJiYgc2Vzc2lvbltvYmoubmFtZV0gIT0gbnVsbCkge1xuICAgICAgICBzZHAucHVzaChtYWtlTGluZSh0eXBlLCBvYmosIHNlc3Npb24pKTtcbiAgICAgIH1cbiAgICAgIGVsc2UgaWYgKG9iai5wdXNoIGluIHNlc3Npb24gJiYgc2Vzc2lvbltvYmoucHVzaF0gIT0gbnVsbCkge1xuICAgICAgICBzZXNzaW9uW29iai5wdXNoXS5mb3JFYWNoKGZ1bmN0aW9uIChlbCkge1xuICAgICAgICAgIHNkcC5wdXNoKG1ha2VMaW5lKHR5cGUsIG9iaiwgZWwpKTtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH0pO1xuXG4gIC8vIHRoZW4gZm9yIGVhY2ggbWVkaWEgbGluZSwgZm9sbG93IHRoZSBpbm5lck9yZGVyXG4gIHNlc3Npb24ubWVkaWEuZm9yRWFjaChmdW5jdGlvbiAobUxpbmUpIHtcbiAgICBzZHAucHVzaChtYWtlTGluZSgnbScsIGdyYW1tYXIubVswXSwgbUxpbmUpKTtcblxuICAgIGlubmVyT3JkZXIuZm9yRWFjaChmdW5jdGlvbiAodHlwZSkge1xuICAgICAgZ3JhbW1hclt0eXBlXS5mb3JFYWNoKGZ1bmN0aW9uIChvYmopIHtcbiAgICAgICAgaWYgKG9iai5uYW1lIGluIG1MaW5lICYmIG1MaW5lW29iai5uYW1lXSAhPSBudWxsKSB7XG4gICAgICAgICAgc2RwLnB1c2gobWFrZUxpbmUodHlwZSwgb2JqLCBtTGluZSkpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKG9iai5wdXNoIGluIG1MaW5lICYmIG1MaW5lW29iai5wdXNoXSAhPSBudWxsKSB7XG4gICAgICAgICAgbUxpbmVbb2JqLnB1c2hdLmZvckVhY2goZnVuY3Rpb24gKGVsKSB7XG4gICAgICAgICAgICBzZHAucHVzaChtYWtlTGluZSh0eXBlLCBvYmosIGVsKSk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH0pO1xuICB9KTtcblxuICByZXR1cm4gc2RwLmpvaW4oJ1xcclxcbicpICsgJ1xcclxcbic7XG59O1xuIiwiLyogQ29weXJpZ2h0IEAgMjAxNSBBdGxhc3NpYW4gUHR5IEx0ZFxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGFycmF5RXF1YWxzKGFycmF5KSB7XG4gICAgLy8gaWYgdGhlIG90aGVyIGFycmF5IGlzIGEgZmFsc3kgdmFsdWUsIHJldHVyblxuICAgIGlmICghYXJyYXkpXG4gICAgICAgIHJldHVybiBmYWxzZTtcblxuICAgIC8vIGNvbXBhcmUgbGVuZ3RocyAtIGNhbiBzYXZlIGEgbG90IG9mIHRpbWVcbiAgICBpZiAodGhpcy5sZW5ndGggIT0gYXJyYXkubGVuZ3RoKVxuICAgICAgICByZXR1cm4gZmFsc2U7XG5cbiAgICBmb3IgKHZhciBpID0gMCwgbCA9IHRoaXMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgICAgIC8vIENoZWNrIGlmIHdlIGhhdmUgbmVzdGVkIGFycmF5c1xuICAgICAgICBpZiAodGhpc1tpXSBpbnN0YW5jZW9mIEFycmF5ICYmIGFycmF5W2ldIGluc3RhbmNlb2YgQXJyYXkpIHtcbiAgICAgICAgICAgIC8vIHJlY3Vyc2UgaW50byB0aGUgbmVzdGVkIGFycmF5c1xuICAgICAgICAgICAgaWYgKCFhcnJheUVxdWFscy5hcHBseSh0aGlzW2ldLCBbYXJyYXlbaV1dKSlcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH0gZWxzZSBpZiAodGhpc1tpXSAhPSBhcnJheVtpXSkge1xuICAgICAgICAgICAgLy8gV2FybmluZyAtIHR3byBkaWZmZXJlbnQgb2JqZWN0IGluc3RhbmNlcyB3aWxsIG5ldmVyIGJlIGVxdWFsOlxuICAgICAgICAgICAgLy8ge3g6MjB9ICE9IHt4OjIwfVxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xufTtcblxuIiwiLyogQ29weXJpZ2h0IEAgMjAxNSBBdGxhc3NpYW4gUHR5IEx0ZFxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqL1xuXG5leHBvcnRzLkludGVyb3AgPSByZXF1aXJlKCcuL2ludGVyb3AnKTtcbiIsIi8qIENvcHlyaWdodCBAIDIwMTUgQXRsYXNzaWFuIFB0eSBMdGRcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKi9cblxuLyogZ2xvYmFsIFJUQ1Nlc3Npb25EZXNjcmlwdGlvbiAqL1xuLyogZ2xvYmFsIFJUQ0ljZUNhbmRpZGF0ZSAqL1xuLyoganNoaW50IC1XMDk3ICovXG5cInVzZSBzdHJpY3RcIjtcblxudmFyIHRyYW5zZm9ybSA9IHJlcXVpcmUoJy4vdHJhbnNmb3JtJyk7XG52YXIgYXJyYXlFcXVhbHMgPSByZXF1aXJlKCcuL2FycmF5LWVxdWFscycpO1xuXG5mdW5jdGlvbiBJbnRlcm9wKCkge1xuXG4gICAgLyoqXG4gICAgICogVGhpcyBtYXAgaG9sZHMgdGhlIG1vc3QgcmVjZW50IFVuaWZpZWQgUGxhbiBvZmZlci9hbnN3ZXIgU0RQIHRoYXQgd2FzXG4gICAgICogY29udmVydGVkIHRvIFBsYW4gQiwgd2l0aCB0aGUgU0RQIHR5cGUgKCdvZmZlcicgb3IgJ2Fuc3dlcicpIGFzIGtleXMgYW5kXG4gICAgICogdGhlIFNEUCBzdHJpbmcgYXMgdmFsdWVzLlxuICAgICAqXG4gICAgICogQHR5cGUge3t9fVxuICAgICAqL1xuICAgIHRoaXMuY2FjaGUgPSB7XG4gICAgICAgIG1sQjJVTWFwIDoge30sXG4gICAgICAgIG1sVTJCTWFwIDoge31cbiAgICB9O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IEludGVyb3A7XG5cbi8qKlxuICogQ2hhbmdlcyB0aGUgY2FuZGlkYXRlIGFyZ3MgdG8gbWF0Y2ggd2l0aCB0aGUgcmVsYXRlZCBVbmlmaWVkIFBsYW5cbiAqL1xuSW50ZXJvcC5wcm90b3R5cGUuY2FuZGlkYXRlVG9VbmlmaWVkUGxhbiA9IGZ1bmN0aW9uKGNhbmRpZGF0ZSkge1xuICAgIHZhciBjYW5kID0gbmV3IFJUQ0ljZUNhbmRpZGF0ZShjYW5kaWRhdGUpO1xuXG4gICAgY2FuZC5zZHBNTGluZUluZGV4ID0gdGhpcy5jYWNoZS5tbEIyVU1hcFtjYW5kLnNkcE1MaW5lSW5kZXhdO1xuICAgIC8qIFRPRE86IGNoYW5nZSBzZHBNaWQgdG8gKGF1ZGlvfHZpZGVvKS1TU1JDICovXG5cbiAgICByZXR1cm4gY2FuZDtcbn07XG5cbi8qKlxuICogQ2hhbmdlcyB0aGUgY2FuZGlkYXRlIGFyZ3MgdG8gbWF0Y2ggd2l0aCB0aGUgcmVsYXRlZCBQbGFuIEJcbiAqL1xuSW50ZXJvcC5wcm90b3R5cGUuY2FuZGlkYXRlVG9QbGFuQiA9IGZ1bmN0aW9uKGNhbmRpZGF0ZSkge1xuICAgIHZhciBjYW5kID0gbmV3IFJUQ0ljZUNhbmRpZGF0ZShjYW5kaWRhdGUpO1xuXG4gICAgaWYgKGNhbmQuc2RwTWlkLmluZGV4T2YoJ2F1ZGlvJykgPT09IDApIHtcbiAgICAgIGNhbmQuc2RwTWlkID0gJ2F1ZGlvJztcbiAgICB9IGVsc2UgaWYgKGNhbmQuc2RwTWlkLmluZGV4T2YoJ3ZpZGVvJykgPT09IDApIHtcbiAgICAgIGNhbmQuc2RwTWlkID0gJ3ZpZGVvJztcbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdjYW5kaWRhdGUgd2l0aCAnICsgY2FuZC5zZHBNaWQgKyAnIG5vdCBhbGxvd2VkJyk7XG4gICAgfVxuXG4gICAgY2FuZC5zZHBNTGluZUluZGV4ID0gdGhpcy5jYWNoZS5tbFUyQk1hcFtjYW5kLnNkcE1MaW5lSW5kZXhdO1xuXG4gICAgcmV0dXJuIGNhbmQ7XG59O1xuXG4vKipcbiAqIFJldHVybnMgdGhlIGluZGV4IG9mIHRoZSBmaXJzdCBtLWxpbmUgd2l0aCB0aGUgZ2l2ZW4gbWVkaWEgdHlwZSBhbmQgd2l0aCBhXG4gKiBkaXJlY3Rpb24gd2hpY2ggYWxsb3dzIHNlbmRpbmcsIGluIHRoZSBsYXN0IFVuaWZpZWQgUGxhbiBkZXNjcmlwdGlvbiB3aXRoXG4gKiB0eXBlIFwiYW5zd2VyXCIgY29udmVydGVkIHRvIFBsYW4gQi4gUmV0dXJucyB7bnVsbH0gaWYgdGhlcmUgaXMgbm8gc2F2ZWRcbiAqIGFuc3dlciwgb3IgaWYgbm9uZSBvZiBpdHMgbS1saW5lcyB3aXRoIHRoZSBnaXZlbiB0eXBlIGFsbG93IHNlbmRpbmcuXG4gKiBAcGFyYW0gdHlwZSB0aGUgbWVkaWEgdHlwZSAoXCJhdWRpb1wiIG9yIFwidmlkZW9cIikuXG4gKiBAcmV0dXJucyB7Kn1cbiAqL1xuSW50ZXJvcC5wcm90b3R5cGUuZ2V0Rmlyc3RTZW5kaW5nSW5kZXhGcm9tQW5zd2VyID0gZnVuY3Rpb24odHlwZSkge1xuICAgIGlmICghdGhpcy5jYWNoZS5hbnN3ZXIpIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgdmFyIHNlc3Npb24gPSB0cmFuc2Zvcm0ucGFyc2UodGhpcy5jYWNoZS5hbnN3ZXIpO1xuICAgIGlmIChzZXNzaW9uICYmIHNlc3Npb24ubWVkaWEgJiYgQXJyYXkuaXNBcnJheShzZXNzaW9uLm1lZGlhKSl7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc2Vzc2lvbi5tZWRpYS5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgaWYgKHNlc3Npb24ubWVkaWFbaV0udHlwZSA9PSB0eXBlICYmXG4gICAgICAgICAgICAgICAgKCFzZXNzaW9uLm1lZGlhW2ldLmRpcmVjdGlvbiAvKiBkZWZhdWx0IHRvIHNlbmRyZWN2ICovIHx8XG4gICAgICAgICAgICAgICAgICAgIHNlc3Npb24ubWVkaWFbaV0uZGlyZWN0aW9uID09PSAnc2VuZHJlY3YnIHx8XG4gICAgICAgICAgICAgICAgICAgIHNlc3Npb24ubWVkaWFbaV0uZGlyZWN0aW9uID09PSAnc2VuZG9ubHknKSl7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gbnVsbDtcbn07XG5cbi8qKlxuICogVGhpcyBtZXRob2QgdHJhbnNmb3JtcyBhIFVuaWZpZWQgUGxhbiBTRFAgdG8gYW4gZXF1aXZhbGVudCBQbGFuIEIgU0RQLiBBXG4gKiBQZWVyQ29ubmVjdGlvbiB3cmFwcGVyIHRyYW5zZm9ybXMgdGhlIFNEUCB0byBQbGFuIEIgYmVmb3JlIHBhc3NpbmcgaXQgdG8gdGhlXG4gKiBhcHBsaWNhdGlvbi5cbiAqXG4gKiBAcGFyYW0gZGVzY1xuICogQHJldHVybnMgeyp9XG4gKi9cbkludGVyb3AucHJvdG90eXBlLnRvUGxhbkIgPSBmdW5jdGlvbihkZXNjKSB7XG4gICAgdmFyIHNlbGYgPSB0aGlzO1xuICAgIC8vI3JlZ2lvbiBQcmVsaW1pbmFyeSBpbnB1dCB2YWxpZGF0aW9uLlxuXG4gICAgaWYgKHR5cGVvZiBkZXNjICE9PSAnb2JqZWN0JyB8fCBkZXNjID09PSBudWxsIHx8XG4gICAgICAgIHR5cGVvZiBkZXNjLnNkcCAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgY29uc29sZS53YXJuKCdBbiBlbXB0eSBkZXNjcmlwdGlvbiB3YXMgcGFzc2VkIGFzIGFuIGFyZ3VtZW50LicpO1xuICAgICAgICByZXR1cm4gZGVzYztcbiAgICB9XG5cbiAgICAvLyBPYmplY3RpZnkgdGhlIFNEUCBmb3IgZWFzaWVyIG1hbmlwdWxhdGlvbi5cbiAgICB2YXIgc2Vzc2lvbiA9IHRyYW5zZm9ybS5wYXJzZShkZXNjLnNkcCk7XG5cbiAgICAvLyBJZiB0aGUgU0RQIGNvbnRhaW5zIG5vIG1lZGlhLCB0aGVyZSdzIG5vdGhpbmcgdG8gdHJhbnNmb3JtLlxuICAgIGlmICh0eXBlb2Ygc2Vzc2lvbi5tZWRpYSA9PT0gJ3VuZGVmaW5lZCcgfHxcbiAgICAgICAgIUFycmF5LmlzQXJyYXkoc2Vzc2lvbi5tZWRpYSkgfHwgc2Vzc2lvbi5tZWRpYS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgY29uc29sZS53YXJuKCdUaGUgZGVzY3JpcHRpb24gaGFzIG5vIG1lZGlhLicpO1xuICAgICAgICByZXR1cm4gZGVzYztcbiAgICB9XG5cbiAgICAvLyBUcnkgc29tZSBoZXVyaXN0aWNzIHRvIFwibWFrZSBzdXJlXCIgdGhpcyBpcyBhIFVuaWZpZWQgUGxhbiBTRFAuIFBsYW4gQlxuICAgIC8vIFNEUCBoYXMgYSB2aWRlbywgYW4gYXVkaW8gYW5kIGEgZGF0YSBcImNoYW5uZWxcIiBhdCBtb3N0LlxuICAgIGlmIChzZXNzaW9uLm1lZGlhLmxlbmd0aCA8PSAzICYmIHNlc3Npb24ubWVkaWEuZXZlcnkoZnVuY3Rpb24obSkge1xuICAgICAgICAgICAgcmV0dXJuIFsndmlkZW8nLCAnYXVkaW8nLCAnZGF0YSddLmluZGV4T2YobS5taWQpICE9PSAtMTtcbiAgICAgICAgfSkpIHtcbiAgICAgICAgY29uc29sZS53YXJuKCdUaGlzIGRlc2NyaXB0aW9uIGRvZXMgbm90IGxvb2sgbGlrZSBVbmlmaWVkIFBsYW4uJyk7XG4gICAgICAgIHJldHVybiBkZXNjO1xuICAgIH1cblxuICAgIC8vI2VuZHJlZ2lvblxuXG4gICAgLy8gSEFDSyBodHRwczovL2J1Z3ppbGxhLm1vemlsbGEub3JnL3Nob3dfYnVnLmNnaT9pZD0xMTEzNDQzXG4gICAgdmFyIHNkcCA9IGRlc2Muc2RwO1xuICAgIHZhciByZXdyaXRlID0gZmFsc2U7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBzZXNzaW9uLm1lZGlhLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHZhciB1TGluZSA9IHNlc3Npb24ubWVkaWFbaV07XG4gICAgICAgIHVMaW5lLnJ0cC5mb3JFYWNoKGZ1bmN0aW9uKHJ0cCkge1xuICAgICAgICAgICAgaWYgKHJ0cC5jb2RlYyA9PT0gJ05VTEwnKVxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHJld3JpdGUgPSB0cnVlO1xuICAgICAgICAgICAgICAgIHZhciBvZmZlciA9IHRyYW5zZm9ybS5wYXJzZShzZWxmLmNhY2hlLm9mZmVyKTtcbiAgICAgICAgICAgICAgICBydHAuY29kZWMgPSBvZmZlci5tZWRpYVtpXS5ydHBbMF0uY29kZWM7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBpZiAocmV3cml0ZSkge1xuICAgICAgICBzZHAgPSB0cmFuc2Zvcm0ud3JpdGUoc2Vzc2lvbik7XG4gICAgfVxuXG4gICAgLy8gVW5pZmllZCBQbGFuIFNEUCBpcyBvdXIgXCJwcmVjaW91c1wiLiBDYWNoZSBpdCBmb3IgbGF0ZXIgdXNlIGluIHRoZSBQbGFuIEJcbiAgICAvLyAtPiBVbmlmaWVkIFBsYW4gdHJhbnNmb3JtYXRpb24uXG4gICAgdGhpcy5jYWNoZVtkZXNjLnR5cGVdID0gc2RwO1xuXG4gICAgLy8jcmVnaW9uIENvbnZlcnQgZnJvbSBVbmlmaWVkIFBsYW4gdG8gUGxhbiBCLlxuXG4gICAgLy8gV2UgcmVidWlsZCB0aGUgc2Vzc2lvbi5tZWRpYSBhcnJheS5cbiAgICB2YXIgbWVkaWEgPSBzZXNzaW9uLm1lZGlhO1xuICAgIHNlc3Npb24ubWVkaWEgPSBbXTtcblxuICAgIC8vIEFzc29jaWF0aXZlIGFycmF5IHRoYXQgbWFwcyBjaGFubmVsIHR5cGVzIHRvIGNoYW5uZWwgb2JqZWN0cyBmb3IgZmFzdFxuICAgIC8vIGFjY2VzcyB0byBjaGFubmVsIG9iamVjdHMgYnkgdGhlaXIgdHlwZSwgZS5nLiB0eXBlMmJsWydhdWRpbyddLT5jaGFubmVsXG4gICAgLy8gb2JqLlxuICAgIHZhciB0eXBlMmJsID0ge307XG5cbiAgICAvLyBVc2VkIHRvIGJ1aWxkIHRoZSBncm91cDpCVU5ETEUgdmFsdWUgYWZ0ZXIgdGhlIGNoYW5uZWxzIGNvbnN0cnVjdGlvblxuICAgIC8vIGxvb3AuXG4gICAgdmFyIHR5cGVzID0gW107XG5cbiAgICBtZWRpYS5mb3JFYWNoKGZ1bmN0aW9uKHVMaW5lKSB7XG4gICAgICAgIC8vIHJ0Y3AtbXV4IGlzIHJlcXVpcmVkIGluIHRoZSBQbGFuIEIgU0RQLlxuICAgICAgICBpZiAoKHR5cGVvZiB1TGluZS5ydGNwTXV4ICE9PSAnc3RyaW5nJyB8fFxuICAgICAgICAgICAgdUxpbmUucnRjcE11eCAhPT0gJ3J0Y3AtbXV4JykgJiZcbiAgICAgICAgICAgIHVMaW5lLmRpcmVjdGlvbiAhPT0gJ2luYWN0aXZlJykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdDYW5ub3QgY29udmVydCB0byBQbGFuIEIgYmVjYXVzZSBtLWxpbmVzICcgK1xuICAgICAgICAgICAgICAgICd3aXRob3V0IHRoZSBydGNwLW11eCBhdHRyaWJ1dGUgd2VyZSBmb3VuZC4nKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIElmIHdlIGRvbid0IGhhdmUgYSBjaGFubmVsIGZvciB0aGlzIHVMaW5lLnR5cGUgT1IgdGhlIHNlbGVjdGVkIGlzXG4gICAgICAgIC8vIGluYWN0aXZlLCB0aGVuIHNlbGVjdCB0aGlzIHVMaW5lIGFzIHRoZSBjaGFubmVsIGJhc2lzLlxuICAgICAgICBpZiAodHlwZW9mIHR5cGUyYmxbdUxpbmUudHlwZV0gPT09ICd1bmRlZmluZWQnIHx8XG4gICAgICAgICAgICB0eXBlMmJsW3VMaW5lLnR5cGVdLmRpcmVjdGlvbiA9PT0gJ2luYWN0aXZlJykge1xuICAgICAgICAgICAgdHlwZTJibFt1TGluZS50eXBlXSA9IHVMaW5lO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHVMaW5lLnByb3RvY29sICE9IHR5cGUyYmxbdUxpbmUudHlwZV0ucHJvdG9jb2wpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0Nhbm5vdCBjb252ZXJ0IHRvIFBsYW4gQiBiZWNhdXNlIG0tbGluZXMgJyArXG4gICAgICAgICAgICAgICdoYXZlIGRpZmZlcmVudCBwcm90b2NvbHMgYW5kIHRoaXMgbGlicmFyeSBkb2VzIG5vdCBoYXZlICcgK1xuICAgICAgICAgICAgICAnc3VwcG9ydCBmb3IgdGhhdCcpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHVMaW5lLnBheWxvYWRzICE9IHR5cGUyYmxbdUxpbmUudHlwZV0ucGF5bG9hZHMpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0Nhbm5vdCBjb252ZXJ0IHRvIFBsYW4gQiBiZWNhdXNlIG0tbGluZXMgJyArXG4gICAgICAgICAgICAgICdoYXZlIGRpZmZlcmVudCBwYXlsb2FkcyBhbmQgdGhpcyBsaWJyYXJ5IGRvZXMgbm90IGhhdmUgJyArXG4gICAgICAgICAgICAgICdzdXBwb3J0IGZvciB0aGF0Jyk7XG4gICAgICAgIH1cblxuICAgIH0pO1xuXG4gICAgLy8gSW1wbG9kZSB0aGUgVW5pZmllZCBQbGFuIG0tbGluZXMvdHJhY2tzIGludG8gUGxhbiBCIGNoYW5uZWxzLlxuICAgIG1lZGlhLmZvckVhY2goZnVuY3Rpb24odUxpbmUpIHtcbiAgICAgICAgaWYgKHVMaW5lLnR5cGUgPT09ICdhcHBsaWNhdGlvbicpIHtcbiAgICAgICAgICAgIHNlc3Npb24ubWVkaWEucHVzaCh1TGluZSk7XG4gICAgICAgICAgICB0eXBlcy5wdXNoKHVMaW5lLm1pZCk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICAvLyBBZGQgc291cmNlcyB0byB0aGUgY2hhbm5lbCBhbmQgaGFuZGxlIGE9bXNpZC5cbiAgICAgICAgaWYgKHR5cGVvZiB1TGluZS5zb3VyY2VzID09PSAnb2JqZWN0Jykge1xuICAgICAgICAgICAgT2JqZWN0LmtleXModUxpbmUuc291cmNlcykuZm9yRWFjaChmdW5jdGlvbihzc3JjKSB7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiB0eXBlMmJsW3VMaW5lLnR5cGVdLnNvdXJjZXMgIT09ICdvYmplY3QnKVxuICAgICAgICAgICAgICAgICAgICB0eXBlMmJsW3VMaW5lLnR5cGVdLnNvdXJjZXMgPSB7fTtcblxuICAgICAgICAgICAgICAgIC8vIEFzc2lnbiB0aGUgc291cmNlcyB0byB0aGUgY2hhbm5lbC5cbiAgICAgICAgICAgICAgICB0eXBlMmJsW3VMaW5lLnR5cGVdLnNvdXJjZXNbc3NyY10gPVxuICAgICAgICAgICAgICAgICAgICB1TGluZS5zb3VyY2VzW3NzcmNdO1xuXG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiB1TGluZS5tc2lkICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgICAgICAgICAvLyBJbiBQbGFuIEIgdGhlIG1zaWQgaXMgYW4gU1NSQyBhdHRyaWJ1dGUuIEFsc28sIHdlIGRvbid0XG4gICAgICAgICAgICAgICAgICAgIC8vIGNhcmUgYWJvdXQgdGhlIG9ic29sZXRlIGxhYmVsIGFuZCBtc2xhYmVsIGF0dHJpYnV0ZXMuXG4gICAgICAgICAgICAgICAgICAgIC8vXG4gICAgICAgICAgICAgICAgICAgIC8vIE5vdGUgdGhhdCBpdCBpcyBub3QgZ3VhcmFudGVlZCB0aGF0IHRoZSB1TGluZSB3aWxsXG4gICAgICAgICAgICAgICAgICAgIC8vIGhhdmUgYW4gbXNpZC4gcmVjdm9ubHkgY2hhbm5lbHMgaW4gcGFydGljdWxhciBkb24ndCBoYXZlXG4gICAgICAgICAgICAgICAgICAgIC8vIG9uZS5cbiAgICAgICAgICAgICAgICAgICAgdHlwZTJibFt1TGluZS50eXBlXS5zb3VyY2VzW3NzcmNdLm1zaWQgPVxuICAgICAgICAgICAgICAgICAgICAgICAgdUxpbmUubXNpZDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgLy8gTk9URSBzc3JjcyBpbiBzc3JjIGdyb3VwcyB3aWxsIHNoYXJlIG1zaWRzLCBhc1xuICAgICAgICAgICAgICAgIC8vIGRyYWZ0LXViZXJ0aS1ydGN3ZWItcGxhbi0wMCBtYW5kYXRlcy5cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gQWRkIHNzcmMgZ3JvdXBzIHRvIHRoZSBjaGFubmVsLlxuICAgICAgICBpZiAodHlwZW9mIHVMaW5lLnNzcmNHcm91cHMgIT09ICd1bmRlZmluZWQnICYmXG4gICAgICAgICAgICAgICAgQXJyYXkuaXNBcnJheSh1TGluZS5zc3JjR3JvdXBzKSkge1xuXG4gICAgICAgICAgICAvLyBDcmVhdGUgdGhlIHNzcmNHcm91cHMgYXJyYXksIGlmIGl0J3Mgbm90IGRlZmluZWQuXG4gICAgICAgICAgICBpZiAodHlwZW9mIHR5cGUyYmxbdUxpbmUudHlwZV0uc3NyY0dyb3VwcyA9PT0gJ3VuZGVmaW5lZCcgfHxcbiAgICAgICAgICAgICAgICAgICAgIUFycmF5LmlzQXJyYXkodHlwZTJibFt1TGluZS50eXBlXS5zc3JjR3JvdXBzKSkge1xuICAgICAgICAgICAgICAgIHR5cGUyYmxbdUxpbmUudHlwZV0uc3NyY0dyb3VwcyA9IFtdO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0eXBlMmJsW3VMaW5lLnR5cGVdLnNzcmNHcm91cHMgPVxuICAgICAgICAgICAgICAgIHR5cGUyYmxbdUxpbmUudHlwZV0uc3NyY0dyb3Vwcy5jb25jYXQoXG4gICAgICAgICAgICAgICAgICAgIHVMaW5lLnNzcmNHcm91cHMpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHR5cGUyYmxbdUxpbmUudHlwZV0gPT09IHVMaW5lKSB7XG4gICAgICAgICAgICAvLyBQbGFuIEIgbWlkcyBhcmUgaW4gWydhdWRpbycsICd2aWRlbycsICdkYXRhJ11cbiAgICAgICAgICAgIHVMaW5lLm1pZCA9IHVMaW5lLnR5cGU7XG5cbiAgICAgICAgICAgIC8vIFBsYW4gQiBkb2Vzbid0IHN1cHBvcnQvbmVlZCB0aGUgYnVuZGxlLW9ubHkgYXR0cmlidXRlLlxuICAgICAgICAgICAgZGVsZXRlIHVMaW5lLmJ1bmRsZU9ubHk7XG5cbiAgICAgICAgICAgIC8vIEluIFBsYW4gQiB0aGUgbXNpZCBpcyBhbiBTU1JDIGF0dHJpYnV0ZS5cbiAgICAgICAgICAgIGRlbGV0ZSB1TGluZS5tc2lkO1xuXG5cdCAgICBpZiAodUxpbmUudHlwZSA9PSBtZWRpYVswXS50eXBlKSB7XG5cdCAgICAgIHR5cGVzLnVuc2hpZnQodUxpbmUudHlwZSk7XG5cdCAgICAgIC8vIEFkZCB0aGUgY2hhbm5lbCB0byB0aGUgbmV3IG1lZGlhIGFycmF5LlxuXHQgICAgICBzZXNzaW9uLm1lZGlhLnVuc2hpZnQodUxpbmUpO1xuXHQgICAgfSBlbHNlIHtcblx0ICAgICAgdHlwZXMucHVzaCh1TGluZS50eXBlKTtcblx0ICAgICAgLy8gQWRkIHRoZSBjaGFubmVsIHRvIHRoZSBuZXcgbWVkaWEgYXJyYXkuXG5cdCAgICAgIHNlc3Npb24ubWVkaWEucHVzaCh1TGluZSk7XG5cdCAgICB9XG4gICAgICAgIH1cbiAgICB9KTtcblxuICAgIGlmICh0eXBlb2Ygc2Vzc2lvbi5ncm91cHMgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAvLyBXZSByZWdlbmVyYXRlIHRoZSBCVU5ETEUgZ3JvdXAgd2l0aCB0aGUgbmV3IG1pZHMuXG4gICAgICBzZXNzaW9uLmdyb3Vwcy5zb21lKGZ1bmN0aW9uKGdyb3VwKSB7XG5cdCAgaWYgKGdyb3VwLnR5cGUgPT09ICdCVU5ETEUnKSB7XG5cdCAgICAgIGdyb3VwLm1pZHMgPSB0eXBlcy5qb2luKCcgJyk7XG5cdCAgICAgIHJldHVybiB0cnVlO1xuXHQgIH1cbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8vIG1zaWQgc2VtYW50aWNcbiAgICBzZXNzaW9uLm1zaWRTZW1hbnRpYyA9IHtcbiAgICAgICAgc2VtYW50aWM6ICdXTVMnLFxuICAgICAgICB0b2tlbjogJyonXG4gICAgfTtcblxuICAgIHZhciByZXNTdHIgPSB0cmFuc2Zvcm0ud3JpdGUoc2Vzc2lvbik7XG5cbiAgICByZXR1cm4gbmV3IFJUQ1Nlc3Npb25EZXNjcmlwdGlvbih7XG4gICAgICAgIHR5cGU6IGRlc2MudHlwZSxcbiAgICAgICAgc2RwOiByZXNTdHJcbiAgICB9KTtcblxuICAgIC8vI2VuZHJlZ2lvblxufTtcblxuLyogZm9sbG93IHJ1bGVzIGRlZmluZWQgaW4gUkZDNDE0NSAqL1xuZnVuY3Rpb24gYWRkU2V0dXBBdHRyKHVMaW5lKSB7XG4gICAgaWYgKHR5cGVvZiB1TGluZS5zZXR1cCA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICh1TGluZS5zZXR1cCA9PT0gXCJhY3RpdmVcIikge1xuICAgICAgICAgICAgdUxpbmUuc2V0dXAgPSBcInBhc3NpdmVcIjtcbiAgICB9IGVsc2UgaWYgKHVMaW5lLnNldHVwID09PSBcInBhc3NpdmVcIikge1xuICAgICAgICB1TGluZS5zZXR1cCA9IFwiYWN0aXZlXCI7XG4gICAgfVxufVxuXG4vKipcbiAqIFRoaXMgbWV0aG9kIHRyYW5zZm9ybXMgYSBQbGFuIEIgU0RQIHRvIGFuIGVxdWl2YWxlbnQgVW5pZmllZCBQbGFuIFNEUC4gQVxuICogUGVlckNvbm5lY3Rpb24gd3JhcHBlciB0cmFuc2Zvcm1zIHRoZSBTRFAgdG8gVW5pZmllZCBQbGFuIGJlZm9yZSBwYXNzaW5nIGl0XG4gKiB0byBGRi5cbiAqXG4gKiBAcGFyYW0gZGVzY1xuICogQHJldHVybnMgeyp9XG4gKi9cbkludGVyb3AucHJvdG90eXBlLnRvVW5pZmllZFBsYW4gPSBmdW5jdGlvbihkZXNjKSB7XG4gICAgdmFyIHNlbGYgPSB0aGlzO1xuICAgIC8vI3JlZ2lvbiBQcmVsaW1pbmFyeSBpbnB1dCB2YWxpZGF0aW9uLlxuXG4gICAgaWYgKHR5cGVvZiBkZXNjICE9PSAnb2JqZWN0JyB8fCBkZXNjID09PSBudWxsIHx8XG4gICAgICAgIHR5cGVvZiBkZXNjLnNkcCAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgY29uc29sZS53YXJuKCdBbiBlbXB0eSBkZXNjcmlwdGlvbiB3YXMgcGFzc2VkIGFzIGFuIGFyZ3VtZW50LicpO1xuICAgICAgICByZXR1cm4gZGVzYztcbiAgICB9XG5cbiAgICB2YXIgc2Vzc2lvbiA9IHRyYW5zZm9ybS5wYXJzZShkZXNjLnNkcCk7XG5cbiAgICAvLyBJZiB0aGUgU0RQIGNvbnRhaW5zIG5vIG1lZGlhLCB0aGVyZSdzIG5vdGhpbmcgdG8gdHJhbnNmb3JtLlxuICAgIGlmICh0eXBlb2Ygc2Vzc2lvbi5tZWRpYSA9PT0gJ3VuZGVmaW5lZCcgfHxcbiAgICAgICAgIUFycmF5LmlzQXJyYXkoc2Vzc2lvbi5tZWRpYSkgfHwgc2Vzc2lvbi5tZWRpYS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgY29uc29sZS53YXJuKCdUaGUgZGVzY3JpcHRpb24gaGFzIG5vIG1lZGlhLicpO1xuICAgICAgICByZXR1cm4gZGVzYztcbiAgICB9XG5cbiAgICAvLyBUcnkgc29tZSBoZXVyaXN0aWNzIHRvIFwibWFrZSBzdXJlXCIgdGhpcyBpcyBhIFBsYW4gQiBTRFAuIFBsYW4gQiBTRFAgaGFzXG4gICAgLy8gYSB2aWRlbywgYW4gYXVkaW8gYW5kIGEgZGF0YSBcImNoYW5uZWxcIiBhdCBtb3N0LlxuICAgIGlmIChzZXNzaW9uLm1lZGlhLmxlbmd0aCA+IDMgfHwgIXNlc3Npb24ubWVkaWEuZXZlcnkoZnVuY3Rpb24obSkge1xuICAgICAgICAgICAgcmV0dXJuIFsndmlkZW8nLCAnYXVkaW8nLCAnZGF0YSddLmluZGV4T2YobS5taWQpICE9PSAtMTtcbiAgICAgICAgfSkpIHtcbiAgICAgICAgY29uc29sZS53YXJuKCdUaGlzIGRlc2NyaXB0aW9uIGRvZXMgbm90IGxvb2sgbGlrZSBQbGFuIEIuJyk7XG4gICAgICAgIHJldHVybiBkZXNjO1xuICAgIH1cblxuICAgIC8vIE1ha2Ugc3VyZSB0aGlzIFBsYW4gQiBTRFAgY2FuIGJlIGNvbnZlcnRlZCB0byBhIFVuaWZpZWQgUGxhbiBTRFAuXG4gICAgdmFyIG1pZHMgPSBbXTtcbiAgICBzZXNzaW9uLm1lZGlhLmZvckVhY2goZnVuY3Rpb24obSkge1xuICAgICAgICBtaWRzLnB1c2gobS5taWQpO1xuICAgIH0pO1xuXG4gICAgdmFyIGhhc0J1bmRsZSA9IGZhbHNlO1xuICAgIGlmICh0eXBlb2Ygc2Vzc2lvbi5ncm91cHMgIT09ICd1bmRlZmluZWQnICYmXG4gICAgICAgIEFycmF5LmlzQXJyYXkoc2Vzc2lvbi5ncm91cHMpKSB7XG4gICAgICAgIGhhc0J1bmRsZSA9IHNlc3Npb24uZ3JvdXBzLmV2ZXJ5KGZ1bmN0aW9uKGcpIHtcbiAgICAgICAgICAgIHJldHVybiBnLnR5cGUgIT09ICdCVU5ETEUnIHx8XG4gICAgICAgICAgICAgICAgYXJyYXlFcXVhbHMuYXBwbHkoZy5taWRzLnNvcnQoKSwgW21pZHMuc29ydCgpXSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIGlmICghaGFzQnVuZGxlKSB7XG4gICAgICAgIHZhciBtdXN0QmVCdW5kbGUgPSBmYWxzZTtcblxuICAgICAgICBzZXNzaW9uLm1lZGlhLmZvckVhY2goZnVuY3Rpb24obSkge1xuICAgICAgICAgICAgaWYgKG0uZGlyZWN0aW9uICE9PSAnaW5hY3RpdmUnKSB7XG4gICAgICAgICAgICAgICAgbXVzdEJlQnVuZGxlID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgaWYgKG11c3RCZUJ1bmRsZSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQ2Fubm90IGNvbnZlcnQgdG8gVW5pZmllZCBQbGFuIGJlY2F1c2UgbS1saW5lcyB0aGF0XCIgK1xuICAgICAgICAgICAgICBcIiBhcmUgbm90IGJ1bmRsZWQgd2VyZSBmb3VuZC5cIik7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyNlbmRyZWdpb25cblxuXG4gICAgLy8jcmVnaW9uIENvbnZlcnQgZnJvbSBQbGFuIEIgdG8gVW5pZmllZCBQbGFuLlxuXG4gICAgLy8gVW5mb3J0dW5hdGVseSwgYSBQbGFuIEIgb2ZmZXIvYW5zd2VyIGRvZXNuJ3QgaGF2ZSBlbm91Z2ggaW5mb3JtYXRpb24gdG9cbiAgICAvLyByZWJ1aWxkIGFuIGVxdWl2YWxlbnQgVW5pZmllZCBQbGFuIG9mZmVyL2Fuc3dlci5cbiAgICAvL1xuICAgIC8vIEZvciBleGFtcGxlLCBpZiB0aGlzIGlzIGEgbG9jYWwgYW5zd2VyIChpbiBVbmlmaWVkIFBsYW4gc3R5bGUpIHRoYXQgd2VcbiAgICAvLyBjb252ZXJ0IHRvIFBsYW4gQiBwcmlvciB0byBoYW5kaW5nIGl0IG92ZXIgdG8gdGhlIGFwcGxpY2F0aW9uICh0aGVcbiAgICAvLyBQZWVyQ29ubmVjdGlvbiB3cmFwcGVyIGNhbGxlZCB1cywgZm9yIGluc3RhbmNlLCBhZnRlciBhIHN1Y2Nlc3NmdWxcbiAgICAvLyBjcmVhdGVBbnN3ZXIpLCB3ZSB3YW50IHRvIHJlbWVtYmVyIHRoZSBtLWxpbmUgYXQgd2hpY2ggd2UndmUgc2VlbiB0aGVcbiAgICAvLyAobG9jYWwpIFNTUkMuIFRoYXQncyBiZWNhdXNlIHdoZW4gdGhlIGFwcGxpY2F0aW9uIHdhbnRzIHRvIGRvIGNhbGwgdGhlXG4gICAgLy8gU0xEIG1ldGhvZCwgZm9yY2luZyB1cyB0byBkbyB0aGUgaW52ZXJzZSB0cmFuc2Zvcm1hdGlvbiAoZnJvbSBQbGFuIEIgdG9cbiAgICAvLyBVbmlmaWVkIFBsYW4pLCB3ZSBuZWVkIHRvIGtub3cgdG8gd2hpY2ggbS1saW5lIHRvIGFzc2lnbiB0aGUgKGxvY2FsKVxuICAgIC8vIFNTUkMuIFdlIGFsc28gbmVlZCB0byBrbm93IGFsbCB0aGUgb3RoZXIgbS1saW5lcyB0aGF0IHRoZSBvcmlnaW5hbFxuICAgIC8vIGFuc3dlciBoYWQgYW5kIGluY2x1ZGUgdGhlbSBpbiB0aGUgdHJhbnNmb3JtZWQgYW5zd2VyIGFzIHdlbGwuXG4gICAgLy9cbiAgICAvLyBBbm90aGVyIGV4YW1wbGUgaXMgaWYgdGhpcyBpcyBhIHJlbW90ZSBvZmZlciB0aGF0IHdlIGNvbnZlcnQgdG8gUGxhbiBCXG4gICAgLy8gcHJpb3IgdG8gZ2l2aW5nIGl0IHRvIHRoZSBhcHBsaWNhdGlvbiwgd2Ugd2FudCB0byByZW1lbWJlciB0aGUgbWlkIGF0XG4gICAgLy8gd2hpY2ggd2UndmUgc2VlbiB0aGUgKHJlbW90ZSkgU1NSQy5cbiAgICAvL1xuICAgIC8vIEluIHRoZSBpdGVyYXRpb24gdGhhdCBmb2xsb3dzLCB3ZSB1c2UgdGhlIGNhY2hlZCBVbmlmaWVkIFBsYW4gKGlmIGl0XG4gICAgLy8gZXhpc3RzKSB0byBhc3NpZ24gbWlkcyB0byBzc3Jjcy5cblxuICAgIHZhciB0eXBlO1xuICAgIGlmIChkZXNjLnR5cGUgPT09ICdhbnN3ZXInKSB7XG4gICAgICAgIHR5cGUgPSAnb2ZmZXInO1xuICAgIH0gZWxzZSBpZiAoZGVzYy50eXBlID09PSAnb2ZmZXInKSB7XG4gICAgICAgIHR5cGUgPSAnYW5zd2VyJztcbiAgICB9IGVsc2Uge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJUeXBlICdcIiArIGRlc2MudHlwZSArIFwiJyBub3Qgc3VwcG9ydGVkLlwiKTtcbiAgICB9XG5cbiAgICB2YXIgY2FjaGVkO1xuICAgIGlmICh0eXBlb2YgdGhpcy5jYWNoZVt0eXBlXSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgY2FjaGVkID0gdHJhbnNmb3JtLnBhcnNlKHRoaXMuY2FjaGVbdHlwZV0pO1xuICAgIH1cblxuICAgIHZhciByZWN2b25seVNzcmNzID0ge1xuICAgICAgICBhdWRpbzoge30sXG4gICAgICAgIHZpZGVvOiB7fVxuICAgIH07XG5cbiAgICAvLyBBIGhlbHBlciBtYXAgdGhhdCBzZW5kcyBtaWRzIHRvIG0tbGluZSBvYmplY3RzLiBXZSB1c2UgaXQgbGF0ZXIgdG9cbiAgICAvLyByZWJ1aWxkIHRoZSBVbmlmaWVkIFBsYW4gc3R5bGUgc2Vzc2lvbi5tZWRpYSBhcnJheS5cbiAgICB2YXIgbWlkMnVsID0ge307XG4gICAgdmFyIGJJZHggPSAwO1xuICAgIHZhciB1SWR4ID0gMDtcblxuICAgIHZhciBzb3VyY2VzMnVsID0ge307XG5cbiAgICB2YXIgY2FuZGlkYXRlcztcbiAgICB2YXIgaWNlVWZyYWc7XG4gICAgdmFyIGljZVB3ZDtcbiAgICB2YXIgZmluZ2VycHJpbnQ7XG4gICAgdmFyIHBheWxvYWRzID0ge307XG4gICAgdmFyIHJ0Y3BGYiA9IHt9O1xuICAgIHZhciBydHAgPSB7fTtcblxuICAgIHNlc3Npb24ubWVkaWEuZm9yRWFjaChmdW5jdGlvbihiTGluZSkge1xuICAgICAgICBpZiAoKHR5cGVvZiBiTGluZS5ydGNwTXV4ICE9PSAnc3RyaW5nJyB8fFxuICAgICAgICAgICAgYkxpbmUucnRjcE11eCAhPT0gJ3J0Y3AtbXV4JykgJiZcbiAgICAgICAgICAgIGJMaW5lLmRpcmVjdGlvbiAhPT0gJ2luYWN0aXZlJykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQ2Fubm90IGNvbnZlcnQgdG8gVW5pZmllZCBQbGFuIGJlY2F1c2UgbS1saW5lcyBcIiArXG4gICAgICAgICAgICAgICAgXCJ3aXRob3V0IHRoZSBydGNwLW11eCBhdHRyaWJ1dGUgd2VyZSBmb3VuZC5cIik7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoYkxpbmUudHlwZSA9PT0gJ2FwcGxpY2F0aW9uJykge1xuICAgICAgICAgICAgbWlkMnVsW2JMaW5lLm1pZF0gPSBiTGluZTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFdpdGggcnRjcC1tdXggYW5kIGJ1bmRsZSBhbGwgdGhlIGNoYW5uZWxzIHNob3VsZCBoYXZlIHRoZSBzYW1lIElDRVxuICAgICAgICAvLyBzdHVmZi5cbiAgICAgICAgdmFyIHNvdXJjZXMgPSBiTGluZS5zb3VyY2VzO1xuICAgICAgICB2YXIgc3NyY0dyb3VwcyA9IGJMaW5lLnNzcmNHcm91cHM7XG4gICAgICAgIHZhciBwb3J0ID0gYkxpbmUucG9ydDtcblxuICAgICAgICAvKiBDaHJvbWUgYWRkcyBkaWZmZXJlbnQgY2FuZGlkYXRlcyBldmVuIHVzaW5nIGJ1bmRsZSwgc28gd2UgY29uY2F0IHRoZSBjYW5kaWRhdGVzIGxpc3QgKi9cbiAgICAgICAgaWYgKHR5cGVvZiBiTGluZS5jYW5kaWRhdGVzICE9ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICBpZiAodHlwZW9mIGNhbmRpZGF0ZXMgIT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgICAgICBjYW5kaWRhdGVzID0gY2FuZGlkYXRlcy5jb25jYXQoYkxpbmUuY2FuZGlkYXRlcyk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNhbmRpZGF0ZXMgPSBiTGluZS5jYW5kaWRhdGVzO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCh0eXBlb2YgaWNlVWZyYWcgIT0gJ3VuZGVmaW5lZCcpICYmICh0eXBlb2YgYkxpbmUuaWNlVWZyYWcgIT0gJ3VuZGVmaW5lZCcpICYmIChpY2VVZnJhZyAhPSBiTGluZS5pY2VVZnJhZykpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIk9ubHkgQlVORExFIHN1cHBvcnRlZCwgaWNlVWZyYWcgbXVzdCBiZSB0aGUgc2FtZSBmb3IgYWxsIG0tbGluZXMuXFxuXCIgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiXFx0TGFzdCBpY2VVZnJhZzogXCIgKyBpY2VVZnJhZyArIFwiXFxuXCIgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiXFx0TmV3IGljZVVmcmFnOiBcIiArIGJMaW5lLmljZVVmcmFnXG4gICAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHR5cGVvZiBiTGluZS5pY2VVZnJhZyAhPSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgICAgIGljZVVmcmFnID0gYkxpbmUuaWNlVWZyYWc7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoKHR5cGVvZiBpY2VQd2QgIT0gJ3VuZGVmaW5lZCcpICYmICh0eXBlb2YgYkxpbmUuaWNlUHdkICE9ICd1bmRlZmluZWQnKSAmJiAoaWNlUHdkICE9IGJMaW5lLmljZVB3ZCkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIk9ubHkgQlVORExFIHN1cHBvcnRlZCwgaWNlUHdkIG11c3QgYmUgdGhlIHNhbWUgZm9yIGFsbCBtLWxpbmVzLlxcblwiICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBcIlxcdExhc3QgaWNlUHdkOiBcIiArIGljZVB3ZCArIFwiXFxuXCIgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiXFx0TmV3IGljZVB3ZDogXCIgKyBiTGluZS5pY2VQd2RcbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodHlwZW9mIGJMaW5lLmljZVB3ZCAhPSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgICAgIGljZVB3ZCA9IGJMaW5lLmljZVB3ZDtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICgodHlwZW9mIGZpbmdlcnByaW50ICE9ICd1bmRlZmluZWQnKSAmJiAodHlwZW9mIGJMaW5lLmZpbmdlcnByaW50ICE9ICd1bmRlZmluZWQnKSAmJlxuICAgICAgICAgICAgKGZpbmdlcnByaW50LnR5cGUgIT0gYkxpbmUuZmluZ2VycHJpbnQudHlwZSB8fCBmaW5nZXJwcmludC5oYXNoICE9IGJMaW5lLmZpbmdlcnByaW50Lmhhc2gpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJPbmx5IEJVTkRMRSBzdXBwb3J0ZWQsIGZpbmdlcnByaW50IG11c3QgYmUgdGhlIHNhbWUgZm9yIGFsbCBtLWxpbmVzLlxcblwiICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBcIlxcdExhc3QgZmluZ2VycHJpbnQ6IFwiICsgSlNPTi5zdHJpbmdpZnkoZmluZ2VycHJpbnQpICsgXCJcXG5cIiArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJcXHROZXcgZmluZ2VycHJpbnQ6IFwiICsgSlNPTi5zdHJpbmdpZnkoYkxpbmUuZmluZ2VycHJpbnQpXG4gICAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHR5cGVvZiBiTGluZS5maW5nZXJwcmludCAhPSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgICAgIGZpbmdlcnByaW50ID0gYkxpbmUuZmluZ2VycHJpbnQ7XG4gICAgICAgIH1cblxuICAgICAgICBwYXlsb2Fkc1tiTGluZS50eXBlXSA9IGJMaW5lLnBheWxvYWRzO1xuICAgICAgICBydGNwRmJbYkxpbmUudHlwZV0gPSBiTGluZS5ydGNwRmI7XG4gICAgICAgIHJ0cFtiTGluZS50eXBlXSA9IGJMaW5lLnJ0cDtcblxuICAgICAgICAvLyBpbnZlcnRlZCBzc3JjIGdyb3VwIG1hcFxuICAgICAgICB2YXIgc3NyYzJncm91cCA9IHt9O1xuICAgICAgICBpZiAodHlwZW9mIHNzcmNHcm91cHMgIT09ICd1bmRlZmluZWQnICYmIEFycmF5LmlzQXJyYXkoc3NyY0dyb3VwcykpIHtcbiAgICAgICAgICAgIHNzcmNHcm91cHMuZm9yRWFjaChmdW5jdGlvbiAoc3NyY0dyb3VwKSB7XG4gICAgICAgICAgICAgICAgLy8gWFhYIFRoaXMgbWlnaHQgYnJha2UgaWYgYW4gU1NSQyBpcyBpbiBtb3JlIHRoYW4gb25lIGdyb3VwXG4gICAgICAgICAgICAgICAgLy8gZm9yIHNvbWUgcmVhc29uLlxuICAgICAgICAgICAgICAgIGlmICh0eXBlb2Ygc3NyY0dyb3VwLnNzcmNzICE9PSAndW5kZWZpbmVkJyAmJlxuICAgICAgICAgICAgICAgICAgICBBcnJheS5pc0FycmF5KHNzcmNHcm91cC5zc3JjcykpIHtcbiAgICAgICAgICAgICAgICAgICAgc3NyY0dyb3VwLnNzcmNzLmZvckVhY2goZnVuY3Rpb24gKHNzcmMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2Ygc3NyYzJncm91cFtzc3JjXSA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzc3JjMmdyb3VwW3NzcmNdID0gW107XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIHNzcmMyZ3JvdXBbc3NyY10ucHVzaChzc3JjR3JvdXApO1xuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIHNzcmMgdG8gbS1saW5lIGluZGV4LlxuICAgICAgICB2YXIgc3NyYzJtbCA9IHt9O1xuXG4gICAgICAgIGlmICh0eXBlb2Ygc291cmNlcyA9PT0gJ29iamVjdCcpIHtcblxuICAgICAgICAgICAgLy8gV2UnbGwgdXNlIHRoZSBcImJMaW5lXCIgb2JqZWN0IGFzIGEgcHJvdG90eXBlIGZvciBlYWNoIG5ldyBcIm1MaW5lXCJcbiAgICAgICAgICAgIC8vIHRoYXQgd2UgY3JlYXRlLCBidXQgZmlyc3Qgd2UgbmVlZCB0byBjbGVhbiBpdCB1cCBhIGJpdC5cbiAgICAgICAgICAgIGRlbGV0ZSBiTGluZS5zb3VyY2VzO1xuICAgICAgICAgICAgZGVsZXRlIGJMaW5lLnNzcmNHcm91cHM7XG4gICAgICAgICAgICBkZWxldGUgYkxpbmUuY2FuZGlkYXRlcztcbiAgICAgICAgICAgIGRlbGV0ZSBiTGluZS5pY2VVZnJhZztcbiAgICAgICAgICAgIGRlbGV0ZSBiTGluZS5pY2VQd2Q7XG4gICAgICAgICAgICBkZWxldGUgYkxpbmUuZmluZ2VycHJpbnQ7XG4gICAgICAgICAgICBkZWxldGUgYkxpbmUucG9ydDtcbiAgICAgICAgICAgIGRlbGV0ZSBiTGluZS5taWQ7XG5cbiAgICAgICAgICAgIC8vIEV4cGxvZGUgdGhlIFBsYW4gQiBjaGFubmVsIHNvdXJjZXMgd2l0aCBvbmUgbS1saW5lIHBlciBzb3VyY2UuXG4gICAgICAgICAgICBPYmplY3Qua2V5cyhzb3VyY2VzKS5mb3JFYWNoKGZ1bmN0aW9uKHNzcmMpIHtcblxuICAgICAgICAgICAgICAgIC8vIFRoZSAodW5pZmllZCkgbS1saW5lIGZvciB0aGlzIFNTUkMuIFdlIGVpdGhlciBjcmVhdGUgaXQgZnJvbVxuICAgICAgICAgICAgICAgIC8vIHNjcmF0Y2ggb3IsIGlmIGl0J3MgYSBncm91cGVkIFNTUkMsIHdlIHJlLXVzZSBhIHJlbGF0ZWRcbiAgICAgICAgICAgICAgICAvLyBtbGluZS4gSW4gb3RoZXIgd29yZHMsIGlmIHRoZSBzb3VyY2UgaXMgZ3JvdXBlZCB3aXRoIGFub3RoZXJcbiAgICAgICAgICAgICAgICAvLyBzb3VyY2UsIHB1dCB0aGUgdHdvIHRvZ2V0aGVyIGluIHRoZSBzYW1lIG0tbGluZS5cbiAgICAgICAgICAgICAgICB2YXIgdUxpbmU7XG5cbiAgICAgICAgICAgICAgICAvLyBXZSBhc3N1bWUgaGVyZSB0aGF0IHdlIGFyZSB0aGUgYW5zd2VyZXIgaW4gdGhlIE8vQSwgc28gYW55XG4gICAgICAgICAgICAgICAgLy8gb2ZmZXJzIHdoaWNoIHdlIHRyYW5zbGF0ZSBjb21lIGZyb20gdGhlIHJlbW90ZSBzaWRlLCB3aGlsZVxuICAgICAgICAgICAgICAgIC8vIGFuc3dlcnMgYXJlIGxvY2FsLiBTbyB0aGUgY2hlY2sgYmVsb3cgaXMgdG8gbWFrZSB0aGF0IHdlXG4gICAgICAgICAgICAgICAgLy8gaGFuZGxlIHJlY2VpdmUtb25seSBTU1JDcyBpbiBhIHNwZWNpYWwgd2F5IG9ubHkgaWYgdGhleSBjb21lXG4gICAgICAgICAgICAgICAgLy8gZnJvbSB0aGUgcmVtb3RlIHNpZGUuXG4gICAgICAgICAgICAgICAgaWYgKGRlc2MudHlwZT09PSdvZmZlcicpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gV2Ugd2FudCB0byBkZXRlY3QgU1NSQ3Mgd2hpY2ggYXJlIHVzZWQgYnkgYSByZW1vdGUgcGVlclxuICAgICAgICAgICAgICAgICAgICAvLyBpbiBhbiBtLWxpbmUgd2l0aCBkaXJlY3Rpb249cmVjdm9ubHkgKGkuZS4gdGhleSBhcmVcbiAgICAgICAgICAgICAgICAgICAgLy8gYmVpbmcgdXNlZCBmb3IgUlRDUCBvbmx5KS5cbiAgICAgICAgICAgICAgICAgICAgLy8gVGhpcyBpbmZvcm1hdGlvbiB3b3VsZCBoYXZlIGdvdHRlbiBsb3N0IGlmIHRoZSByZW1vdGVcbiAgICAgICAgICAgICAgICAgICAgLy8gcGVlciB1c2VkIFVuaWZpZWQgUGxhbiBhbmQgdGhlaXIgbG9jYWwgZGVzY3JpcHRpb24gd2FzXG4gICAgICAgICAgICAgICAgICAgIC8vIHRyYW5zbGF0ZWQgdG8gUGxhbiBCLiBTbyB3ZSB1c2UgdGhlIGxhY2sgb2YgYW4gTVNJRFxuICAgICAgICAgICAgICAgICAgICAvLyBhdHRyaWJ1dGUgdG8gZGVkdWNlIGEgXCJyZWNlaXZlIG9ubHlcIiBTU1JDLlxuICAgICAgICAgICAgICAgICAgICBpZiAoIXNvdXJjZXNbc3NyY10ubXNpZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVjdm9ubHlTc3Jjc1tiTGluZS50eXBlXVtzc3JjXSA9IHNvdXJjZXNbc3NyY107XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBSZWNlaXZlLW9ubHkgU1NSQ3MgbXVzdCBub3QgY3JlYXRlIG5ldyBtLWxpbmVzLiBXZVxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gd2lsbCBhc3NpZ24gdGhlbSB0byBhbiBleGlzdGluZyBtLWxpbmUgbGF0ZXIuXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHNzcmMyZ3JvdXBbc3NyY10gIT09ICd1bmRlZmluZWQnICYmXG4gICAgICAgICAgICAgICAgICAgIEFycmF5LmlzQXJyYXkoc3NyYzJncm91cFtzc3JjXSkpIHtcbiAgICAgICAgICAgICAgICAgICAgc3NyYzJncm91cFtzc3JjXS5zb21lKGZ1bmN0aW9uIChzc3JjR3JvdXApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIHNzcmNHcm91cC5zc3JjcyAqaXMqIGFuIEFycmF5LCBubyBuZWVkIHRvIGNoZWNrXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBhZ2FpbiBoZXJlLlxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHNzcmNHcm91cC5zc3Jjcy5zb21lKGZ1bmN0aW9uIChyZWxhdGVkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBzc3JjMm1sW3JlbGF0ZWRdID09PSAnb2JqZWN0Jykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1TGluZSA9IHNzcmMybWxbcmVsYXRlZF07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHVMaW5lID09PSAnb2JqZWN0Jykge1xuICAgICAgICAgICAgICAgICAgICAvLyB0aGUgbS1saW5lIGFscmVhZHkgZXhpc3RzLiBKdXN0IGFkZCB0aGUgc291cmNlLlxuICAgICAgICAgICAgICAgICAgICB1TGluZS5zb3VyY2VzW3NzcmNdID0gc291cmNlc1tzc3JjXTtcbiAgICAgICAgICAgICAgICAgICAgZGVsZXRlIHNvdXJjZXNbc3NyY10ubXNpZDtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAvLyBVc2UgdGhlIFwiYkxpbmVcIiBhcyBhIHByb3RvdHlwZSBmb3IgdGhlIFwidUxpbmVcIi5cbiAgICAgICAgICAgICAgICAgICAgdUxpbmUgPSBPYmplY3QuY3JlYXRlKGJMaW5lKTtcbiAgICAgICAgICAgICAgICAgICAgc3NyYzJtbFtzc3JjXSA9IHVMaW5lO1xuXG4gICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2Ygc291cmNlc1tzc3JjXS5tc2lkICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gQXNzaWduIHRoZSBtc2lkIG9mIHRoZSBzb3VyY2UgdG8gdGhlIG0tbGluZS4gTm90ZVxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gdGhhdCBpdCBpcyBub3QgZ3VhcmFudGVlZCB0aGF0IHRoZSBzb3VyY2Ugd2lsbCBoYXZlXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBtc2lkLiBJbiBwYXJ0aWN1bGFyIFwicmVjdm9ubHlcIiBzb3VyY2VzIGRvbid0IGhhdmUgYW5cbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIG1zaWQuIE5vdGUgdGhhdCBcInJlY3Zvbmx5XCIgaXMgYSB0ZXJtIG9ubHkgZGVmaW5lZFxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gZm9yIG0tbGluZXMuXG4gICAgICAgICAgICAgICAgICAgICAgICB1TGluZS5tc2lkID0gc291cmNlc1tzc3JjXS5tc2lkO1xuICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlIHNvdXJjZXNbc3NyY10ubXNpZDtcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIC8vIFdlIGFzc2lnbiBvbmUgU1NSQyBwZXIgbWVkaWEgbGluZS5cbiAgICAgICAgICAgICAgICAgICAgdUxpbmUuc291cmNlcyA9IHt9O1xuICAgICAgICAgICAgICAgICAgICB1TGluZS5zb3VyY2VzW3NzcmNdID0gc291cmNlc1tzc3JjXTtcbiAgICAgICAgICAgICAgICAgICAgdUxpbmUuc3NyY0dyb3VwcyA9IHNzcmMyZ3JvdXBbc3NyY107XG5cbiAgICAgICAgICAgICAgICAgICAgLy8gVXNlIHRoZSBjYWNoZWQgVW5pZmllZCBQbGFuIFNEUCAoaWYgaXQgZXhpc3RzKSB0byBhc3NpZ25cbiAgICAgICAgICAgICAgICAgICAgLy8gU1NSQ3MgdG8gbWlkcy5cbiAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBjYWNoZWQgIT09ICd1bmRlZmluZWQnICYmXG4gICAgICAgICAgICAgICAgICAgICAgICB0eXBlb2YgY2FjaGVkLm1lZGlhICE9PSAndW5kZWZpbmVkJyAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgQXJyYXkuaXNBcnJheShjYWNoZWQubWVkaWEpKSB7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGNhY2hlZC5tZWRpYS5mb3JFYWNoKGZ1bmN0aW9uIChtKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBtLnNvdXJjZXMgPT09ICdvYmplY3QnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9iamVjdC5rZXlzKG0uc291cmNlcykuZm9yRWFjaChmdW5jdGlvbiAocykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHMgPT09IHNzcmMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1TGluZS5taWQgPSBtLm1pZDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHVMaW5lLm1pZCA9PT0gJ3VuZGVmaW5lZCcpIHtcblxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gSWYgdGhpcyBpcyBhbiBTU1JDIHRoYXQgd2Ugc2VlIGZvciB0aGUgZmlyc3QgdGltZVxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gYXNzaWduIGl0IGEgbmV3IG1pZC4gVGhpcyBpcyB0eXBpY2FsbHkgdGhlIGNhc2Ugd2hlblxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gdGhpcyBtZXRob2QgaXMgY2FsbGVkIHRvIHRyYW5zZm9ybSBhIHJlbW90ZVxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gZGVzY3JpcHRpb24gZm9yIHRoZSBmaXJzdCB0aW1lIG9yIHdoZW4gdGhlcmUgaXMgYVxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gbmV3IFNTUkMgaW4gdGhlIHJlbW90ZSBkZXNjcmlwdGlvbiBiZWNhdXNlIGEgbmV3XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBwZWVyIGhhcyBqb2luZWQgdGhlIGNvbmZlcmVuY2UuIExvY2FsIFNTUkNzIHNob3VsZFxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gaGF2ZSBhbHJlYWR5IGJlZW4gYWRkZWQgdG8gdGhlIG1hcCBpbiB0aGUgdG9QbGFuQlxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gbWV0aG9kLlxuICAgICAgICAgICAgICAgICAgICAgICAgLy9cbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIEJlY2F1c2UgRkYgZ2VuZXJhdGVzIGFuc3dlcnMgaW4gVW5pZmllZCBQbGFuIHN0eWxlLFxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gd2UgTVVTVCBhbHJlYWR5IGhhdmUgYSBjYWNoZWQgYW5zd2VyIHdpdGggYWxsIHRoZVxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gbG9jYWwgU1NSQ3MgbWFwcGVkIHRvIHNvbWUgbS1saW5lL21pZC5cblxuICAgICAgICAgICAgICAgICAgICAgICAgdUxpbmUubWlkID0gW2JMaW5lLnR5cGUsICctJywgc3NyY10uam9pbignJyk7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAvLyBJbmNsdWRlIHRoZSBjYW5kaWRhdGVzIGluIHRoZSAxc3QgbWVkaWEgbGluZS5cbiAgICAgICAgICAgICAgICAgICAgdUxpbmUuY2FuZGlkYXRlcyA9IGNhbmRpZGF0ZXM7XG4gICAgICAgICAgICAgICAgICAgIHVMaW5lLmljZVVmcmFnID0gaWNlVWZyYWc7XG4gICAgICAgICAgICAgICAgICAgIHVMaW5lLmljZVB3ZCA9IGljZVB3ZDtcbiAgICAgICAgICAgICAgICAgICAgdUxpbmUuZmluZ2VycHJpbnQgPSBmaW5nZXJwcmludDtcbiAgICAgICAgICAgICAgICAgICAgdUxpbmUucG9ydCA9IHBvcnQ7XG5cbiAgICAgICAgICAgICAgICAgICAgbWlkMnVsW3VMaW5lLm1pZF0gPSB1TGluZTtcbiAgICAgICAgICAgICAgICAgICAgc291cmNlczJ1bFt1SWR4XSA9IHVMaW5lLnNvdXJjZXM7XG5cbiAgICAgICAgICAgICAgICAgICAgc2VsZi5jYWNoZS5tbFUyQk1hcFt1SWR4XSA9IGJJZHg7XG4gICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2Ygc2VsZi5jYWNoZS5tbEIyVU1hcFtiSWR4XSA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICBzZWxmLmNhY2hlLm1sQjJVTWFwW2JJZHhdID0gdUlkeDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB1SWR4Kys7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdmFyIHVMaW5lID0gYkxpbmU7XG5cbiAgICAgICAgICB1TGluZS5jYW5kaWRhdGVzID0gY2FuZGlkYXRlcztcbiAgICAgICAgICB1TGluZS5pY2VVZnJhZyA9IGljZVVmcmFnO1xuICAgICAgICAgIHVMaW5lLmljZVB3ZCA9IGljZVB3ZDtcbiAgICAgICAgICB1TGluZS5maW5nZXJwcmludCA9IGZpbmdlcnByaW50O1xuICAgICAgICAgIHVMaW5lLnBvcnQgPSBwb3J0O1xuXG4gICAgICAgICAgbWlkMnVsW3VMaW5lLm1pZF0gPSB1TGluZTtcblxuICAgICAgICAgIHNlbGYuY2FjaGUubWxVMkJNYXBbdUlkeF0gPSBiSWR4O1xuICAgICAgICAgIGlmICh0eXBlb2Ygc2VsZi5jYWNoZS5tbEIyVU1hcFtiSWR4XSA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIHNlbGYuY2FjaGUubWxCMlVNYXBbYklkeF0gPSB1SWR4O1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGJJZHgrKztcbiAgICB9KTtcblxuICAgIC8vIFJlYnVpbGQgdGhlIG1lZGlhIGFycmF5IGluIHRoZSByaWdodCBvcmRlciBhbmQgYWRkIHRoZSBtaXNzaW5nIG1MaW5lc1xuICAgIC8vIChtaXNzaW5nIGZyb20gdGhlIFBsYW4gQiBTRFApLlxuICAgIHNlc3Npb24ubWVkaWEgPSBbXTtcbiAgICBtaWRzID0gW107IC8vIHJldXNlXG5cbiAgICBpZiAoZGVzYy50eXBlID09PSAnYW5zd2VyJykge1xuXG4gICAgICAgIC8vIFRoZSBtZWRpYSBsaW5lcyBpbiB0aGUgYW5zd2VyIG11c3QgbWF0Y2ggdGhlIG1lZGlhIGxpbmVzIGluIHRoZVxuICAgICAgICAvLyBvZmZlci4gVGhlIG9yZGVyIGlzIGltcG9ydGFudCB0b28uIEhlcmUgd2UgYXNzdW1lIHRoYXQgRmlyZWZveCBpc1xuICAgICAgICAvLyB0aGUgYW5zd2VyZXIsIHNvIHdlIG1lcmVseSBoYXZlIHRvIHVzZSB0aGUgcmVjb25zdHJ1Y3RlZCAodW5pZmllZClcbiAgICAgICAgLy8gYW5zd2VyIHRvIHVwZGF0ZSB0aGUgY2FjaGVkICh1bmlmaWVkKSBhbnN3ZXIgYWNjb3JkaW5nbHkuXG4gICAgICAgIC8vXG4gICAgICAgIC8vIEluIHRoZSBnZW5lcmFsIGNhc2UsIG9uZSB3b3VsZCBoYXZlIHRvIHVzZSB0aGUgY2FjaGVkICh1bmlmaWVkKVxuICAgICAgICAvLyBvZmZlciB0byBmaW5kIHRoZSBtLWxpbmVzIHRoYXQgYXJlIG1pc3NpbmcgZnJvbSB0aGUgcmVjb25zdHJ1Y3RlZFxuICAgICAgICAvLyBhbnN3ZXIsIHBvdGVudGlhbGx5IGdyYWJiaW5nIHRoZW0gZnJvbSB0aGUgY2FjaGVkICh1bmlmaWVkKSBhbnN3ZXIuXG4gICAgICAgIC8vIE9uZSBoYXMgdG8gYmUgY2FyZWZ1bCB3aXRoIHRoaXMgYXBwcm9hY2ggYmVjYXVzZSBpbmFjdGl2ZSBtLWxpbmVzIGRvXG4gICAgICAgIC8vIG5vdCBhbHdheXMgaGF2ZSBhbiBtaWQsIG1ha2luZyBpdCB0cmlja3kgKGltcG9zc2libGU/KSB0byBmaW5kIHdoZXJlXG4gICAgICAgIC8vIGV4YWN0bHkgYW5kIHdoaWNoIG0tbGluZXMgYXJlIG1pc3NpbmcgZnJvbSB0aGUgcmVjb25zdHJ1Y3RlZCBhbnN3ZXIuXG5cbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBjYWNoZWQubWVkaWEubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIHZhciB1TGluZSA9IGNhY2hlZC5tZWRpYVtpXTtcblxuICAgICAgICAgICAgZGVsZXRlIHVMaW5lLm1zaWQ7XG4gICAgICAgICAgICBkZWxldGUgdUxpbmUuc291cmNlcztcbiAgICAgICAgICAgIGRlbGV0ZSB1TGluZS5zc3JjR3JvdXBzO1xuXG4gICAgICAgICAgICBpZiAodHlwZW9mIHNvdXJjZXMydWxbaV0gPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICAgIGlmICghdUxpbmUuZGlyZWN0aW9uXG4gICAgICAgICAgICAgICAgICB8fCB1TGluZS5kaXJlY3Rpb24gPT09ICdzZW5kcmVjdicpXG4gICAgICAgICAgICAgICAgICB1TGluZS5kaXJlY3Rpb24gPSAncmVjdm9ubHknO1xuICAgICAgICAgICAgICBlbHNlIGlmICh1TGluZS5kaXJlY3Rpb24gPT09ICdzZW5kb25seScpXG4gICAgICAgICAgICAgICAgICB1TGluZS5kaXJlY3Rpb24gPSAnaW5hY3RpdmUnO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgaWYgKCF1TGluZS5kaXJlY3Rpb25cbiAgICAgICAgICAgICAgICAgIHx8IHVMaW5lLmRpcmVjdGlvbiA9PT0gJ3NlbmRyZWN2JylcbiAgICAgICAgICAgICAgICAgIHVMaW5lLmRpcmVjdGlvbiA9ICdzZW5kcmVjdic7XG4gICAgICAgICAgICAgIGVsc2UgaWYgKHVMaW5lLmRpcmVjdGlvbiA9PT0gJ3JlY3Zvbmx5JylcbiAgICAgICAgICAgICAgICAgIHVMaW5lLmRpcmVjdGlvbiA9ICdzZW5kb25seSc7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHVMaW5lLnNvdXJjZXMgPSBzb3VyY2VzMnVsW2ldO1xuICAgICAgICAgICAgdUxpbmUuY2FuZGlkYXRlcyA9IGNhbmRpZGF0ZXM7XG4gICAgICAgICAgICB1TGluZS5pY2VVZnJhZyA9IGljZVVmcmFnO1xuICAgICAgICAgICAgdUxpbmUuaWNlUHdkID0gaWNlUHdkO1xuICAgICAgICAgICAgdUxpbmUuZmluZ2VycHJpbnQgPSBmaW5nZXJwcmludDtcblxuICAgICAgICAgICAgdUxpbmUucnRwID0gcnRwW3VMaW5lLnR5cGVdO1xuICAgICAgICAgICAgdUxpbmUucGF5bG9hZHMgPSBwYXlsb2Fkc1t1TGluZS50eXBlXTtcbiAgICAgICAgICAgIHVMaW5lLnJ0Y3BGYiA9IHJ0Y3BGYlt1TGluZS50eXBlXTtcblxuICAgICAgICAgICAgc2Vzc2lvbi5tZWRpYS5wdXNoKHVMaW5lKTtcblxuICAgICAgICAgICAgaWYgKHR5cGVvZiB1TGluZS5taWQgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICAgICAgLy8gaW5hY3RpdmUgbGluZXMgZG9uJ3QvbWF5IG5vdCBoYXZlIGFuIG1pZC5cbiAgICAgICAgICAgICAgICBtaWRzLnB1c2godUxpbmUubWlkKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH0gZWxzZSB7XG5cbiAgICAgICAgLy8gU0RQIG9mZmVyL2Fuc3dlciAoYW5kIHRoZSBKU0VQIHNwZWMpIGZvcmJpZHMgcmVtb3ZpbmcgYW4gbS1zZWN0aW9uXG4gICAgICAgIC8vIHVuZGVyIGFueSBjaXJjdW1zdGFuY2VzLiBJZiB3ZSBhcmUgbm8gbG9uZ2VyIGludGVyZXN0ZWQgaW4gc2VuZGluZyBhXG4gICAgICAgIC8vIHRyYWNrLCB3ZSBqdXN0IHJlbW92ZSB0aGUgbXNpZCBhbmQgc3NyYyBhdHRyaWJ1dGVzIGFuZCBzZXQgaXQgdG9cbiAgICAgICAgLy8gZWl0aGVyIGE9cmVjdm9ubHkgKGFzIHRoZSByZW9mZmVyZXIsIHdlIG11c3QgdXNlIHJlY3Zvbmx5IGlmIHRoZVxuICAgICAgICAvLyBvdGhlciBzaWRlIHdhcyBwcmV2aW91c2x5IHNlbmRpbmcgb24gdGhlIG0tc2VjdGlvbiwgYnV0IHdlIGNhbiBhbHNvXG4gICAgICAgIC8vIGxlYXZlIHRoZSBwb3NzaWJpbGl0eSBvcGVuIGlmIGl0IHdhc24ndCBwcmV2aW91c2x5IGluIHVzZSksIG9yXG4gICAgICAgIC8vIGE9aW5hY3RpdmUuXG5cbiAgICAgICAgaWYgKHR5cGVvZiBjYWNoZWQgIT09ICd1bmRlZmluZWQnICYmXG4gICAgICAgICAgICB0eXBlb2YgY2FjaGVkLm1lZGlhICE9PSAndW5kZWZpbmVkJyAmJlxuICAgICAgICAgICAgQXJyYXkuaXNBcnJheShjYWNoZWQubWVkaWEpKSB7XG4gICAgICAgICAgICBjYWNoZWQubWVkaWEuZm9yRWFjaChmdW5jdGlvbih1TGluZSkge1xuICAgICAgICAgICAgICAgIG1pZHMucHVzaCh1TGluZS5taWQpO1xuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgbWlkMnVsW3VMaW5lLm1pZF0gIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICAgICAgICAgIHNlc3Npb24ubWVkaWEucHVzaChtaWQydWxbdUxpbmUubWlkXSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgZGVsZXRlIHVMaW5lLm1zaWQ7XG4gICAgICAgICAgICAgICAgICAgIGRlbGV0ZSB1TGluZS5zb3VyY2VzO1xuICAgICAgICAgICAgICAgICAgICBkZWxldGUgdUxpbmUuc3NyY0dyb3VwcztcblxuICAgICAgICAgICAgICAgICAgICBpZiAoIXVMaW5lLmRpcmVjdGlvblxuICAgICAgICAgICAgICAgICAgICAgICAgfHwgdUxpbmUuZGlyZWN0aW9uID09PSAnc2VuZHJlY3YnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB1TGluZS5kaXJlY3Rpb24gPSAnc2VuZG9ubHknO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmICghdUxpbmUuZGlyZWN0aW9uXG4gICAgICAgICAgICAgICAgICAgICAgICB8fCB1TGluZS5kaXJlY3Rpb24gPT09ICdyZWN2b25seScpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHVMaW5lLmRpcmVjdGlvbiA9ICdpbmFjdGl2ZSc7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICBhZGRTZXR1cEF0dHIgKHVMaW5lKTtcbiAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbi5tZWRpYS5wdXNoKHVMaW5lKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEFkZCBhbGwgdGhlIHJlbWFpbmluZyAobmV3KSBtLWxpbmVzIG9mIHRoZSB0cmFuc2Zvcm1lZCBTRFAuXG4gICAgICAgIE9iamVjdC5rZXlzKG1pZDJ1bCkuZm9yRWFjaChmdW5jdGlvbihtaWQpIHtcbiAgICAgICAgICAgIGlmIChtaWRzLmluZGV4T2YobWlkKSA9PT0gLTEpIHtcbiAgICAgICAgICAgICAgICBtaWRzLnB1c2gobWlkKTtcbiAgICAgICAgICAgICAgICBpZiAobWlkMnVsW21pZF0uZGlyZWN0aW9uID09PSAncmVjdm9ubHknKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIFRoaXMgaXMgYSByZW1vdGUgcmVjdm9ubHkgY2hhbm5lbC4gQWRkIGl0cyBTU1JDIHRvIHRoZVxuICAgICAgICAgICAgICAgICAgICAvLyBhcHByb3ByaWF0ZSBzZW5kcmVjdiBvciBzZW5kb25seSBjaGFubmVsLlxuICAgICAgICAgICAgICAgICAgICAvLyBUT0RPKGdwKSB3aGF0IGlmIHdlIGRvbid0IGhhdmUgc2VuZHJlY3Yvc2VuZG9ubHlcbiAgICAgICAgICAgICAgICAgICAgLy8gY2hhbm5lbD9cblxuICAgICAgICAgICAgICAgICAgICB2YXIgZG9uZSA9IGZhbHNlO1xuXG4gICAgICAgICAgICAgICAgICAgIHNlc3Npb24ubWVkaWEuc29tZShmdW5jdGlvbiAodUxpbmUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgodUxpbmUuZGlyZWN0aW9uID09PSAnc2VuZHJlY3YnIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdUxpbmUuZGlyZWN0aW9uID09PSAnc2VuZG9ubHknKSAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVMaW5lLnR5cGUgPT09IG1pZDJ1bFttaWRdLnR5cGUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBtaWQydWxbbWlkXSBzaG91bGRuJ3QgaGF2ZSBhbnkgc3NyYy1ncm91cHNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBPYmplY3Qua2V5cyhtaWQydWxbbWlkXS5zb3VyY2VzKS5mb3JFYWNoKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbiAoc3NyYykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1TGluZS5zb3VyY2VzW3NzcmNdID1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1pZDJ1bFttaWRdLnNvdXJjZXNbc3NyY107XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKCFkb25lKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzZXNzaW9uLm1lZGlhLnB1c2gobWlkMnVsW21pZF0pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbi5tZWRpYS5wdXNoKG1pZDJ1bFttaWRdKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8vIEFmdGVyIHdlIGhhdmUgY29uc3RydWN0ZWQgdGhlIFBsYW4gVW5pZmllZCBtLWxpbmVzIHdlIGNhbiBmaWd1cmUgb3V0XG4gICAgLy8gd2hlcmUgKGluIHdoaWNoIG0tbGluZSkgdG8gcGxhY2UgdGhlICdyZWN2b25seSBTU1JDcycuXG4gICAgLy8gTm90ZTogd2UgYXNzdW1lIGhlcmUgdGhhdCB3ZSBhcmUgdGhlIGFuc3dlcmVyIGluIHRoZSBPL0EsIHNvIGFueSBvZmZlcnNcbiAgICAvLyB3aGljaCB3ZSB0cmFuc2xhdGUgY29tZSBmcm9tIHRoZSByZW1vdGUgc2lkZSwgd2hpbGUgYW5zd2VycyBhcmUgbG9jYWxcbiAgICAvLyAoYW5kIHNvIG91ciBsYXN0IGxvY2FsIGRlc2NyaXB0aW9uIGlzIGNhY2hlZCBhcyBhbiAnYW5zd2VyJykuXG4gICAgW1wiYXVkaW9cIiwgXCJ2aWRlb1wiXS5mb3JFYWNoKGZ1bmN0aW9uICh0eXBlKSB7XG4gICAgICAgIGlmICghc2Vzc2lvbiB8fCAhc2Vzc2lvbi5tZWRpYSB8fCAhQXJyYXkuaXNBcnJheShzZXNzaW9uLm1lZGlhKSlcbiAgICAgICAgICAgIHJldHVybjtcblxuICAgICAgICB2YXIgaWR4ID0gbnVsbDtcbiAgICAgICAgaWYgKE9iamVjdC5rZXlzKHJlY3Zvbmx5U3NyY3NbdHlwZV0pLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIGlkeCA9IHNlbGYuZ2V0Rmlyc3RTZW5kaW5nSW5kZXhGcm9tQW5zd2VyKHR5cGUpO1xuICAgICAgICAgICAgaWYgKGlkeCA9PT0gbnVsbCl7XG4gICAgICAgICAgICAgICAgLy8gSWYgdGhpcyBpcyB0aGUgZmlyc3Qgb2ZmZXIgd2UgcmVjZWl2ZSwgd2UgZG9uJ3QgaGF2ZSBhXG4gICAgICAgICAgICAgICAgLy8gY2FjaGVkIGFuc3dlci4gQXNzdW1lIHRoYXQgd2Ugd2lsbCBiZSBzZW5kaW5nIG1lZGlhIHVzaW5nXG4gICAgICAgICAgICAgICAgLy8gdGhlIGZpcnN0IG0tbGluZSBmb3IgZWFjaCBtZWRpYSB0eXBlLlxuXG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBzZXNzaW9uLm1lZGlhLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzZXNzaW9uLm1lZGlhW2ldLnR5cGUgPT09IHR5cGUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlkeCA9IGk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChpZHggJiYgc2Vzc2lvbi5tZWRpYS5sZW5ndGggPiBpZHgpIHtcbiAgICAgICAgICAgIHZhciBtTGluZSA9IHNlc3Npb24ubWVkaWFbaWR4XTtcbiAgICAgICAgICAgIE9iamVjdC5rZXlzKHJlY3Zvbmx5U3NyY3NbdHlwZV0pLmZvckVhY2goZnVuY3Rpb24oc3NyYykge1xuICAgICAgICAgICAgICAgIGlmIChtTGluZS5zb3VyY2VzICYmIG1MaW5lLnNvdXJjZXNbc3NyY10pIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS53YXJuKFwiUmVwbGFjaW5nIGFuIGV4aXN0aW5nIFNTUkMuXCIpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoIW1MaW5lLnNvdXJjZXMpIHtcbiAgICAgICAgICAgICAgICAgICAgbUxpbmUuc291cmNlcyA9IHt9O1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIG1MaW5lLnNvdXJjZXNbc3NyY10gPSByZWN2b25seVNzcmNzW3R5cGVdW3NzcmNdO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9KTtcblxuICAgIGlmICh0eXBlb2Ygc2Vzc2lvbi5ncm91cHMgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAvLyBXZSByZWdlbmVyYXRlIHRoZSBCVU5ETEUgZ3JvdXAgKHNpbmNlIHdlIHJlZ2VuZXJhdGVkIHRoZSBtaWRzKVxuICAgICAgc2Vzc2lvbi5ncm91cHMuc29tZShmdW5jdGlvbihncm91cCkge1xuXHQgIGlmIChncm91cC50eXBlID09PSAnQlVORExFJykge1xuXHQgICAgICBncm91cC5taWRzID0gbWlkcy5qb2luKCcgJyk7XG5cdCAgICAgIHJldHVybiB0cnVlO1xuXHQgIH1cbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8vIG1zaWQgc2VtYW50aWNcbiAgICBzZXNzaW9uLm1zaWRTZW1hbnRpYyA9IHtcbiAgICAgICAgc2VtYW50aWM6ICdXTVMnLFxuICAgICAgICB0b2tlbjogJyonXG4gICAgfTtcblxuICAgIHZhciByZXNTdHIgPSB0cmFuc2Zvcm0ud3JpdGUoc2Vzc2lvbik7XG5cbiAgICAvLyBDYWNoZSB0aGUgdHJhbnNmb3JtZWQgU0RQIChVbmlmaWVkIFBsYW4pIGZvciBsYXRlciByZS11c2UgaW4gdGhpc1xuICAgIC8vIGZ1bmN0aW9uLlxuICAgIHRoaXMuY2FjaGVbZGVzYy50eXBlXSA9IHJlc1N0cjtcblxuICAgIHJldHVybiBuZXcgUlRDU2Vzc2lvbkRlc2NyaXB0aW9uKHtcbiAgICAgICAgdHlwZTogZGVzYy50eXBlLFxuICAgICAgICBzZHA6IHJlc1N0clxuICAgIH0pO1xuXG4gICAgLy8jZW5kcmVnaW9uXG59O1xuIiwiLyogQ29weXJpZ2h0IEAgMjAxNSBBdGxhc3NpYW4gUHR5IEx0ZFxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqL1xuXG52YXIgdHJhbnNmb3JtID0gcmVxdWlyZSgnc2RwLXRyYW5zZm9ybScpO1xuXG5leHBvcnRzLndyaXRlID0gZnVuY3Rpb24oc2Vzc2lvbiwgb3B0cykge1xuXG4gIGlmICh0eXBlb2Ygc2Vzc2lvbiAhPT0gJ3VuZGVmaW5lZCcgJiZcbiAgICAgIHR5cGVvZiBzZXNzaW9uLm1lZGlhICE9PSAndW5kZWZpbmVkJyAmJlxuICAgICAgQXJyYXkuaXNBcnJheShzZXNzaW9uLm1lZGlhKSkge1xuXG4gICAgc2Vzc2lvbi5tZWRpYS5mb3JFYWNoKGZ1bmN0aW9uIChtTGluZSkge1xuICAgICAgLy8gZXhwYW5kIHNvdXJjZXMgdG8gc3NyY3NcbiAgICAgIGlmICh0eXBlb2YgbUxpbmUuc291cmNlcyAhPT0gJ3VuZGVmaW5lZCcgJiZcbiAgICAgICAgT2JqZWN0LmtleXMobUxpbmUuc291cmNlcykubGVuZ3RoICE9PSAwKSB7XG4gICAgICAgICAgbUxpbmUuc3NyY3MgPSBbXTtcbiAgICAgICAgICBPYmplY3Qua2V5cyhtTGluZS5zb3VyY2VzKS5mb3JFYWNoKGZ1bmN0aW9uIChzc3JjKSB7XG4gICAgICAgICAgICB2YXIgc291cmNlID0gbUxpbmUuc291cmNlc1tzc3JjXTtcbiAgICAgICAgICAgIE9iamVjdC5rZXlzKHNvdXJjZSkuZm9yRWFjaChmdW5jdGlvbiAoYXR0cmlidXRlKSB7XG4gICAgICAgICAgICAgIG1MaW5lLnNzcmNzLnB1c2goe1xuICAgICAgICAgICAgICAgIGlkOiBzc3JjLFxuICAgICAgICAgICAgICAgIGF0dHJpYnV0ZTogYXR0cmlidXRlLFxuICAgICAgICAgICAgICAgIHZhbHVlOiBzb3VyY2VbYXR0cmlidXRlXVxuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH0pO1xuICAgICAgICAgIGRlbGV0ZSBtTGluZS5zb3VyY2VzO1xuICAgICAgICB9XG5cbiAgICAgIC8vIGpvaW4gc3NyY3MgaW4gc3NyYyBncm91cHNcbiAgICAgIGlmICh0eXBlb2YgbUxpbmUuc3NyY0dyb3VwcyAhPT0gJ3VuZGVmaW5lZCcgJiZcbiAgICAgICAgQXJyYXkuaXNBcnJheShtTGluZS5zc3JjR3JvdXBzKSkge1xuICAgICAgICAgIG1MaW5lLnNzcmNHcm91cHMuZm9yRWFjaChmdW5jdGlvbiAoc3NyY0dyb3VwKSB7XG4gICAgICAgICAgICBpZiAodHlwZW9mIHNzcmNHcm91cC5zc3JjcyAhPT0gJ3VuZGVmaW5lZCcgJiZcbiAgICAgICAgICAgICAgICBBcnJheS5pc0FycmF5KHNzcmNHcm91cC5zc3JjcykpIHtcbiAgICAgICAgICAgICAgc3NyY0dyb3VwLnNzcmNzID0gc3NyY0dyb3VwLnNzcmNzLmpvaW4oJyAnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgLy8gam9pbiBncm91cCBtaWRzXG4gIGlmICh0eXBlb2Ygc2Vzc2lvbiAhPT0gJ3VuZGVmaW5lZCcgJiZcbiAgICAgIHR5cGVvZiBzZXNzaW9uLmdyb3VwcyAhPT0gJ3VuZGVmaW5lZCcgJiYgQXJyYXkuaXNBcnJheShzZXNzaW9uLmdyb3VwcykpIHtcblxuICAgIHNlc3Npb24uZ3JvdXBzLmZvckVhY2goZnVuY3Rpb24gKGcpIHtcbiAgICAgIGlmICh0eXBlb2YgZy5taWRzICE9PSAndW5kZWZpbmVkJyAmJiBBcnJheS5pc0FycmF5KGcubWlkcykpIHtcbiAgICAgICAgZy5taWRzID0gZy5taWRzLmpvaW4oJyAnKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIHJldHVybiB0cmFuc2Zvcm0ud3JpdGUoc2Vzc2lvbiwgb3B0cyk7XG59O1xuXG5leHBvcnRzLnBhcnNlID0gZnVuY3Rpb24oc2RwKSB7XG4gIHZhciBzZXNzaW9uID0gdHJhbnNmb3JtLnBhcnNlKHNkcCk7XG5cbiAgaWYgKHR5cGVvZiBzZXNzaW9uICE9PSAndW5kZWZpbmVkJyAmJiB0eXBlb2Ygc2Vzc2lvbi5tZWRpYSAhPT0gJ3VuZGVmaW5lZCcgJiZcbiAgICAgIEFycmF5LmlzQXJyYXkoc2Vzc2lvbi5tZWRpYSkpIHtcblxuICAgIHNlc3Npb24ubWVkaWEuZm9yRWFjaChmdW5jdGlvbiAobUxpbmUpIHtcbiAgICAgIC8vIGdyb3VwIHNvdXJjZXMgYXR0cmlidXRlcyBieSBzc3JjXG4gICAgICBpZiAodHlwZW9mIG1MaW5lLnNzcmNzICE9PSAndW5kZWZpbmVkJyAmJiBBcnJheS5pc0FycmF5KG1MaW5lLnNzcmNzKSkge1xuICAgICAgICBtTGluZS5zb3VyY2VzID0ge307XG4gICAgICAgIG1MaW5lLnNzcmNzLmZvckVhY2goZnVuY3Rpb24gKHNzcmMpIHtcbiAgICAgICAgICBpZiAoIW1MaW5lLnNvdXJjZXNbc3NyYy5pZF0pXG4gICAgICAgICAgbUxpbmUuc291cmNlc1tzc3JjLmlkXSA9IHt9O1xuICAgICAgICBtTGluZS5zb3VyY2VzW3NzcmMuaWRdW3NzcmMuYXR0cmlidXRlXSA9IHNzcmMudmFsdWU7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGRlbGV0ZSBtTGluZS5zc3JjcztcbiAgICAgIH1cblxuICAgICAgLy8gc3BsaXQgc3NyY3MgaW4gc3NyYyBncm91cHNcbiAgICAgIGlmICh0eXBlb2YgbUxpbmUuc3NyY0dyb3VwcyAhPT0gJ3VuZGVmaW5lZCcgJiZcbiAgICAgICAgQXJyYXkuaXNBcnJheShtTGluZS5zc3JjR3JvdXBzKSkge1xuICAgICAgICAgIG1MaW5lLnNzcmNHcm91cHMuZm9yRWFjaChmdW5jdGlvbiAoc3NyY0dyb3VwKSB7XG4gICAgICAgICAgICBpZiAodHlwZW9mIHNzcmNHcm91cC5zc3JjcyA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgICAgc3NyY0dyb3VwLnNzcmNzID0gc3NyY0dyb3VwLnNzcmNzLnNwbGl0KCcgJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9KTtcbiAgfVxuICAvLyBzcGxpdCBncm91cCBtaWRzXG4gIGlmICh0eXBlb2Ygc2Vzc2lvbiAhPT0gJ3VuZGVmaW5lZCcgJiZcbiAgICAgIHR5cGVvZiBzZXNzaW9uLmdyb3VwcyAhPT0gJ3VuZGVmaW5lZCcgJiYgQXJyYXkuaXNBcnJheShzZXNzaW9uLmdyb3VwcykpIHtcblxuICAgIHNlc3Npb24uZ3JvdXBzLmZvckVhY2goZnVuY3Rpb24gKGcpIHtcbiAgICAgIGlmICh0eXBlb2YgZy5taWRzID09PSAnc3RyaW5nJykge1xuICAgICAgICBnLm1pZHMgPSBnLm1pZHMuc3BsaXQoJyAnKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIHJldHVybiBzZXNzaW9uO1xufTtcblxuIiwiIC8qIGVzbGludC1lbnYgbm9kZSAqL1xuJ3VzZSBzdHJpY3QnO1xuXG4vLyBTRFAgaGVscGVycy5cbnZhciBTRFBVdGlscyA9IHt9O1xuXG4vLyBHZW5lcmF0ZSBhbiBhbHBoYW51bWVyaWMgaWRlbnRpZmllciBmb3IgY25hbWUgb3IgbWlkcy5cbi8vIFRPRE86IHVzZSBVVUlEcyBpbnN0ZWFkPyBodHRwczovL2dpc3QuZ2l0aHViLmNvbS9qZWQvOTgyODgzXG5TRFBVdGlscy5nZW5lcmF0ZUlkZW50aWZpZXIgPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuIE1hdGgucmFuZG9tKCkudG9TdHJpbmcoMzYpLnN1YnN0cigyLCAxMCk7XG59O1xuXG4vLyBUaGUgUlRDUCBDTkFNRSB1c2VkIGJ5IGFsbCBwZWVyY29ubmVjdGlvbnMgZnJvbSB0aGUgc2FtZSBKUy5cblNEUFV0aWxzLmxvY2FsQ05hbWUgPSBTRFBVdGlscy5nZW5lcmF0ZUlkZW50aWZpZXIoKTtcblxuLy8gU3BsaXRzIFNEUCBpbnRvIGxpbmVzLCBkZWFsaW5nIHdpdGggYm90aCBDUkxGIGFuZCBMRi5cblNEUFV0aWxzLnNwbGl0TGluZXMgPSBmdW5jdGlvbihibG9iKSB7XG4gIHJldHVybiBibG9iLnRyaW0oKS5zcGxpdCgnXFxuJykubWFwKGZ1bmN0aW9uKGxpbmUpIHtcbiAgICByZXR1cm4gbGluZS50cmltKCk7XG4gIH0pO1xufTtcbi8vIFNwbGl0cyBTRFAgaW50byBzZXNzaW9ucGFydCBhbmQgbWVkaWFzZWN0aW9ucy4gRW5zdXJlcyBDUkxGLlxuU0RQVXRpbHMuc3BsaXRTZWN0aW9ucyA9IGZ1bmN0aW9uKGJsb2IpIHtcbiAgdmFyIHBhcnRzID0gYmxvYi5zcGxpdCgnXFxubT0nKTtcbiAgcmV0dXJuIHBhcnRzLm1hcChmdW5jdGlvbihwYXJ0LCBpbmRleCkge1xuICAgIHJldHVybiAoaW5kZXggPiAwID8gJ209JyArIHBhcnQgOiBwYXJ0KS50cmltKCkgKyAnXFxyXFxuJztcbiAgfSk7XG59O1xuXG4vLyBSZXR1cm5zIGxpbmVzIHRoYXQgc3RhcnQgd2l0aCBhIGNlcnRhaW4gcHJlZml4LlxuU0RQVXRpbHMubWF0Y2hQcmVmaXggPSBmdW5jdGlvbihibG9iLCBwcmVmaXgpIHtcbiAgcmV0dXJuIFNEUFV0aWxzLnNwbGl0TGluZXMoYmxvYikuZmlsdGVyKGZ1bmN0aW9uKGxpbmUpIHtcbiAgICByZXR1cm4gbGluZS5pbmRleE9mKHByZWZpeCkgPT09IDA7XG4gIH0pO1xufTtcblxuLy8gUGFyc2VzIGFuIElDRSBjYW5kaWRhdGUgbGluZS4gU2FtcGxlIGlucHV0OlxuLy8gY2FuZGlkYXRlOjcwMjc4NjM1MCAyIHVkcCA0MTgxOTkwMiA4LjguOC44IDYwNzY5IHR5cCByZWxheSByYWRkciA4LjguOC44XG4vLyBycG9ydCA1NTk5NlwiXG5TRFBVdGlscy5wYXJzZUNhbmRpZGF0ZSA9IGZ1bmN0aW9uKGxpbmUpIHtcbiAgdmFyIHBhcnRzO1xuICAvLyBQYXJzZSBib3RoIHZhcmlhbnRzLlxuICBpZiAobGluZS5pbmRleE9mKCdhPWNhbmRpZGF0ZTonKSA9PT0gMCkge1xuICAgIHBhcnRzID0gbGluZS5zdWJzdHJpbmcoMTIpLnNwbGl0KCcgJyk7XG4gIH0gZWxzZSB7XG4gICAgcGFydHMgPSBsaW5lLnN1YnN0cmluZygxMCkuc3BsaXQoJyAnKTtcbiAgfVxuXG4gIHZhciBjYW5kaWRhdGUgPSB7XG4gICAgZm91bmRhdGlvbjogcGFydHNbMF0sXG4gICAgY29tcG9uZW50OiBwYXJ0c1sxXSxcbiAgICBwcm90b2NvbDogcGFydHNbMl0udG9Mb3dlckNhc2UoKSxcbiAgICBwcmlvcml0eTogcGFyc2VJbnQocGFydHNbM10sIDEwKSxcbiAgICBpcDogcGFydHNbNF0sXG4gICAgcG9ydDogcGFyc2VJbnQocGFydHNbNV0sIDEwKSxcbiAgICAvLyBza2lwIHBhcnRzWzZdID09ICd0eXAnXG4gICAgdHlwZTogcGFydHNbN11cbiAgfTtcblxuICBmb3IgKHZhciBpID0gODsgaSA8IHBhcnRzLmxlbmd0aDsgaSArPSAyKSB7XG4gICAgc3dpdGNoIChwYXJ0c1tpXSkge1xuICAgICAgY2FzZSAncmFkZHInOlxuICAgICAgICBjYW5kaWRhdGUucmVsYXRlZEFkZHJlc3MgPSBwYXJ0c1tpICsgMV07XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAncnBvcnQnOlxuICAgICAgICBjYW5kaWRhdGUucmVsYXRlZFBvcnQgPSBwYXJzZUludChwYXJ0c1tpICsgMV0sIDEwKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICd0Y3B0eXBlJzpcbiAgICAgICAgY2FuZGlkYXRlLnRjcFR5cGUgPSBwYXJ0c1tpICsgMV07XG4gICAgICAgIGJyZWFrO1xuICAgICAgZGVmYXVsdDogLy8gZXh0ZW5zaW9uIGhhbmRsaW5nLCBpbiBwYXJ0aWN1bGFyIHVmcmFnXG4gICAgICAgIGNhbmRpZGF0ZVtwYXJ0c1tpXV0gPSBwYXJ0c1tpICsgMV07XG4gICAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuICByZXR1cm4gY2FuZGlkYXRlO1xufTtcblxuLy8gVHJhbnNsYXRlcyBhIGNhbmRpZGF0ZSBvYmplY3QgaW50byBTRFAgY2FuZGlkYXRlIGF0dHJpYnV0ZS5cblNEUFV0aWxzLndyaXRlQ2FuZGlkYXRlID0gZnVuY3Rpb24oY2FuZGlkYXRlKSB7XG4gIHZhciBzZHAgPSBbXTtcbiAgc2RwLnB1c2goY2FuZGlkYXRlLmZvdW5kYXRpb24pO1xuICBzZHAucHVzaChjYW5kaWRhdGUuY29tcG9uZW50KTtcbiAgc2RwLnB1c2goY2FuZGlkYXRlLnByb3RvY29sLnRvVXBwZXJDYXNlKCkpO1xuICBzZHAucHVzaChjYW5kaWRhdGUucHJpb3JpdHkpO1xuICBzZHAucHVzaChjYW5kaWRhdGUuaXApO1xuICBzZHAucHVzaChjYW5kaWRhdGUucG9ydCk7XG5cbiAgdmFyIHR5cGUgPSBjYW5kaWRhdGUudHlwZTtcbiAgc2RwLnB1c2goJ3R5cCcpO1xuICBzZHAucHVzaCh0eXBlKTtcbiAgaWYgKHR5cGUgIT09ICdob3N0JyAmJiBjYW5kaWRhdGUucmVsYXRlZEFkZHJlc3MgJiZcbiAgICAgIGNhbmRpZGF0ZS5yZWxhdGVkUG9ydCkge1xuICAgIHNkcC5wdXNoKCdyYWRkcicpO1xuICAgIHNkcC5wdXNoKGNhbmRpZGF0ZS5yZWxhdGVkQWRkcmVzcyk7IC8vIHdhczogcmVsQWRkclxuICAgIHNkcC5wdXNoKCdycG9ydCcpO1xuICAgIHNkcC5wdXNoKGNhbmRpZGF0ZS5yZWxhdGVkUG9ydCk7IC8vIHdhczogcmVsUG9ydFxuICB9XG4gIGlmIChjYW5kaWRhdGUudGNwVHlwZSAmJiBjYW5kaWRhdGUucHJvdG9jb2wudG9Mb3dlckNhc2UoKSA9PT0gJ3RjcCcpIHtcbiAgICBzZHAucHVzaCgndGNwdHlwZScpO1xuICAgIHNkcC5wdXNoKGNhbmRpZGF0ZS50Y3BUeXBlKTtcbiAgfVxuICByZXR1cm4gJ2NhbmRpZGF0ZTonICsgc2RwLmpvaW4oJyAnKTtcbn07XG5cbi8vIFBhcnNlcyBhbiBpY2Utb3B0aW9ucyBsaW5lLCByZXR1cm5zIGFuIGFycmF5IG9mIG9wdGlvbiB0YWdzLlxuLy8gYT1pY2Utb3B0aW9uczpmb28gYmFyXG5TRFBVdGlscy5wYXJzZUljZU9wdGlvbnMgPSBmdW5jdGlvbihsaW5lKSB7XG4gIHJldHVybiBsaW5lLnN1YnN0cigxNCkuc3BsaXQoJyAnKTtcbn1cblxuLy8gUGFyc2VzIGFuIHJ0cG1hcCBsaW5lLCByZXR1cm5zIFJUQ1J0cENvZGRlY1BhcmFtZXRlcnMuIFNhbXBsZSBpbnB1dDpcbi8vIGE9cnRwbWFwOjExMSBvcHVzLzQ4MDAwLzJcblNEUFV0aWxzLnBhcnNlUnRwTWFwID0gZnVuY3Rpb24obGluZSkge1xuICB2YXIgcGFydHMgPSBsaW5lLnN1YnN0cig5KS5zcGxpdCgnICcpO1xuICB2YXIgcGFyc2VkID0ge1xuICAgIHBheWxvYWRUeXBlOiBwYXJzZUludChwYXJ0cy5zaGlmdCgpLCAxMCkgLy8gd2FzOiBpZFxuICB9O1xuXG4gIHBhcnRzID0gcGFydHNbMF0uc3BsaXQoJy8nKTtcblxuICBwYXJzZWQubmFtZSA9IHBhcnRzWzBdO1xuICBwYXJzZWQuY2xvY2tSYXRlID0gcGFyc2VJbnQocGFydHNbMV0sIDEwKTsgLy8gd2FzOiBjbG9ja3JhdGVcbiAgLy8gd2FzOiBjaGFubmVsc1xuICBwYXJzZWQubnVtQ2hhbm5lbHMgPSBwYXJ0cy5sZW5ndGggPT09IDMgPyBwYXJzZUludChwYXJ0c1syXSwgMTApIDogMTtcbiAgcmV0dXJuIHBhcnNlZDtcbn07XG5cbi8vIEdlbmVyYXRlIGFuIGE9cnRwbWFwIGxpbmUgZnJvbSBSVENSdHBDb2RlY0NhcGFiaWxpdHkgb3Jcbi8vIFJUQ1J0cENvZGVjUGFyYW1ldGVycy5cblNEUFV0aWxzLndyaXRlUnRwTWFwID0gZnVuY3Rpb24oY29kZWMpIHtcbiAgdmFyIHB0ID0gY29kZWMucGF5bG9hZFR5cGU7XG4gIGlmIChjb2RlYy5wcmVmZXJyZWRQYXlsb2FkVHlwZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgcHQgPSBjb2RlYy5wcmVmZXJyZWRQYXlsb2FkVHlwZTtcbiAgfVxuICByZXR1cm4gJ2E9cnRwbWFwOicgKyBwdCArICcgJyArIGNvZGVjLm5hbWUgKyAnLycgKyBjb2RlYy5jbG9ja1JhdGUgK1xuICAgICAgKGNvZGVjLm51bUNoYW5uZWxzICE9PSAxID8gJy8nICsgY29kZWMubnVtQ2hhbm5lbHMgOiAnJykgKyAnXFxyXFxuJztcbn07XG5cbi8vIFBhcnNlcyBhbiBhPWV4dG1hcCBsaW5lIChoZWFkZXJleHRlbnNpb24gZnJvbSBSRkMgNTI4NSkuIFNhbXBsZSBpbnB1dDpcbi8vIGE9ZXh0bWFwOjIgdXJuOmlldGY6cGFyYW1zOnJ0cC1oZHJleHQ6dG9mZnNldFxuLy8gYT1leHRtYXA6Mi9zZW5kb25seSB1cm46aWV0ZjpwYXJhbXM6cnRwLWhkcmV4dDp0b2Zmc2V0XG5TRFBVdGlscy5wYXJzZUV4dG1hcCA9IGZ1bmN0aW9uKGxpbmUpIHtcbiAgdmFyIHBhcnRzID0gbGluZS5zdWJzdHIoOSkuc3BsaXQoJyAnKTtcbiAgcmV0dXJuIHtcbiAgICBpZDogcGFyc2VJbnQocGFydHNbMF0sIDEwKSxcbiAgICBkaXJlY3Rpb246IHBhcnRzWzBdLmluZGV4T2YoJy8nKSA+IDAgPyBwYXJ0c1swXS5zcGxpdCgnLycpWzFdIDogJ3NlbmRyZWN2JyxcbiAgICB1cmk6IHBhcnRzWzFdXG4gIH07XG59O1xuXG4vLyBHZW5lcmF0ZXMgYT1leHRtYXAgbGluZSBmcm9tIFJUQ1J0cEhlYWRlckV4dGVuc2lvblBhcmFtZXRlcnMgb3Jcbi8vIFJUQ1J0cEhlYWRlckV4dGVuc2lvbi5cblNEUFV0aWxzLndyaXRlRXh0bWFwID0gZnVuY3Rpb24oaGVhZGVyRXh0ZW5zaW9uKSB7XG4gIHJldHVybiAnYT1leHRtYXA6JyArIChoZWFkZXJFeHRlbnNpb24uaWQgfHwgaGVhZGVyRXh0ZW5zaW9uLnByZWZlcnJlZElkKSArXG4gICAgICAoaGVhZGVyRXh0ZW5zaW9uLmRpcmVjdGlvbiAmJiBoZWFkZXJFeHRlbnNpb24uZGlyZWN0aW9uICE9PSAnc2VuZHJlY3YnXG4gICAgICAgICAgPyAnLycgKyBoZWFkZXJFeHRlbnNpb24uZGlyZWN0aW9uXG4gICAgICAgICAgOiAnJykgK1xuICAgICAgJyAnICsgaGVhZGVyRXh0ZW5zaW9uLnVyaSArICdcXHJcXG4nO1xufTtcblxuLy8gUGFyc2VzIGFuIGZ0bXAgbGluZSwgcmV0dXJucyBkaWN0aW9uYXJ5LiBTYW1wbGUgaW5wdXQ6XG4vLyBhPWZtdHA6OTYgdmJyPW9uO2NuZz1vblxuLy8gQWxzbyBkZWFscyB3aXRoIHZicj1vbjsgY25nPW9uXG5TRFBVdGlscy5wYXJzZUZtdHAgPSBmdW5jdGlvbihsaW5lKSB7XG4gIHZhciBwYXJzZWQgPSB7fTtcbiAgdmFyIGt2O1xuICB2YXIgcGFydHMgPSBsaW5lLnN1YnN0cihsaW5lLmluZGV4T2YoJyAnKSArIDEpLnNwbGl0KCc7Jyk7XG4gIGZvciAodmFyIGogPSAwOyBqIDwgcGFydHMubGVuZ3RoOyBqKyspIHtcbiAgICBrdiA9IHBhcnRzW2pdLnRyaW0oKS5zcGxpdCgnPScpO1xuICAgIHBhcnNlZFtrdlswXS50cmltKCldID0ga3ZbMV07XG4gIH1cbiAgcmV0dXJuIHBhcnNlZDtcbn07XG5cbi8vIEdlbmVyYXRlcyBhbiBhPWZ0bXAgbGluZSBmcm9tIFJUQ1J0cENvZGVjQ2FwYWJpbGl0eSBvciBSVENSdHBDb2RlY1BhcmFtZXRlcnMuXG5TRFBVdGlscy53cml0ZUZtdHAgPSBmdW5jdGlvbihjb2RlYykge1xuICB2YXIgbGluZSA9ICcnO1xuICB2YXIgcHQgPSBjb2RlYy5wYXlsb2FkVHlwZTtcbiAgaWYgKGNvZGVjLnByZWZlcnJlZFBheWxvYWRUeXBlICE9PSB1bmRlZmluZWQpIHtcbiAgICBwdCA9IGNvZGVjLnByZWZlcnJlZFBheWxvYWRUeXBlO1xuICB9XG4gIGlmIChjb2RlYy5wYXJhbWV0ZXJzICYmIE9iamVjdC5rZXlzKGNvZGVjLnBhcmFtZXRlcnMpLmxlbmd0aCkge1xuICAgIHZhciBwYXJhbXMgPSBbXTtcbiAgICBPYmplY3Qua2V5cyhjb2RlYy5wYXJhbWV0ZXJzKS5mb3JFYWNoKGZ1bmN0aW9uKHBhcmFtKSB7XG4gICAgICBwYXJhbXMucHVzaChwYXJhbSArICc9JyArIGNvZGVjLnBhcmFtZXRlcnNbcGFyYW1dKTtcbiAgICB9KTtcbiAgICBsaW5lICs9ICdhPWZtdHA6JyArIHB0ICsgJyAnICsgcGFyYW1zLmpvaW4oJzsnKSArICdcXHJcXG4nO1xuICB9XG4gIHJldHVybiBsaW5lO1xufTtcblxuLy8gUGFyc2VzIGFuIHJ0Y3AtZmIgbGluZSwgcmV0dXJucyBSVENQUnRjcEZlZWRiYWNrIG9iamVjdC4gU2FtcGxlIGlucHV0OlxuLy8gYT1ydGNwLWZiOjk4IG5hY2sgcnBzaVxuU0RQVXRpbHMucGFyc2VSdGNwRmIgPSBmdW5jdGlvbihsaW5lKSB7XG4gIHZhciBwYXJ0cyA9IGxpbmUuc3Vic3RyKGxpbmUuaW5kZXhPZignICcpICsgMSkuc3BsaXQoJyAnKTtcbiAgcmV0dXJuIHtcbiAgICB0eXBlOiBwYXJ0cy5zaGlmdCgpLFxuICAgIHBhcmFtZXRlcjogcGFydHMuam9pbignICcpXG4gIH07XG59O1xuLy8gR2VuZXJhdGUgYT1ydGNwLWZiIGxpbmVzIGZyb20gUlRDUnRwQ29kZWNDYXBhYmlsaXR5IG9yIFJUQ1J0cENvZGVjUGFyYW1ldGVycy5cblNEUFV0aWxzLndyaXRlUnRjcEZiID0gZnVuY3Rpb24oY29kZWMpIHtcbiAgdmFyIGxpbmVzID0gJyc7XG4gIHZhciBwdCA9IGNvZGVjLnBheWxvYWRUeXBlO1xuICBpZiAoY29kZWMucHJlZmVycmVkUGF5bG9hZFR5cGUgIT09IHVuZGVmaW5lZCkge1xuICAgIHB0ID0gY29kZWMucHJlZmVycmVkUGF5bG9hZFR5cGU7XG4gIH1cbiAgaWYgKGNvZGVjLnJ0Y3BGZWVkYmFjayAmJiBjb2RlYy5ydGNwRmVlZGJhY2subGVuZ3RoKSB7XG4gICAgLy8gRklYTUU6IHNwZWNpYWwgaGFuZGxpbmcgZm9yIHRyci1pbnQ/XG4gICAgY29kZWMucnRjcEZlZWRiYWNrLmZvckVhY2goZnVuY3Rpb24oZmIpIHtcbiAgICAgIGxpbmVzICs9ICdhPXJ0Y3AtZmI6JyArIHB0ICsgJyAnICsgZmIudHlwZSArXG4gICAgICAoZmIucGFyYW1ldGVyICYmIGZiLnBhcmFtZXRlci5sZW5ndGggPyAnICcgKyBmYi5wYXJhbWV0ZXIgOiAnJykgK1xuICAgICAgICAgICdcXHJcXG4nO1xuICAgIH0pO1xuICB9XG4gIHJldHVybiBsaW5lcztcbn07XG5cbi8vIFBhcnNlcyBhbiBSRkMgNTU3NiBzc3JjIG1lZGlhIGF0dHJpYnV0ZS4gU2FtcGxlIGlucHV0OlxuLy8gYT1zc3JjOjM3MzU5Mjg1NTkgY25hbWU6c29tZXRoaW5nXG5TRFBVdGlscy5wYXJzZVNzcmNNZWRpYSA9IGZ1bmN0aW9uKGxpbmUpIHtcbiAgdmFyIHNwID0gbGluZS5pbmRleE9mKCcgJyk7XG4gIHZhciBwYXJ0cyA9IHtcbiAgICBzc3JjOiBwYXJzZUludChsaW5lLnN1YnN0cig3LCBzcCAtIDcpLCAxMClcbiAgfTtcbiAgdmFyIGNvbG9uID0gbGluZS5pbmRleE9mKCc6Jywgc3ApO1xuICBpZiAoY29sb24gPiAtMSkge1xuICAgIHBhcnRzLmF0dHJpYnV0ZSA9IGxpbmUuc3Vic3RyKHNwICsgMSwgY29sb24gLSBzcCAtIDEpO1xuICAgIHBhcnRzLnZhbHVlID0gbGluZS5zdWJzdHIoY29sb24gKyAxKTtcbiAgfSBlbHNlIHtcbiAgICBwYXJ0cy5hdHRyaWJ1dGUgPSBsaW5lLnN1YnN0cihzcCArIDEpO1xuICB9XG4gIHJldHVybiBwYXJ0cztcbn07XG5cbi8vIEV4dHJhY3RzIHRoZSBNSUQgKFJGQyA1ODg4KSBmcm9tIGEgbWVkaWEgc2VjdGlvbi5cbi8vIHJldHVybnMgdGhlIE1JRCBvciB1bmRlZmluZWQgaWYgbm8gbWlkIGxpbmUgd2FzIGZvdW5kLlxuU0RQVXRpbHMuZ2V0TWlkID0gZnVuY3Rpb24obWVkaWFTZWN0aW9uKSB7XG4gIHZhciBtaWQgPSBTRFBVdGlscy5tYXRjaFByZWZpeChtZWRpYVNlY3Rpb24sICdhPW1pZDonKVswXTtcbiAgaWYgKG1pZCkge1xuICAgIHJldHVybiBtaWQuc3Vic3RyKDYpO1xuICB9XG59XG5cblNEUFV0aWxzLnBhcnNlRmluZ2VycHJpbnQgPSBmdW5jdGlvbihsaW5lKSB7XG4gIHZhciBwYXJ0cyA9IGxpbmUuc3Vic3RyKDE0KS5zcGxpdCgnICcpO1xuICByZXR1cm4ge1xuICAgIGFsZ29yaXRobTogcGFydHNbMF0udG9Mb3dlckNhc2UoKSwgLy8gYWxnb3JpdGhtIGlzIGNhc2Utc2Vuc2l0aXZlIGluIEVkZ2UuXG4gICAgdmFsdWU6IHBhcnRzWzFdXG4gIH07XG59O1xuXG4vLyBFeHRyYWN0cyBEVExTIHBhcmFtZXRlcnMgZnJvbSBTRFAgbWVkaWEgc2VjdGlvbiBvciBzZXNzaW9ucGFydC5cbi8vIEZJWE1FOiBmb3IgY29uc2lzdGVuY3kgd2l0aCBvdGhlciBmdW5jdGlvbnMgdGhpcyBzaG91bGQgb25seVxuLy8gICBnZXQgdGhlIGZpbmdlcnByaW50IGxpbmUgYXMgaW5wdXQuIFNlZSBhbHNvIGdldEljZVBhcmFtZXRlcnMuXG5TRFBVdGlscy5nZXREdGxzUGFyYW1ldGVycyA9IGZ1bmN0aW9uKG1lZGlhU2VjdGlvbiwgc2Vzc2lvbnBhcnQpIHtcbiAgdmFyIGxpbmVzID0gU0RQVXRpbHMubWF0Y2hQcmVmaXgobWVkaWFTZWN0aW9uICsgc2Vzc2lvbnBhcnQsXG4gICAgICAnYT1maW5nZXJwcmludDonKTtcbiAgLy8gTm90ZTogYT1zZXR1cCBsaW5lIGlzIGlnbm9yZWQgc2luY2Ugd2UgdXNlIHRoZSAnYXV0bycgcm9sZS5cbiAgLy8gTm90ZTI6ICdhbGdvcml0aG0nIGlzIG5vdCBjYXNlIHNlbnNpdGl2ZSBleGNlcHQgaW4gRWRnZS5cbiAgcmV0dXJuIHtcbiAgICByb2xlOiAnYXV0bycsXG4gICAgZmluZ2VycHJpbnRzOiBsaW5lcy5tYXAoU0RQVXRpbHMucGFyc2VGaW5nZXJwcmludClcbiAgfTtcbn07XG5cbi8vIFNlcmlhbGl6ZXMgRFRMUyBwYXJhbWV0ZXJzIHRvIFNEUC5cblNEUFV0aWxzLndyaXRlRHRsc1BhcmFtZXRlcnMgPSBmdW5jdGlvbihwYXJhbXMsIHNldHVwVHlwZSkge1xuICB2YXIgc2RwID0gJ2E9c2V0dXA6JyArIHNldHVwVHlwZSArICdcXHJcXG4nO1xuICBwYXJhbXMuZmluZ2VycHJpbnRzLmZvckVhY2goZnVuY3Rpb24oZnApIHtcbiAgICBzZHAgKz0gJ2E9ZmluZ2VycHJpbnQ6JyArIGZwLmFsZ29yaXRobSArICcgJyArIGZwLnZhbHVlICsgJ1xcclxcbic7XG4gIH0pO1xuICByZXR1cm4gc2RwO1xufTtcbi8vIFBhcnNlcyBJQ0UgaW5mb3JtYXRpb24gZnJvbSBTRFAgbWVkaWEgc2VjdGlvbiBvciBzZXNzaW9ucGFydC5cbi8vIEZJWE1FOiBmb3IgY29uc2lzdGVuY3kgd2l0aCBvdGhlciBmdW5jdGlvbnMgdGhpcyBzaG91bGQgb25seVxuLy8gICBnZXQgdGhlIGljZS11ZnJhZyBhbmQgaWNlLXB3ZCBsaW5lcyBhcyBpbnB1dC5cblNEUFV0aWxzLmdldEljZVBhcmFtZXRlcnMgPSBmdW5jdGlvbihtZWRpYVNlY3Rpb24sIHNlc3Npb25wYXJ0KSB7XG4gIHZhciBsaW5lcyA9IFNEUFV0aWxzLnNwbGl0TGluZXMobWVkaWFTZWN0aW9uKTtcbiAgLy8gU2VhcmNoIGluIHNlc3Npb24gcGFydCwgdG9vLlxuICBsaW5lcyA9IGxpbmVzLmNvbmNhdChTRFBVdGlscy5zcGxpdExpbmVzKHNlc3Npb25wYXJ0KSk7XG4gIHZhciBpY2VQYXJhbWV0ZXJzID0ge1xuICAgIHVzZXJuYW1lRnJhZ21lbnQ6IGxpbmVzLmZpbHRlcihmdW5jdGlvbihsaW5lKSB7XG4gICAgICByZXR1cm4gbGluZS5pbmRleE9mKCdhPWljZS11ZnJhZzonKSA9PT0gMDtcbiAgICB9KVswXS5zdWJzdHIoMTIpLFxuICAgIHBhc3N3b3JkOiBsaW5lcy5maWx0ZXIoZnVuY3Rpb24obGluZSkge1xuICAgICAgcmV0dXJuIGxpbmUuaW5kZXhPZignYT1pY2UtcHdkOicpID09PSAwO1xuICAgIH0pWzBdLnN1YnN0cigxMClcbiAgfTtcbiAgcmV0dXJuIGljZVBhcmFtZXRlcnM7XG59O1xuXG4vLyBTZXJpYWxpemVzIElDRSBwYXJhbWV0ZXJzIHRvIFNEUC5cblNEUFV0aWxzLndyaXRlSWNlUGFyYW1ldGVycyA9IGZ1bmN0aW9uKHBhcmFtcykge1xuICByZXR1cm4gJ2E9aWNlLXVmcmFnOicgKyBwYXJhbXMudXNlcm5hbWVGcmFnbWVudCArICdcXHJcXG4nICtcbiAgICAgICdhPWljZS1wd2Q6JyArIHBhcmFtcy5wYXNzd29yZCArICdcXHJcXG4nO1xufTtcblxuLy8gUGFyc2VzIHRoZSBTRFAgbWVkaWEgc2VjdGlvbiBhbmQgcmV0dXJucyBSVENSdHBQYXJhbWV0ZXJzLlxuU0RQVXRpbHMucGFyc2VSdHBQYXJhbWV0ZXJzID0gZnVuY3Rpb24obWVkaWFTZWN0aW9uKSB7XG4gIHZhciBkZXNjcmlwdGlvbiA9IHtcbiAgICBjb2RlY3M6IFtdLFxuICAgIGhlYWRlckV4dGVuc2lvbnM6IFtdLFxuICAgIGZlY01lY2hhbmlzbXM6IFtdLFxuICAgIHJ0Y3A6IFtdXG4gIH07XG4gIHZhciBsaW5lcyA9IFNEUFV0aWxzLnNwbGl0TGluZXMobWVkaWFTZWN0aW9uKTtcbiAgdmFyIG1saW5lID0gbGluZXNbMF0uc3BsaXQoJyAnKTtcbiAgZm9yICh2YXIgaSA9IDM7IGkgPCBtbGluZS5sZW5ndGg7IGkrKykgeyAvLyBmaW5kIGFsbCBjb2RlY3MgZnJvbSBtbGluZVszLi5dXG4gICAgdmFyIHB0ID0gbWxpbmVbaV07XG4gICAgdmFyIHJ0cG1hcGxpbmUgPSBTRFBVdGlscy5tYXRjaFByZWZpeChcbiAgICAgICAgbWVkaWFTZWN0aW9uLCAnYT1ydHBtYXA6JyArIHB0ICsgJyAnKVswXTtcbiAgICBpZiAocnRwbWFwbGluZSkge1xuICAgICAgdmFyIGNvZGVjID0gU0RQVXRpbHMucGFyc2VSdHBNYXAocnRwbWFwbGluZSk7XG4gICAgICB2YXIgZm10cHMgPSBTRFBVdGlscy5tYXRjaFByZWZpeChcbiAgICAgICAgICBtZWRpYVNlY3Rpb24sICdhPWZtdHA6JyArIHB0ICsgJyAnKTtcbiAgICAgIC8vIE9ubHkgdGhlIGZpcnN0IGE9Zm10cDo8cHQ+IGlzIGNvbnNpZGVyZWQuXG4gICAgICBjb2RlYy5wYXJhbWV0ZXJzID0gZm10cHMubGVuZ3RoID8gU0RQVXRpbHMucGFyc2VGbXRwKGZtdHBzWzBdKSA6IHt9O1xuICAgICAgY29kZWMucnRjcEZlZWRiYWNrID0gU0RQVXRpbHMubWF0Y2hQcmVmaXgoXG4gICAgICAgICAgbWVkaWFTZWN0aW9uLCAnYT1ydGNwLWZiOicgKyBwdCArICcgJylcbiAgICAgICAgLm1hcChTRFBVdGlscy5wYXJzZVJ0Y3BGYik7XG4gICAgICBkZXNjcmlwdGlvbi5jb2RlY3MucHVzaChjb2RlYyk7XG4gICAgICAvLyBwYXJzZSBGRUMgbWVjaGFuaXNtcyBmcm9tIHJ0cG1hcCBsaW5lcy5cbiAgICAgIHN3aXRjaCAoY29kZWMubmFtZS50b1VwcGVyQ2FzZSgpKSB7XG4gICAgICAgIGNhc2UgJ1JFRCc6XG4gICAgICAgIGNhc2UgJ1VMUEZFQyc6XG4gICAgICAgICAgZGVzY3JpcHRpb24uZmVjTWVjaGFuaXNtcy5wdXNoKGNvZGVjLm5hbWUudG9VcHBlckNhc2UoKSk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGRlZmF1bHQ6IC8vIG9ubHkgUkVEIGFuZCBVTFBGRUMgYXJlIHJlY29nbml6ZWQgYXMgRkVDIG1lY2hhbmlzbXMuXG4gICAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIFNEUFV0aWxzLm1hdGNoUHJlZml4KG1lZGlhU2VjdGlvbiwgJ2E9ZXh0bWFwOicpLmZvckVhY2goZnVuY3Rpb24obGluZSkge1xuICAgIGRlc2NyaXB0aW9uLmhlYWRlckV4dGVuc2lvbnMucHVzaChTRFBVdGlscy5wYXJzZUV4dG1hcChsaW5lKSk7XG4gIH0pO1xuICAvLyBGSVhNRTogcGFyc2UgcnRjcC5cbiAgcmV0dXJuIGRlc2NyaXB0aW9uO1xufTtcblxuLy8gR2VuZXJhdGVzIHBhcnRzIG9mIHRoZSBTRFAgbWVkaWEgc2VjdGlvbiBkZXNjcmliaW5nIHRoZSBjYXBhYmlsaXRpZXMgL1xuLy8gcGFyYW1ldGVycy5cblNEUFV0aWxzLndyaXRlUnRwRGVzY3JpcHRpb24gPSBmdW5jdGlvbihraW5kLCBjYXBzKSB7XG4gIHZhciBzZHAgPSAnJztcblxuICAvLyBCdWlsZCB0aGUgbWxpbmUuXG4gIHNkcCArPSAnbT0nICsga2luZCArICcgJztcbiAgc2RwICs9IGNhcHMuY29kZWNzLmxlbmd0aCA+IDAgPyAnOScgOiAnMCc7IC8vIHJlamVjdCBpZiBubyBjb2RlY3MuXG4gIHNkcCArPSAnIFVEUC9UTFMvUlRQL1NBVlBGICc7XG4gIHNkcCArPSBjYXBzLmNvZGVjcy5tYXAoZnVuY3Rpb24oY29kZWMpIHtcbiAgICBpZiAoY29kZWMucHJlZmVycmVkUGF5bG9hZFR5cGUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuIGNvZGVjLnByZWZlcnJlZFBheWxvYWRUeXBlO1xuICAgIH1cbiAgICByZXR1cm4gY29kZWMucGF5bG9hZFR5cGU7XG4gIH0pLmpvaW4oJyAnKSArICdcXHJcXG4nO1xuXG4gIHNkcCArPSAnYz1JTiBJUDQgMC4wLjAuMFxcclxcbic7XG4gIHNkcCArPSAnYT1ydGNwOjkgSU4gSVA0IDAuMC4wLjBcXHJcXG4nO1xuXG4gIC8vIEFkZCBhPXJ0cG1hcCBsaW5lcyBmb3IgZWFjaCBjb2RlYy4gQWxzbyBmbXRwIGFuZCBydGNwLWZiLlxuICBjYXBzLmNvZGVjcy5mb3JFYWNoKGZ1bmN0aW9uKGNvZGVjKSB7XG4gICAgc2RwICs9IFNEUFV0aWxzLndyaXRlUnRwTWFwKGNvZGVjKTtcbiAgICBzZHAgKz0gU0RQVXRpbHMud3JpdGVGbXRwKGNvZGVjKTtcbiAgICBzZHAgKz0gU0RQVXRpbHMud3JpdGVSdGNwRmIoY29kZWMpO1xuICB9KTtcbiAgdmFyIG1heHB0aW1lID0gMDtcbiAgY2Fwcy5jb2RlY3MuZm9yRWFjaChmdW5jdGlvbihjb2RlYykge1xuICAgIGlmIChjb2RlYy5tYXhwdGltZSA+IG1heHB0aW1lKSB7XG4gICAgICBtYXhwdGltZSA9IGNvZGVjLm1heHB0aW1lO1xuICAgIH1cbiAgfSk7XG4gIGlmIChtYXhwdGltZSA+IDApIHtcbiAgICBzZHAgKz0gJ2E9bWF4cHRpbWU6JyArIG1heHB0aW1lICsgJ1xcclxcbic7XG4gIH1cbiAgc2RwICs9ICdhPXJ0Y3AtbXV4XFxyXFxuJztcblxuICBjYXBzLmhlYWRlckV4dGVuc2lvbnMuZm9yRWFjaChmdW5jdGlvbihleHRlbnNpb24pIHtcbiAgICBzZHAgKz0gU0RQVXRpbHMud3JpdGVFeHRtYXAoZXh0ZW5zaW9uKTtcbiAgfSk7XG4gIC8vIEZJWE1FOiB3cml0ZSBmZWNNZWNoYW5pc21zLlxuICByZXR1cm4gc2RwO1xufTtcblxuLy8gUGFyc2VzIHRoZSBTRFAgbWVkaWEgc2VjdGlvbiBhbmQgcmV0dXJucyBhbiBhcnJheSBvZlxuLy8gUlRDUnRwRW5jb2RpbmdQYXJhbWV0ZXJzLlxuU0RQVXRpbHMucGFyc2VSdHBFbmNvZGluZ1BhcmFtZXRlcnMgPSBmdW5jdGlvbihtZWRpYVNlY3Rpb24pIHtcbiAgdmFyIGVuY29kaW5nUGFyYW1ldGVycyA9IFtdO1xuICB2YXIgZGVzY3JpcHRpb24gPSBTRFBVdGlscy5wYXJzZVJ0cFBhcmFtZXRlcnMobWVkaWFTZWN0aW9uKTtcbiAgdmFyIGhhc1JlZCA9IGRlc2NyaXB0aW9uLmZlY01lY2hhbmlzbXMuaW5kZXhPZignUkVEJykgIT09IC0xO1xuICB2YXIgaGFzVWxwZmVjID0gZGVzY3JpcHRpb24uZmVjTWVjaGFuaXNtcy5pbmRleE9mKCdVTFBGRUMnKSAhPT0gLTE7XG5cbiAgLy8gZmlsdGVyIGE9c3NyYzouLi4gY25hbWU6LCBpZ25vcmUgUGxhbkItbXNpZFxuICB2YXIgc3NyY3MgPSBTRFBVdGlscy5tYXRjaFByZWZpeChtZWRpYVNlY3Rpb24sICdhPXNzcmM6JylcbiAgLm1hcChmdW5jdGlvbihsaW5lKSB7XG4gICAgcmV0dXJuIFNEUFV0aWxzLnBhcnNlU3NyY01lZGlhKGxpbmUpO1xuICB9KVxuICAuZmlsdGVyKGZ1bmN0aW9uKHBhcnRzKSB7XG4gICAgcmV0dXJuIHBhcnRzLmF0dHJpYnV0ZSA9PT0gJ2NuYW1lJztcbiAgfSk7XG4gIHZhciBwcmltYXJ5U3NyYyA9IHNzcmNzLmxlbmd0aCA+IDAgJiYgc3NyY3NbMF0uc3NyYztcbiAgdmFyIHNlY29uZGFyeVNzcmM7XG5cbiAgdmFyIGZsb3dzID0gU0RQVXRpbHMubWF0Y2hQcmVmaXgobWVkaWFTZWN0aW9uLCAnYT1zc3JjLWdyb3VwOkZJRCcpXG4gIC5tYXAoZnVuY3Rpb24obGluZSkge1xuICAgIHZhciBwYXJ0cyA9IGxpbmUuc3BsaXQoJyAnKTtcbiAgICBwYXJ0cy5zaGlmdCgpO1xuICAgIHJldHVybiBwYXJ0cy5tYXAoZnVuY3Rpb24ocGFydCkge1xuICAgICAgcmV0dXJuIHBhcnNlSW50KHBhcnQsIDEwKTtcbiAgICB9KTtcbiAgfSk7XG4gIGlmIChmbG93cy5sZW5ndGggPiAwICYmIGZsb3dzWzBdLmxlbmd0aCA+IDEgJiYgZmxvd3NbMF1bMF0gPT09IHByaW1hcnlTc3JjKSB7XG4gICAgc2Vjb25kYXJ5U3NyYyA9IGZsb3dzWzBdWzFdO1xuICB9XG5cbiAgZGVzY3JpcHRpb24uY29kZWNzLmZvckVhY2goZnVuY3Rpb24oY29kZWMpIHtcbiAgICBpZiAoY29kZWMubmFtZS50b1VwcGVyQ2FzZSgpID09PSAnUlRYJyAmJiBjb2RlYy5wYXJhbWV0ZXJzLmFwdCkge1xuICAgICAgdmFyIGVuY1BhcmFtID0ge1xuICAgICAgICBzc3JjOiBwcmltYXJ5U3NyYyxcbiAgICAgICAgY29kZWNQYXlsb2FkVHlwZTogcGFyc2VJbnQoY29kZWMucGFyYW1ldGVycy5hcHQsIDEwKSxcbiAgICAgICAgcnR4OiB7XG4gICAgICAgICAgc3NyYzogc2Vjb25kYXJ5U3NyY1xuICAgICAgICB9XG4gICAgICB9O1xuICAgICAgZW5jb2RpbmdQYXJhbWV0ZXJzLnB1c2goZW5jUGFyYW0pO1xuICAgICAgaWYgKGhhc1JlZCkge1xuICAgICAgICBlbmNQYXJhbSA9IEpTT04ucGFyc2UoSlNPTi5zdHJpbmdpZnkoZW5jUGFyYW0pKTtcbiAgICAgICAgZW5jUGFyYW0uZmVjID0ge1xuICAgICAgICAgIHNzcmM6IHNlY29uZGFyeVNzcmMsXG4gICAgICAgICAgbWVjaGFuaXNtOiBoYXNVbHBmZWMgPyAncmVkK3VscGZlYycgOiAncmVkJ1xuICAgICAgICB9O1xuICAgICAgICBlbmNvZGluZ1BhcmFtZXRlcnMucHVzaChlbmNQYXJhbSk7XG4gICAgICB9XG4gICAgfVxuICB9KTtcbiAgaWYgKGVuY29kaW5nUGFyYW1ldGVycy5sZW5ndGggPT09IDAgJiYgcHJpbWFyeVNzcmMpIHtcbiAgICBlbmNvZGluZ1BhcmFtZXRlcnMucHVzaCh7XG4gICAgICBzc3JjOiBwcmltYXJ5U3NyY1xuICAgIH0pO1xuICB9XG5cbiAgLy8gd2Ugc3VwcG9ydCBib3RoIGI9QVMgYW5kIGI9VElBUyBidXQgaW50ZXJwcmV0IEFTIGFzIFRJQVMuXG4gIHZhciBiYW5kd2lkdGggPSBTRFBVdGlscy5tYXRjaFByZWZpeChtZWRpYVNlY3Rpb24sICdiPScpO1xuICBpZiAoYmFuZHdpZHRoLmxlbmd0aCkge1xuICAgIGlmIChiYW5kd2lkdGhbMF0uaW5kZXhPZignYj1USUFTOicpID09PSAwKSB7XG4gICAgICBiYW5kd2lkdGggPSBwYXJzZUludChiYW5kd2lkdGhbMF0uc3Vic3RyKDcpLCAxMCk7XG4gICAgfSBlbHNlIGlmIChiYW5kd2lkdGhbMF0uaW5kZXhPZignYj1BUzonKSA9PT0gMCkge1xuICAgICAgYmFuZHdpZHRoID0gcGFyc2VJbnQoYmFuZHdpZHRoWzBdLnN1YnN0cig1KSwgMTApO1xuICAgIH1cbiAgICBlbmNvZGluZ1BhcmFtZXRlcnMuZm9yRWFjaChmdW5jdGlvbihwYXJhbXMpIHtcbiAgICAgIHBhcmFtcy5tYXhCaXRyYXRlID0gYmFuZHdpZHRoO1xuICAgIH0pO1xuICB9XG4gIHJldHVybiBlbmNvZGluZ1BhcmFtZXRlcnM7XG59O1xuXG4vLyBwYXJzZXMgaHR0cDovL2RyYWZ0Lm9ydGMub3JnLyNydGNydGNwcGFyYW1ldGVycypcblNEUFV0aWxzLnBhcnNlUnRjcFBhcmFtZXRlcnMgPSBmdW5jdGlvbihtZWRpYVNlY3Rpb24pIHtcbiAgdmFyIHJ0Y3BQYXJhbWV0ZXJzID0ge307XG5cbiAgdmFyIGNuYW1lO1xuICAvLyBHZXRzIHRoZSBmaXJzdCBTU1JDLiBOb3RlIHRoYXQgd2l0aCBSVFggdGhlcmUgbWlnaHQgYmUgbXVsdGlwbGVcbiAgLy8gU1NSQ3MuXG4gIHZhciByZW1vdGVTc3JjID0gU0RQVXRpbHMubWF0Y2hQcmVmaXgobWVkaWFTZWN0aW9uLCAnYT1zc3JjOicpXG4gICAgICAubWFwKGZ1bmN0aW9uKGxpbmUpIHtcbiAgICAgICAgcmV0dXJuIFNEUFV0aWxzLnBhcnNlU3NyY01lZGlhKGxpbmUpO1xuICAgICAgfSlcbiAgICAgIC5maWx0ZXIoZnVuY3Rpb24ob2JqKSB7XG4gICAgICAgIHJldHVybiBvYmouYXR0cmlidXRlID09PSAnY25hbWUnO1xuICAgICAgfSlbMF07XG4gIGlmIChyZW1vdGVTc3JjKSB7XG4gICAgcnRjcFBhcmFtZXRlcnMuY25hbWUgPSByZW1vdGVTc3JjLnZhbHVlO1xuICAgIHJ0Y3BQYXJhbWV0ZXJzLnNzcmMgPSByZW1vdGVTc3JjLnNzcmM7XG4gIH1cblxuICAvLyBFZGdlIHVzZXMgdGhlIGNvbXBvdW5kIGF0dHJpYnV0ZSBpbnN0ZWFkIG9mIHJlZHVjZWRTaXplXG4gIC8vIGNvbXBvdW5kIGlzICFyZWR1Y2VkU2l6ZVxuICB2YXIgcnNpemUgPSBTRFBVdGlscy5tYXRjaFByZWZpeChtZWRpYVNlY3Rpb24sICdhPXJ0Y3AtcnNpemUnKTtcbiAgcnRjcFBhcmFtZXRlcnMucmVkdWNlZFNpemUgPSByc2l6ZS5sZW5ndGggPiAwO1xuICBydGNwUGFyYW1ldGVycy5jb21wb3VuZCA9IHJzaXplLmxlbmd0aCA9PT0gMDtcblxuICAvLyBwYXJzZXMgdGhlIHJ0Y3AtbXV4IGF0dHLRlmJ1dGUuXG4gIC8vIE5vdGUgdGhhdCBFZGdlIGRvZXMgbm90IHN1cHBvcnQgdW5tdXhlZCBSVENQLlxuICB2YXIgbXV4ID0gU0RQVXRpbHMubWF0Y2hQcmVmaXgobWVkaWFTZWN0aW9uLCAnYT1ydGNwLW11eCcpO1xuICBydGNwUGFyYW1ldGVycy5tdXggPSBtdXgubGVuZ3RoID4gMDtcblxuICByZXR1cm4gcnRjcFBhcmFtZXRlcnM7XG59O1xuXG4vLyBwYXJzZXMgZWl0aGVyIGE9bXNpZDogb3IgYT1zc3JjOi4uLiBtc2lkIGxpbmVzIGFuZCByZXR1cm5zXG4vLyB0aGUgaWQgb2YgdGhlIE1lZGlhU3RyZWFtIGFuZCBNZWRpYVN0cmVhbVRyYWNrLlxuU0RQVXRpbHMucGFyc2VNc2lkID0gZnVuY3Rpb24obWVkaWFTZWN0aW9uKSB7XG4gIHZhciBwYXJ0cztcbiAgdmFyIHNwZWMgPSBTRFBVdGlscy5tYXRjaFByZWZpeChtZWRpYVNlY3Rpb24sICdhPW1zaWQ6Jyk7XG4gIGlmIChzcGVjLmxlbmd0aCA9PT0gMSkge1xuICAgIHBhcnRzID0gc3BlY1swXS5zdWJzdHIoNykuc3BsaXQoJyAnKTtcbiAgICByZXR1cm4ge3N0cmVhbTogcGFydHNbMF0sIHRyYWNrOiBwYXJ0c1sxXX07XG4gIH1cbiAgdmFyIHBsYW5CID0gU0RQVXRpbHMubWF0Y2hQcmVmaXgobWVkaWFTZWN0aW9uLCAnYT1zc3JjOicpXG4gIC5tYXAoZnVuY3Rpb24obGluZSkge1xuICAgIHJldHVybiBTRFBVdGlscy5wYXJzZVNzcmNNZWRpYShsaW5lKTtcbiAgfSlcbiAgLmZpbHRlcihmdW5jdGlvbihwYXJ0cykge1xuICAgIHJldHVybiBwYXJ0cy5hdHRyaWJ1dGUgPT09ICdtc2lkJztcbiAgfSk7XG4gIGlmIChwbGFuQi5sZW5ndGggPiAwKSB7XG4gICAgcGFydHMgPSBwbGFuQlswXS52YWx1ZS5zcGxpdCgnICcpO1xuICAgIHJldHVybiB7c3RyZWFtOiBwYXJ0c1swXSwgdHJhY2s6IHBhcnRzWzFdfTtcbiAgfVxufTtcblxuU0RQVXRpbHMud3JpdGVTZXNzaW9uQm9pbGVycGxhdGUgPSBmdW5jdGlvbigpIHtcbiAgLy8gRklYTUU6IHNlc3MtaWQgc2hvdWxkIGJlIGFuIE5UUCB0aW1lc3RhbXAuXG4gIHJldHVybiAndj0wXFxyXFxuJyArXG4gICAgICAnbz10aGlzaXNhZGFwdGVyb3J0YyA4MTY5NjM5OTE1NjQ2OTQzMTM3IDIgSU4gSVA0IDEyNy4wLjAuMVxcclxcbicgK1xuICAgICAgJ3M9LVxcclxcbicgK1xuICAgICAgJ3Q9MCAwXFxyXFxuJztcbn07XG5cblNEUFV0aWxzLndyaXRlTWVkaWFTZWN0aW9uID0gZnVuY3Rpb24odHJhbnNjZWl2ZXIsIGNhcHMsIHR5cGUsIHN0cmVhbSkge1xuICB2YXIgc2RwID0gU0RQVXRpbHMud3JpdGVSdHBEZXNjcmlwdGlvbih0cmFuc2NlaXZlci5raW5kLCBjYXBzKTtcblxuICAvLyBNYXAgSUNFIHBhcmFtZXRlcnMgKHVmcmFnLCBwd2QpIHRvIFNEUC5cbiAgc2RwICs9IFNEUFV0aWxzLndyaXRlSWNlUGFyYW1ldGVycyhcbiAgICAgIHRyYW5zY2VpdmVyLmljZUdhdGhlcmVyLmdldExvY2FsUGFyYW1ldGVycygpKTtcblxuICAvLyBNYXAgRFRMUyBwYXJhbWV0ZXJzIHRvIFNEUC5cbiAgc2RwICs9IFNEUFV0aWxzLndyaXRlRHRsc1BhcmFtZXRlcnMoXG4gICAgICB0cmFuc2NlaXZlci5kdGxzVHJhbnNwb3J0LmdldExvY2FsUGFyYW1ldGVycygpLFxuICAgICAgdHlwZSA9PT0gJ29mZmVyJyA/ICdhY3RwYXNzJyA6ICdhY3RpdmUnKTtcblxuICBzZHAgKz0gJ2E9bWlkOicgKyB0cmFuc2NlaXZlci5taWQgKyAnXFxyXFxuJztcblxuICBpZiAodHJhbnNjZWl2ZXIuZGlyZWN0aW9uKSB7XG4gICAgc2RwICs9ICdhPScgKyB0cmFuc2NlaXZlci5kaXJlY3Rpb24gKyAnXFxyXFxuJztcbiAgfSBlbHNlIGlmICh0cmFuc2NlaXZlci5ydHBTZW5kZXIgJiYgdHJhbnNjZWl2ZXIucnRwUmVjZWl2ZXIpIHtcbiAgICBzZHAgKz0gJ2E9c2VuZHJlY3ZcXHJcXG4nO1xuICB9IGVsc2UgaWYgKHRyYW5zY2VpdmVyLnJ0cFNlbmRlcikge1xuICAgIHNkcCArPSAnYT1zZW5kb25seVxcclxcbic7XG4gIH0gZWxzZSBpZiAodHJhbnNjZWl2ZXIucnRwUmVjZWl2ZXIpIHtcbiAgICBzZHAgKz0gJ2E9cmVjdm9ubHlcXHJcXG4nO1xuICB9IGVsc2Uge1xuICAgIHNkcCArPSAnYT1pbmFjdGl2ZVxcclxcbic7XG4gIH1cblxuICBpZiAodHJhbnNjZWl2ZXIucnRwU2VuZGVyKSB7XG4gICAgLy8gc3BlYy5cbiAgICB2YXIgbXNpZCA9ICdtc2lkOicgKyBzdHJlYW0uaWQgKyAnICcgK1xuICAgICAgICB0cmFuc2NlaXZlci5ydHBTZW5kZXIudHJhY2suaWQgKyAnXFxyXFxuJztcbiAgICBzZHAgKz0gJ2E9JyArIG1zaWQ7XG5cbiAgICAvLyBmb3IgQ2hyb21lLlxuICAgIHNkcCArPSAnYT1zc3JjOicgKyB0cmFuc2NlaXZlci5zZW5kRW5jb2RpbmdQYXJhbWV0ZXJzWzBdLnNzcmMgK1xuICAgICAgICAnICcgKyBtc2lkO1xuICAgIGlmICh0cmFuc2NlaXZlci5zZW5kRW5jb2RpbmdQYXJhbWV0ZXJzWzBdLnJ0eCkge1xuICAgICAgc2RwICs9ICdhPXNzcmM6JyArIHRyYW5zY2VpdmVyLnNlbmRFbmNvZGluZ1BhcmFtZXRlcnNbMF0ucnR4LnNzcmMgK1xuICAgICAgICAgICcgJyArIG1zaWQ7XG4gICAgICBzZHAgKz0gJ2E9c3NyYy1ncm91cDpGSUQgJyArXG4gICAgICAgICAgdHJhbnNjZWl2ZXIuc2VuZEVuY29kaW5nUGFyYW1ldGVyc1swXS5zc3JjICsgJyAnICtcbiAgICAgICAgICB0cmFuc2NlaXZlci5zZW5kRW5jb2RpbmdQYXJhbWV0ZXJzWzBdLnJ0eC5zc3JjICtcbiAgICAgICAgICAnXFxyXFxuJztcbiAgICB9XG4gIH1cbiAgLy8gRklYTUU6IHRoaXMgc2hvdWxkIGJlIHdyaXR0ZW4gYnkgd3JpdGVSdHBEZXNjcmlwdGlvbi5cbiAgc2RwICs9ICdhPXNzcmM6JyArIHRyYW5zY2VpdmVyLnNlbmRFbmNvZGluZ1BhcmFtZXRlcnNbMF0uc3NyYyArXG4gICAgICAnIGNuYW1lOicgKyBTRFBVdGlscy5sb2NhbENOYW1lICsgJ1xcclxcbic7XG4gIGlmICh0cmFuc2NlaXZlci5ydHBTZW5kZXIgJiYgdHJhbnNjZWl2ZXIuc2VuZEVuY29kaW5nUGFyYW1ldGVyc1swXS5ydHgpIHtcbiAgICBzZHAgKz0gJ2E9c3NyYzonICsgdHJhbnNjZWl2ZXIuc2VuZEVuY29kaW5nUGFyYW1ldGVyc1swXS5ydHguc3NyYyArXG4gICAgICAgICcgY25hbWU6JyArIFNEUFV0aWxzLmxvY2FsQ05hbWUgKyAnXFxyXFxuJztcbiAgfVxuICByZXR1cm4gc2RwO1xufTtcblxuLy8gR2V0cyB0aGUgZGlyZWN0aW9uIGZyb20gdGhlIG1lZGlhU2VjdGlvbiBvciB0aGUgc2Vzc2lvbnBhcnQuXG5TRFBVdGlscy5nZXREaXJlY3Rpb24gPSBmdW5jdGlvbihtZWRpYVNlY3Rpb24sIHNlc3Npb25wYXJ0KSB7XG4gIC8vIExvb2sgZm9yIHNlbmRyZWN2LCBzZW5kb25seSwgcmVjdm9ubHksIGluYWN0aXZlLCBkZWZhdWx0IHRvIHNlbmRyZWN2LlxuICB2YXIgbGluZXMgPSBTRFBVdGlscy5zcGxpdExpbmVzKG1lZGlhU2VjdGlvbik7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGluZXMubGVuZ3RoOyBpKyspIHtcbiAgICBzd2l0Y2ggKGxpbmVzW2ldKSB7XG4gICAgICBjYXNlICdhPXNlbmRyZWN2JzpcbiAgICAgIGNhc2UgJ2E9c2VuZG9ubHknOlxuICAgICAgY2FzZSAnYT1yZWN2b25seSc6XG4gICAgICBjYXNlICdhPWluYWN0aXZlJzpcbiAgICAgICAgcmV0dXJuIGxpbmVzW2ldLnN1YnN0cigyKTtcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIC8vIEZJWE1FOiBXaGF0IHNob3VsZCBoYXBwZW4gaGVyZT9cbiAgICB9XG4gIH1cbiAgaWYgKHNlc3Npb25wYXJ0KSB7XG4gICAgcmV0dXJuIFNEUFV0aWxzLmdldERpcmVjdGlvbihzZXNzaW9ucGFydCk7XG4gIH1cbiAgcmV0dXJuICdzZW5kcmVjdic7XG59O1xuXG5TRFBVdGlscy5nZXRLaW5kID0gZnVuY3Rpb24obWVkaWFTZWN0aW9uKSB7XG4gIHZhciBsaW5lcyA9IFNEUFV0aWxzLnNwbGl0TGluZXMobWVkaWFTZWN0aW9uKTtcbiAgdmFyIG1saW5lID0gbGluZXNbMF0uc3BsaXQoJyAnKTtcbiAgcmV0dXJuIG1saW5lWzBdLnN1YnN0cigyKTtcbn07XG5cblNEUFV0aWxzLmlzUmVqZWN0ZWQgPSBmdW5jdGlvbihtZWRpYVNlY3Rpb24pIHtcbiAgcmV0dXJuIG1lZGlhU2VjdGlvbi5zcGxpdCgnICcsIDIpWzFdID09PSAnMCc7XG59O1xuXG4vLyBFeHBvc2UgcHVibGljIG1ldGhvZHMuXG5tb2R1bGUuZXhwb3J0cyA9IFNEUFV0aWxzO1xuIiwiLyoqXG4gKiBVQVBhcnNlci5qcyB2MC43LjE0XG4gKiBMaWdodHdlaWdodCBKYXZhU2NyaXB0LWJhc2VkIFVzZXItQWdlbnQgc3RyaW5nIHBhcnNlclxuICogaHR0cHM6Ly9naXRodWIuY29tL2ZhaXNhbG1hbi91YS1wYXJzZXItanNcbiAqXG4gKiBDb3B5cmlnaHQgwqkgMjAxMi0yMDE2IEZhaXNhbCBTYWxtYW4gPGZ5emxtYW5AZ21haWwuY29tPlxuICogRHVhbCBsaWNlbnNlZCB1bmRlciBHUEx2MiAmIE1JVFxuICovXG5cbihmdW5jdGlvbiAod2luZG93LCB1bmRlZmluZWQpIHtcblxuICAgICd1c2Ugc3RyaWN0JztcblxuICAgIC8vLy8vLy8vLy8vLy8vXG4gICAgLy8gQ29uc3RhbnRzXG4gICAgLy8vLy8vLy8vLy8vL1xuXG5cbiAgICB2YXIgTElCVkVSU0lPTiAgPSAnMC43LjE0JyxcbiAgICAgICAgRU1QVFkgICAgICAgPSAnJyxcbiAgICAgICAgVU5LTk9XTiAgICAgPSAnPycsXG4gICAgICAgIEZVTkNfVFlQRSAgID0gJ2Z1bmN0aW9uJyxcbiAgICAgICAgVU5ERUZfVFlQRSAgPSAndW5kZWZpbmVkJyxcbiAgICAgICAgT0JKX1RZUEUgICAgPSAnb2JqZWN0JyxcbiAgICAgICAgU1RSX1RZUEUgICAgPSAnc3RyaW5nJyxcbiAgICAgICAgTUFKT1IgICAgICAgPSAnbWFqb3InLCAvLyBkZXByZWNhdGVkXG4gICAgICAgIE1PREVMICAgICAgID0gJ21vZGVsJyxcbiAgICAgICAgTkFNRSAgICAgICAgPSAnbmFtZScsXG4gICAgICAgIFRZUEUgICAgICAgID0gJ3R5cGUnLFxuICAgICAgICBWRU5ET1IgICAgICA9ICd2ZW5kb3InLFxuICAgICAgICBWRVJTSU9OICAgICA9ICd2ZXJzaW9uJyxcbiAgICAgICAgQVJDSElURUNUVVJFPSAnYXJjaGl0ZWN0dXJlJyxcbiAgICAgICAgQ09OU09MRSAgICAgPSAnY29uc29sZScsXG4gICAgICAgIE1PQklMRSAgICAgID0gJ21vYmlsZScsXG4gICAgICAgIFRBQkxFVCAgICAgID0gJ3RhYmxldCcsXG4gICAgICAgIFNNQVJUVFYgICAgID0gJ3NtYXJ0dHYnLFxuICAgICAgICBXRUFSQUJMRSAgICA9ICd3ZWFyYWJsZScsXG4gICAgICAgIEVNQkVEREVEICAgID0gJ2VtYmVkZGVkJztcblxuXG4gICAgLy8vLy8vLy8vLy9cbiAgICAvLyBIZWxwZXJcbiAgICAvLy8vLy8vLy8vXG5cblxuICAgIHZhciB1dGlsID0ge1xuICAgICAgICBleHRlbmQgOiBmdW5jdGlvbiAocmVnZXhlcywgZXh0ZW5zaW9ucykge1xuICAgICAgICAgICAgdmFyIG1hcmdlZFJlZ2V4ZXMgPSB7fTtcbiAgICAgICAgICAgIGZvciAodmFyIGkgaW4gcmVnZXhlcykge1xuICAgICAgICAgICAgICAgIGlmIChleHRlbnNpb25zW2ldICYmIGV4dGVuc2lvbnNbaV0ubGVuZ3RoICUgMiA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICBtYXJnZWRSZWdleGVzW2ldID0gZXh0ZW5zaW9uc1tpXS5jb25jYXQocmVnZXhlc1tpXSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgbWFyZ2VkUmVnZXhlc1tpXSA9IHJlZ2V4ZXNbaV07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIG1hcmdlZFJlZ2V4ZXM7XG4gICAgICAgIH0sXG4gICAgICAgIGhhcyA6IGZ1bmN0aW9uIChzdHIxLCBzdHIyKSB7XG4gICAgICAgICAgaWYgKHR5cGVvZiBzdHIxID09PSBcInN0cmluZ1wiKSB7XG4gICAgICAgICAgICByZXR1cm4gc3RyMi50b0xvd2VyQ2FzZSgpLmluZGV4T2Yoc3RyMS50b0xvd2VyQ2FzZSgpKSAhPT0gLTE7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIGxvd2VyaXplIDogZnVuY3Rpb24gKHN0cikge1xuICAgICAgICAgICAgcmV0dXJuIHN0ci50b0xvd2VyQ2FzZSgpO1xuICAgICAgICB9LFxuICAgICAgICBtYWpvciA6IGZ1bmN0aW9uICh2ZXJzaW9uKSB7XG4gICAgICAgICAgICByZXR1cm4gdHlwZW9mKHZlcnNpb24pID09PSBTVFJfVFlQRSA/IHZlcnNpb24ucmVwbGFjZSgvW15cXGRcXC5dL2csJycpLnNwbGl0KFwiLlwiKVswXSA6IHVuZGVmaW5lZDtcbiAgICAgICAgfSxcbiAgICAgICAgdHJpbSA6IGZ1bmN0aW9uIChzdHIpIHtcbiAgICAgICAgICByZXR1cm4gc3RyLnJlcGxhY2UoL15bXFxzXFx1RkVGRlxceEEwXSt8W1xcc1xcdUZFRkZcXHhBMF0rJC9nLCAnJyk7XG4gICAgICAgIH1cbiAgICB9O1xuXG5cbiAgICAvLy8vLy8vLy8vLy8vLy9cbiAgICAvLyBNYXAgaGVscGVyXG4gICAgLy8vLy8vLy8vLy8vLy9cblxuXG4gICAgdmFyIG1hcHBlciA9IHtcblxuICAgICAgICByZ3ggOiBmdW5jdGlvbiAodWEsIGFycmF5cykge1xuXG4gICAgICAgICAgICAvL3ZhciByZXN1bHQgPSB7fSxcbiAgICAgICAgICAgIHZhciBpID0gMCwgaiwgaywgcCwgcSwgbWF0Y2hlcywgbWF0Y2g7Ly8sIGFyZ3MgPSBhcmd1bWVudHM7XG5cbiAgICAgICAgICAgIC8qLy8gY29uc3RydWN0IG9iamVjdCBiYXJlYm9uZXNcbiAgICAgICAgICAgIGZvciAocCA9IDA7IHAgPCBhcmdzWzFdLmxlbmd0aDsgcCsrKSB7XG4gICAgICAgICAgICAgICAgcSA9IGFyZ3NbMV1bcF07XG4gICAgICAgICAgICAgICAgcmVzdWx0W3R5cGVvZiBxID09PSBPQkpfVFlQRSA/IHFbMF0gOiBxXSA9IHVuZGVmaW5lZDtcbiAgICAgICAgICAgIH0qL1xuXG4gICAgICAgICAgICAvLyBsb29wIHRocm91Z2ggYWxsIHJlZ2V4ZXMgbWFwc1xuICAgICAgICAgICAgd2hpbGUgKGkgPCBhcnJheXMubGVuZ3RoICYmICFtYXRjaGVzKSB7XG5cbiAgICAgICAgICAgICAgICB2YXIgcmVnZXggPSBhcnJheXNbaV0sICAgICAgIC8vIGV2ZW4gc2VxdWVuY2UgKDAsMiw0LC4uKVxuICAgICAgICAgICAgICAgICAgICBwcm9wcyA9IGFycmF5c1tpICsgMV07ICAgLy8gb2RkIHNlcXVlbmNlICgxLDMsNSwuLilcbiAgICAgICAgICAgICAgICBqID0gayA9IDA7XG5cbiAgICAgICAgICAgICAgICAvLyB0cnkgbWF0Y2hpbmcgdWFzdHJpbmcgd2l0aCByZWdleGVzXG4gICAgICAgICAgICAgICAgd2hpbGUgKGogPCByZWdleC5sZW5ndGggJiYgIW1hdGNoZXMpIHtcblxuICAgICAgICAgICAgICAgICAgICBtYXRjaGVzID0gcmVnZXhbaisrXS5leGVjKHVhKTtcblxuICAgICAgICAgICAgICAgICAgICBpZiAoISFtYXRjaGVzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKHAgPSAwOyBwIDwgcHJvcHMubGVuZ3RoOyBwKyspIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXRjaCA9IG1hdGNoZXNbKytrXTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBxID0gcHJvcHNbcF07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gY2hlY2sgaWYgZ2l2ZW4gcHJvcGVydHkgaXMgYWN0dWFsbHkgYXJyYXlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHEgPT09IE9CSl9UWVBFICYmIHEubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocS5sZW5ndGggPT0gMikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBxWzFdID09IEZVTkNfVFlQRSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGFzc2lnbiBtb2RpZmllZCBtYXRjaFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXNbcVswXV0gPSBxWzFdLmNhbGwodGhpcywgbWF0Y2gpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBhc3NpZ24gZ2l2ZW4gdmFsdWUsIGlnbm9yZSByZWdleCBtYXRjaFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXNbcVswXV0gPSBxWzFdO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHEubGVuZ3RoID09IDMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNoZWNrIHdoZXRoZXIgZnVuY3Rpb24gb3IgcmVnZXhcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgcVsxXSA9PT0gRlVOQ19UWVBFICYmICEocVsxXS5leGVjICYmIHFbMV0udGVzdCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBjYWxsIGZ1bmN0aW9uICh1c3VhbGx5IHN0cmluZyBtYXBwZXIpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpc1txWzBdXSA9IG1hdGNoID8gcVsxXS5jYWxsKHRoaXMsIG1hdGNoLCBxWzJdKSA6IHVuZGVmaW5lZDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gc2FuaXRpemUgbWF0Y2ggdXNpbmcgZ2l2ZW4gcmVnZXhcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzW3FbMF1dID0gbWF0Y2ggPyBtYXRjaC5yZXBsYWNlKHFbMV0sIHFbMl0pIDogdW5kZWZpbmVkO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHEubGVuZ3RoID09IDQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzW3FbMF1dID0gbWF0Y2ggPyBxWzNdLmNhbGwodGhpcywgbWF0Y2gucmVwbGFjZShxWzFdLCBxWzJdKSkgOiB1bmRlZmluZWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzW3FdID0gbWF0Y2ggPyBtYXRjaCA6IHVuZGVmaW5lZDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaSArPSAyO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy9jb25zb2xlLmxvZyh0aGlzKTtcbiAgICAgICAgICAgIC8vcmV0dXJuIHRoaXM7XG4gICAgICAgIH0sXG5cbiAgICAgICAgc3RyIDogZnVuY3Rpb24gKHN0ciwgbWFwKSB7XG5cbiAgICAgICAgICAgIGZvciAodmFyIGkgaW4gbWFwKSB7XG4gICAgICAgICAgICAgICAgLy8gY2hlY2sgaWYgYXJyYXlcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIG1hcFtpXSA9PT0gT0JKX1RZUEUgJiYgbWFwW2ldLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBtYXBbaV0ubGVuZ3RoOyBqKyspIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh1dGlsLmhhcyhtYXBbaV1bal0sIHN0cikpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gKGkgPT09IFVOS05PV04pID8gdW5kZWZpbmVkIDogaTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAodXRpbC5oYXMobWFwW2ldLCBzdHIpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAoaSA9PT0gVU5LTk9XTikgPyB1bmRlZmluZWQgOiBpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBzdHI7XG4gICAgICAgIH1cbiAgICB9O1xuXG5cbiAgICAvLy8vLy8vLy8vLy8vLy9cbiAgICAvLyBTdHJpbmcgbWFwXG4gICAgLy8vLy8vLy8vLy8vLy9cblxuXG4gICAgdmFyIG1hcHMgPSB7XG5cbiAgICAgICAgYnJvd3NlciA6IHtcbiAgICAgICAgICAgIG9sZHNhZmFyaSA6IHtcbiAgICAgICAgICAgICAgICB2ZXJzaW9uIDoge1xuICAgICAgICAgICAgICAgICAgICAnMS4wJyAgIDogJy84JyxcbiAgICAgICAgICAgICAgICAgICAgJzEuMicgICA6ICcvMScsXG4gICAgICAgICAgICAgICAgICAgICcxLjMnICAgOiAnLzMnLFxuICAgICAgICAgICAgICAgICAgICAnMi4wJyAgIDogJy80MTInLFxuICAgICAgICAgICAgICAgICAgICAnMi4wLjInIDogJy80MTYnLFxuICAgICAgICAgICAgICAgICAgICAnMi4wLjMnIDogJy80MTcnLFxuICAgICAgICAgICAgICAgICAgICAnMi4wLjQnIDogJy80MTknLFxuICAgICAgICAgICAgICAgICAgICAnPycgICAgIDogJy8nXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9LFxuXG4gICAgICAgIGRldmljZSA6IHtcbiAgICAgICAgICAgIGFtYXpvbiA6IHtcbiAgICAgICAgICAgICAgICBtb2RlbCA6IHtcbiAgICAgICAgICAgICAgICAgICAgJ0ZpcmUgUGhvbmUnIDogWydTRCcsICdLRiddXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNwcmludCA6IHtcbiAgICAgICAgICAgICAgICBtb2RlbCA6IHtcbiAgICAgICAgICAgICAgICAgICAgJ0V2byBTaGlmdCA0RycgOiAnNzM3M0tUJ1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgdmVuZG9yIDoge1xuICAgICAgICAgICAgICAgICAgICAnSFRDJyAgICAgICA6ICdBUEEnLFxuICAgICAgICAgICAgICAgICAgICAnU3ByaW50JyAgICA6ICdTcHJpbnQnXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9LFxuXG4gICAgICAgIG9zIDoge1xuICAgICAgICAgICAgd2luZG93cyA6IHtcbiAgICAgICAgICAgICAgICB2ZXJzaW9uIDoge1xuICAgICAgICAgICAgICAgICAgICAnTUUnICAgICAgICA6ICc0LjkwJyxcbiAgICAgICAgICAgICAgICAgICAgJ05UIDMuMTEnICAgOiAnTlQzLjUxJyxcbiAgICAgICAgICAgICAgICAgICAgJ05UIDQuMCcgICAgOiAnTlQ0LjAnLFxuICAgICAgICAgICAgICAgICAgICAnMjAwMCcgICAgICA6ICdOVCA1LjAnLFxuICAgICAgICAgICAgICAgICAgICAnWFAnICAgICAgICA6IFsnTlQgNS4xJywgJ05UIDUuMiddLFxuICAgICAgICAgICAgICAgICAgICAnVmlzdGEnICAgICA6ICdOVCA2LjAnLFxuICAgICAgICAgICAgICAgICAgICAnNycgICAgICAgICA6ICdOVCA2LjEnLFxuICAgICAgICAgICAgICAgICAgICAnOCcgICAgICAgICA6ICdOVCA2LjInLFxuICAgICAgICAgICAgICAgICAgICAnOC4xJyAgICAgICA6ICdOVCA2LjMnLFxuICAgICAgICAgICAgICAgICAgICAnMTAnICAgICAgICA6IFsnTlQgNi40JywgJ05UIDEwLjAnXSxcbiAgICAgICAgICAgICAgICAgICAgJ1JUJyAgICAgICAgOiAnQVJNJ1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH07XG5cblxuICAgIC8vLy8vLy8vLy8vLy8vXG4gICAgLy8gUmVnZXggbWFwXG4gICAgLy8vLy8vLy8vLy8vL1xuXG5cbiAgICB2YXIgcmVnZXhlcyA9IHtcblxuICAgICAgICBicm93c2VyIDogW1tcblxuICAgICAgICAgICAgLy8gUHJlc3RvIGJhc2VkXG4gICAgICAgICAgICAvKG9wZXJhXFxzbWluaSlcXC8oW1xcd1xcLi1dKykvaSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBPcGVyYSBNaW5pXG4gICAgICAgICAgICAvKG9wZXJhXFxzW21vYmlsZXRhYl0rKS4rdmVyc2lvblxcLyhbXFx3XFwuLV0rKS9pLCAgICAgICAgICAgICAgICAgICAgICAvLyBPcGVyYSBNb2JpL1RhYmxldFxuICAgICAgICAgICAgLyhvcGVyYSkuK3ZlcnNpb25cXC8oW1xcd1xcLl0rKS9pLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBPcGVyYSA+IDkuODBcbiAgICAgICAgICAgIC8ob3BlcmEpW1xcL1xcc10rKFtcXHdcXC5dKykvaSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE9wZXJhIDwgOS44MFxuICAgICAgICAgICAgXSwgW05BTUUsIFZFUlNJT05dLCBbXG5cbiAgICAgICAgICAgIC8ob3Bpb3MpW1xcL1xcc10rKFtcXHdcXC5dKykvaSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE9wZXJhIG1pbmkgb24gaXBob25lID49IDguMFxuICAgICAgICAgICAgXSwgW1tOQU1FLCAnT3BlcmEgTWluaSddLCBWRVJTSU9OXSwgW1xuXG4gICAgICAgICAgICAvXFxzKG9wcilcXC8oW1xcd1xcLl0rKS9pICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBPcGVyYSBXZWJraXRcbiAgICAgICAgICAgIF0sIFtbTkFNRSwgJ09wZXJhJ10sIFZFUlNJT05dLCBbXG5cbiAgICAgICAgICAgIC8vIE1peGVkXG4gICAgICAgICAgICAvKGtpbmRsZSlcXC8oW1xcd1xcLl0rKS9pLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEtpbmRsZVxuICAgICAgICAgICAgLyhsdW5hc2NhcGV8bWF4dGhvbnxuZXRmcm9udHxqYXNtaW5lfGJsYXplcilbXFwvXFxzXT8oW1xcd1xcLl0rKSovaSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gTHVuYXNjYXBlL01heHRob24vTmV0ZnJvbnQvSmFzbWluZS9CbGF6ZXJcblxuICAgICAgICAgICAgLy8gVHJpZGVudCBiYXNlZFxuICAgICAgICAgICAgLyhhdmFudFxcc3xpZW1vYmlsZXxzbGltfGJhaWR1KSg/OmJyb3dzZXIpP1tcXC9cXHNdPyhbXFx3XFwuXSopL2ksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEF2YW50L0lFTW9iaWxlL1NsaW1Ccm93c2VyL0JhaWR1XG4gICAgICAgICAgICAvKD86bXN8XFwoKShpZSlcXHMoW1xcd1xcLl0rKS9pLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBJbnRlcm5ldCBFeHBsb3JlclxuXG4gICAgICAgICAgICAvLyBXZWJraXQvS0hUTUwgYmFzZWRcbiAgICAgICAgICAgIC8ocmVrb25xKVxcLyhbXFx3XFwuXSspKi9pLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gUmVrb25xXG4gICAgICAgICAgICAvKGNocm9taXVtfGZsb2NrfHJvY2ttZWx0fG1pZG9yaXxlcGlwaGFueXxzaWxrfHNreWZpcmV8b3ZpYnJvd3Nlcnxib2x0fGlyb258dml2YWxkaXxpcmlkaXVtfHBoYW50b21qc3xib3dzZXIpXFwvKFtcXHdcXC4tXSspL2lcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQ2hyb21pdW0vRmxvY2svUm9ja01lbHQvTWlkb3JpL0VwaXBoYW55L1NpbGsvU2t5ZmlyZS9Cb2x0L0lyb24vSXJpZGl1bS9QaGFudG9tSlMvQm93c2VyXG4gICAgICAgICAgICBdLCBbTkFNRSwgVkVSU0lPTl0sIFtcblxuICAgICAgICAgICAgLyh0cmlkZW50KS4rcnZbOlxcc10oW1xcd1xcLl0rKS4rbGlrZVxcc2dlY2tvL2kgICAgICAgICAgICAgICAgICAgICAgICAgLy8gSUUxMVxuICAgICAgICAgICAgXSwgW1tOQU1FLCAnSUUnXSwgVkVSU0lPTl0sIFtcblxuICAgICAgICAgICAgLyhlZGdlKVxcLygoXFxkKyk/W1xcd1xcLl0rKS9pICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gTWljcm9zb2Z0IEVkZ2VcbiAgICAgICAgICAgIF0sIFtOQU1FLCBWRVJTSU9OXSwgW1xuXG4gICAgICAgICAgICAvKHlhYnJvd3NlcilcXC8oW1xcd1xcLl0rKS9pICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFlhbmRleFxuICAgICAgICAgICAgXSwgW1tOQU1FLCAnWWFuZGV4J10sIFZFUlNJT05dLCBbXG5cbiAgICAgICAgICAgIC8ocHVmZmluKVxcLyhbXFx3XFwuXSspL2kgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gUHVmZmluXG4gICAgICAgICAgICBdLCBbW05BTUUsICdQdWZmaW4nXSwgVkVSU0lPTl0sIFtcblxuICAgICAgICAgICAgLygoPzpbXFxzXFwvXSl1Yz9cXHM/YnJvd3NlcnwoPzpqdWMuKyl1Y3dlYilbXFwvXFxzXT8oW1xcd1xcLl0rKS9pXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFVDQnJvd3NlclxuICAgICAgICAgICAgXSwgW1tOQU1FLCAnVUNCcm93c2VyJ10sIFZFUlNJT05dLCBbXG5cbiAgICAgICAgICAgIC8oY29tb2RvX2RyYWdvbilcXC8oW1xcd1xcLl0rKS9pICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQ29tb2RvIERyYWdvblxuICAgICAgICAgICAgXSwgW1tOQU1FLCAvXy9nLCAnICddLCBWRVJTSU9OXSwgW1xuXG4gICAgICAgICAgICAvKG1pY3JvbWVzc2VuZ2VyKVxcLyhbXFx3XFwuXSspL2kgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFdlQ2hhdFxuICAgICAgICAgICAgXSwgW1tOQU1FLCAnV2VDaGF0J10sIFZFUlNJT05dLCBbXG5cbiAgICAgICAgICAgIC8oUVEpXFwvKFtcXGRcXC5dKykvaSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gUVEsIGFrYSBTaG91UVxuICAgICAgICAgICAgXSwgW05BTUUsIFZFUlNJT05dLCBbXG5cbiAgICAgICAgICAgIC9tPyhxcWJyb3dzZXIpW1xcL1xcc10/KFtcXHdcXC5dKykvaSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFFRQnJvd3NlclxuICAgICAgICAgICAgXSwgW05BTUUsIFZFUlNJT05dLCBbXG5cbiAgICAgICAgICAgIC94aWFvbWlcXC9taXVpYnJvd3NlclxcLyhbXFx3XFwuXSspL2kgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE1JVUkgQnJvd3NlclxuICAgICAgICAgICAgXSwgW1ZFUlNJT04sIFtOQU1FLCAnTUlVSSBCcm93c2VyJ11dLCBbXG5cbiAgICAgICAgICAgIC87ZmJhdlxcLyhbXFx3XFwuXSspOy9pICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gRmFjZWJvb2sgQXBwIGZvciBpT1MgJiBBbmRyb2lkXG4gICAgICAgICAgICBdLCBbVkVSU0lPTiwgW05BTUUsICdGYWNlYm9vayddXSwgW1xuXG4gICAgICAgICAgICAvKGhlYWRsZXNzY2hyb21lKSAoW1xcd1xcLl0rKS9pICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQ2hyb21lIEhlYWRsZXNzXG4gICAgICAgICAgICBdLCBbVkVSU0lPTiwgW05BTUUsICdDaHJvbWUgSGVhZGxlc3MnXV0sIFtcblxuICAgICAgICAgICAgL1xcc3d2XFwpLisoY2hyb21lKVxcLyhbXFx3XFwuXSspL2kgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIENocm9tZSBXZWJWaWV3XG4gICAgICAgICAgICBdLCBbW05BTUUsIC8oLispLywgJyQxIFdlYlZpZXcnXSwgVkVSU0lPTl0sIFtcblxuICAgICAgICAgICAgLygoPzpvY3VsdXN8c2Ftc3VuZylicm93c2VyKVxcLyhbXFx3XFwuXSspL2lcbiAgICAgICAgICAgIF0sIFtbTkFNRSwgLyguKyg/Omd8dXMpKSguKykvLCAnJDEgJDInXSwgVkVSU0lPTl0sIFsgICAgICAgICAgICAgICAgLy8gT2N1bHVzIC8gU2Ftc3VuZyBCcm93c2VyXG5cbiAgICAgICAgICAgIC9hbmRyb2lkLit2ZXJzaW9uXFwvKFtcXHdcXC5dKylcXHMrKD86bW9iaWxlXFxzP3NhZmFyaXxzYWZhcmkpKi9pICAgICAgICAvLyBBbmRyb2lkIEJyb3dzZXJcbiAgICAgICAgICAgIF0sIFtWRVJTSU9OLCBbTkFNRSwgJ0FuZHJvaWQgQnJvd3NlciddXSwgW1xuXG4gICAgICAgICAgICAvKGNocm9tZXxvbW5pd2VifGFyb3JhfFt0aXplbm9rYV17NX1cXHM/YnJvd3NlcilcXC92PyhbXFx3XFwuXSspL2lcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQ2hyb21lL09tbmlXZWIvQXJvcmEvVGl6ZW4vTm9raWFcbiAgICAgICAgICAgIF0sIFtOQU1FLCBWRVJTSU9OXSwgW1xuXG4gICAgICAgICAgICAvKGRvbGZpbilcXC8oW1xcd1xcLl0rKS9pICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIERvbHBoaW5cbiAgICAgICAgICAgIF0sIFtbTkFNRSwgJ0RvbHBoaW4nXSwgVkVSU0lPTl0sIFtcblxuICAgICAgICAgICAgLygoPzphbmRyb2lkLispY3Jtb3xjcmlvcylcXC8oW1xcd1xcLl0rKS9pICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBDaHJvbWUgZm9yIEFuZHJvaWQvaU9TXG4gICAgICAgICAgICBdLCBbW05BTUUsICdDaHJvbWUnXSwgVkVSU0lPTl0sIFtcblxuICAgICAgICAgICAgLyhjb2FzdClcXC8oW1xcd1xcLl0rKS9pICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBPcGVyYSBDb2FzdFxuICAgICAgICAgICAgXSwgW1tOQU1FLCAnT3BlcmEgQ29hc3QnXSwgVkVSU0lPTl0sIFtcblxuICAgICAgICAgICAgL2Z4aW9zXFwvKFtcXHdcXC4tXSspL2kgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBGaXJlZm94IGZvciBpT1NcbiAgICAgICAgICAgIF0sIFtWRVJTSU9OLCBbTkFNRSwgJ0ZpcmVmb3gnXV0sIFtcblxuICAgICAgICAgICAgL3ZlcnNpb25cXC8oW1xcd1xcLl0rKS4rP21vYmlsZVxcL1xcdytcXHMoc2FmYXJpKS9pICAgICAgICAgICAgICAgICAgICAgICAvLyBNb2JpbGUgU2FmYXJpXG4gICAgICAgICAgICBdLCBbVkVSU0lPTiwgW05BTUUsICdNb2JpbGUgU2FmYXJpJ11dLCBbXG5cbiAgICAgICAgICAgIC92ZXJzaW9uXFwvKFtcXHdcXC5dKykuKz8obW9iaWxlXFxzP3NhZmFyaXxzYWZhcmkpL2kgICAgICAgICAgICAgICAgICAgIC8vIFNhZmFyaSAmIFNhZmFyaSBNb2JpbGVcbiAgICAgICAgICAgIF0sIFtWRVJTSU9OLCBOQU1FXSwgW1xuXG4gICAgICAgICAgICAvd2Via2l0Lis/KG1vYmlsZVxccz9zYWZhcml8c2FmYXJpKShcXC9bXFx3XFwuXSspL2kgICAgICAgICAgICAgICAgICAgICAvLyBTYWZhcmkgPCAzLjBcbiAgICAgICAgICAgIF0sIFtOQU1FLCBbVkVSU0lPTiwgbWFwcGVyLnN0ciwgbWFwcy5icm93c2VyLm9sZHNhZmFyaS52ZXJzaW9uXV0sIFtcblxuICAgICAgICAgICAgLyhrb25xdWVyb3IpXFwvKFtcXHdcXC5dKykvaSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBLb25xdWVyb3JcbiAgICAgICAgICAgIC8od2Via2l0fGtodG1sKVxcLyhbXFx3XFwuXSspL2lcbiAgICAgICAgICAgIF0sIFtOQU1FLCBWRVJTSU9OXSwgW1xuXG4gICAgICAgICAgICAvLyBHZWNrbyBiYXNlZFxuICAgICAgICAgICAgLyhuYXZpZ2F0b3J8bmV0c2NhcGUpXFwvKFtcXHdcXC4tXSspL2kgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBOZXRzY2FwZVxuICAgICAgICAgICAgXSwgW1tOQU1FLCAnTmV0c2NhcGUnXSwgVkVSU0lPTl0sIFtcbiAgICAgICAgICAgIC8oc3dpZnRmb3gpL2ksICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gU3dpZnRmb3hcbiAgICAgICAgICAgIC8oaWNlZHJhZ29ufGljZXdlYXNlbHxjYW1pbm98Y2hpbWVyYXxmZW5uZWN8bWFlbW9cXHNicm93c2VyfG1pbmltb3xjb25rZXJvcilbXFwvXFxzXT8oW1xcd1xcLlxcK10rKS9pLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBJY2VEcmFnb24vSWNld2Vhc2VsL0NhbWluby9DaGltZXJhL0Zlbm5lYy9NYWVtby9NaW5pbW8vQ29ua2Vyb3JcbiAgICAgICAgICAgIC8oZmlyZWZveHxzZWFtb25rZXl8ay1tZWxlb258aWNlY2F0fGljZWFwZXxmaXJlYmlyZHxwaG9lbml4KVxcLyhbXFx3XFwuLV0rKS9pLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBGaXJlZm94L1NlYU1vbmtleS9LLU1lbGVvbi9JY2VDYXQvSWNlQXBlL0ZpcmViaXJkL1Bob2VuaXhcbiAgICAgICAgICAgIC8obW96aWxsYSlcXC8oW1xcd1xcLl0rKS4rcnZcXDouK2dlY2tvXFwvXFxkKy9pLCAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gTW96aWxsYVxuXG4gICAgICAgICAgICAvLyBPdGhlclxuICAgICAgICAgICAgLyhwb2xhcmlzfGx5bnh8ZGlsbG98aWNhYnxkb3Jpc3xhbWF5YXx3M218bmV0c3VyZnxzbGVpcG5pcilbXFwvXFxzXT8oW1xcd1xcLl0rKS9pLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBQb2xhcmlzL0x5bngvRGlsbG8vaUNhYi9Eb3Jpcy9BbWF5YS93M20vTmV0U3VyZi9TbGVpcG5pclxuICAgICAgICAgICAgLyhsaW5rcylcXHNcXCgoW1xcd1xcLl0rKS9pLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gTGlua3NcbiAgICAgICAgICAgIC8oZ29icm93c2VyKVxcLz8oW1xcd1xcLl0rKSovaSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gR29Ccm93c2VyXG4gICAgICAgICAgICAvKGljZVxccz9icm93c2VyKVxcL3Y/KFtcXHdcXC5fXSspL2ksICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBJQ0UgQnJvd3NlclxuICAgICAgICAgICAgLyhtb3NhaWMpW1xcL1xcc10oW1xcd1xcLl0rKS9pICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gTW9zYWljXG4gICAgICAgICAgICBdLCBbTkFNRSwgVkVSU0lPTl1cblxuICAgICAgICAgICAgLyogLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG4gICAgICAgICAgICAvLyBNZWRpYSBwbGF5ZXJzIEJFR0lOXG4gICAgICAgICAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblxuICAgICAgICAgICAgLCBbXG5cbiAgICAgICAgICAgIC8oYXBwbGUoPzpjb3JlbWVkaWF8KSlcXC8oKFxcZCspW1xcd1xcLl9dKykvaSwgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEdlbmVyaWMgQXBwbGUgQ29yZU1lZGlhXG4gICAgICAgICAgICAvKGNvcmVtZWRpYSkgdigoXFxkKylbXFx3XFwuX10rKS9pXG4gICAgICAgICAgICBdLCBbTkFNRSwgVkVSU0lPTl0sIFtcblxuICAgICAgICAgICAgLyhhcXVhbHVuZ3xseXNzbmF8YnNwbGF5ZXIpXFwvKChcXGQrKT9bXFx3XFwuLV0rKS9pICAgICAgICAgICAgICAgICAgICAgLy8gQXF1YWx1bmcvTHlzc25hL0JTUGxheWVyXG4gICAgICAgICAgICBdLCBbTkFNRSwgVkVSU0lPTl0sIFtcblxuICAgICAgICAgICAgLyhhcmVzfG9zc3Byb3h5KVxccygoXFxkKylbXFx3XFwuLV0rKS9pICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQXJlcy9PU1NQcm94eVxuICAgICAgICAgICAgXSwgW05BTUUsIFZFUlNJT05dLCBbXG5cbiAgICAgICAgICAgIC8oYXVkYWNpb3VzfGF1ZGltdXNpY3N0cmVhbXxhbWFyb2t8YmFzc3xjb3JlfGRhbHZpa3xnbm9tZW1wbGF5ZXJ8bXVzaWMgb24gY29uc29sZXxuc3BsYXllcnxwc3AtaW50ZXJuZXRyYWRpb3BsYXllcnx2aWRlb3MpXFwvKChcXGQrKVtcXHdcXC4tXSspL2ksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEF1ZGFjaW91cy9BdWRpTXVzaWNTdHJlYW0vQW1hcm9rL0JBU1MvT3BlbkNPUkUvRGFsdmlrL0dub21lTXBsYXllci9Nb0NcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gTlNQbGF5ZXIvUFNQLUludGVybmV0UmFkaW9QbGF5ZXIvVmlkZW9zXG4gICAgICAgICAgICAvKGNsZW1lbnRpbmV8bXVzaWMgcGxheWVyIGRhZW1vbilcXHMoKFxcZCspW1xcd1xcLi1dKykvaSwgICAgICAgICAgICAgICAvLyBDbGVtZW50aW5lL01QRFxuICAgICAgICAgICAgLyhsZyBwbGF5ZXJ8bmV4cGxheWVyKVxccygoXFxkKylbXFxkXFwuXSspL2ksXG4gICAgICAgICAgICAvcGxheWVyXFwvKG5leHBsYXllcnxsZyBwbGF5ZXIpXFxzKChcXGQrKVtcXHdcXC4tXSspL2kgICAgICAgICAgICAgICAgICAgLy8gTmV4UGxheWVyL0xHIFBsYXllclxuICAgICAgICAgICAgXSwgW05BTUUsIFZFUlNJT05dLCBbXG4gICAgICAgICAgICAvKG5leHBsYXllcilcXHMoKFxcZCspW1xcd1xcLi1dKykvaSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBOZXhwbGF5ZXJcbiAgICAgICAgICAgIF0sIFtOQU1FLCBWRVJTSU9OXSwgW1xuXG4gICAgICAgICAgICAvKGZscnApXFwvKChcXGQrKVtcXHdcXC4tXSspL2kgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBGbGlwIFBsYXllclxuICAgICAgICAgICAgXSwgW1tOQU1FLCAnRmxpcCBQbGF5ZXInXSwgVkVSU0lPTl0sIFtcblxuICAgICAgICAgICAgLyhmc3RyZWFtfG5hdGl2ZWhvc3R8cXVlcnlzZWVrc3BpZGVyfGlhLWFyY2hpdmVyfGZhY2Vib29rZXh0ZXJuYWxoaXQpL2lcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gRlN0cmVhbS9OYXRpdmVIb3N0L1F1ZXJ5U2Vla1NwaWRlci9JQSBBcmNoaXZlci9mYWNlYm9va2V4dGVybmFsaGl0XG4gICAgICAgICAgICBdLCBbTkFNRV0sIFtcblxuICAgICAgICAgICAgLyhnc3RyZWFtZXIpIHNvdXBodHRwc3JjICg/OlxcKFteXFwpXStcXCkpezAsMX0gbGlic291cFxcLygoXFxkKylbXFx3XFwuLV0rKS9pXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEdzdHJlYW1lclxuICAgICAgICAgICAgXSwgW05BTUUsIFZFUlNJT05dLCBbXG5cbiAgICAgICAgICAgIC8oaHRjIHN0cmVhbWluZyBwbGF5ZXIpXFxzW1xcd19dK1xcc1xcL1xccygoXFxkKylbXFxkXFwuXSspL2ksICAgICAgICAgICAgICAvLyBIVEMgU3RyZWFtaW5nIFBsYXllclxuICAgICAgICAgICAgLyhqYXZhfHB5dGhvbi11cmxsaWJ8cHl0aG9uLXJlcXVlc3RzfHdnZXR8bGliY3VybClcXC8oKFxcZCspW1xcd1xcLi1fXSspL2ksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEphdmEvdXJsbGliL3JlcXVlc3RzL3dnZXQvY1VSTFxuICAgICAgICAgICAgLyhsYXZmKSgoXFxkKylbXFxkXFwuXSspL2kgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBMYXZmIChGRk1QRUcpXG4gICAgICAgICAgICBdLCBbTkFNRSwgVkVSU0lPTl0sIFtcblxuICAgICAgICAgICAgLyhodGNfb25lX3MpXFwvKChcXGQrKVtcXGRcXC5dKykvaSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gSFRDIE9uZSBTXG4gICAgICAgICAgICBdLCBbW05BTUUsIC9fL2csICcgJ10sIFZFUlNJT05dLCBbXG5cbiAgICAgICAgICAgIC8obXBsYXllcikoPzpcXHN8XFwvKSg/Oig/OnNoZXJweWEtKXswLDF9c3ZuKSg/Oi18XFxzKShyXFxkKyg/Oi1cXGQrW1xcd1xcLi1dKyl7MCwxfSkvaVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBNUGxheWVyIFNWTlxuICAgICAgICAgICAgXSwgW05BTUUsIFZFUlNJT05dLCBbXG5cbiAgICAgICAgICAgIC8obXBsYXllcikoPzpcXHN8XFwvfFt1bmtvdy1dKykoKFxcZCspW1xcd1xcLi1dKykvaSAgICAgICAgICAgICAgICAgICAgICAvLyBNUGxheWVyXG4gICAgICAgICAgICBdLCBbTkFNRSwgVkVSU0lPTl0sIFtcblxuICAgICAgICAgICAgLyhtcGxheWVyKS9pLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBNUGxheWVyIChubyBvdGhlciBpbmZvKVxuICAgICAgICAgICAgLyh5b3VybXV6ZSkvaSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBZb3VyTXV6ZVxuICAgICAgICAgICAgLyhtZWRpYSBwbGF5ZXIgY2xhc3NpY3xuZXJvIHNob3d0aW1lKS9pICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBNZWRpYSBQbGF5ZXIgQ2xhc3NpYy9OZXJvIFNob3dUaW1lXG4gICAgICAgICAgICBdLCBbTkFNRV0sIFtcblxuICAgICAgICAgICAgLyhuZXJvICg/OmhvbWV8c2NvdXQpKVxcLygoXFxkKylbXFx3XFwuLV0rKS9pICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gTmVybyBIb21lL05lcm8gU2NvdXRcbiAgICAgICAgICAgIF0sIFtOQU1FLCBWRVJTSU9OXSwgW1xuXG4gICAgICAgICAgICAvKG5va2lhXFxkKylcXC8oKFxcZCspW1xcd1xcLi1dKykvaSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gTm9raWFcbiAgICAgICAgICAgIF0sIFtOQU1FLCBWRVJTSU9OXSwgW1xuXG4gICAgICAgICAgICAvXFxzKHNvbmdiaXJkKVxcLygoXFxkKylbXFx3XFwuLV0rKS9pICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gU29uZ2JpcmQvUGhpbGlwcy1Tb25nYmlyZFxuICAgICAgICAgICAgXSwgW05BTUUsIFZFUlNJT05dLCBbXG5cbiAgICAgICAgICAgIC8od2luYW1wKTMgdmVyc2lvbiAoKFxcZCspW1xcd1xcLi1dKykvaSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gV2luYW1wXG4gICAgICAgICAgICAvKHdpbmFtcClcXHMoKFxcZCspW1xcd1xcLi1dKykvaSxcbiAgICAgICAgICAgIC8od2luYW1wKW1wZWdcXC8oKFxcZCspW1xcd1xcLi1dKykvaVxuICAgICAgICAgICAgXSwgW05BTUUsIFZFUlNJT05dLCBbXG5cbiAgICAgICAgICAgIC8ob2Ntcy1ib3R8dGFwaW5yYWRpb3x0dW5laW4gcmFkaW98dW5rbm93bnx3aW5hbXB8aW5saWdodCByYWRpbykvaSAgLy8gT0NNUy1ib3QvdGFwIGluIHJhZGlvL3R1bmVpbi91bmtub3duL3dpbmFtcCAobm8gb3RoZXIgaW5mbylcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gaW5saWdodCByYWRpb1xuICAgICAgICAgICAgXSwgW05BTUVdLCBbXG5cbiAgICAgICAgICAgIC8ocXVpY2t0aW1lfHJtYXxyYWRpb2FwcHxyYWRpb2NsaWVudGFwcGxpY2F0aW9ufHNvdW5kdGFwfHRvdGVtfHN0YWdlZnJpZ2h0fHN0cmVhbWl1bSlcXC8oKFxcZCspW1xcd1xcLi1dKykvaVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBRdWlja1RpbWUvUmVhbE1lZGlhL1JhZGlvQXBwL1JhZGlvQ2xpZW50QXBwbGljYXRpb24vXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFNvdW5kVGFwL1RvdGVtL1N0YWdlZnJpZ2h0L1N0cmVhbWl1bVxuICAgICAgICAgICAgXSwgW05BTUUsIFZFUlNJT05dLCBbXG5cbiAgICAgICAgICAgIC8oc21wKSgoXFxkKylbXFxkXFwuXSspL2kgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gU01QXG4gICAgICAgICAgICBdLCBbTkFNRSwgVkVSU0lPTl0sIFtcblxuICAgICAgICAgICAgLyh2bGMpIG1lZGlhIHBsYXllciAtIHZlcnNpb24gKChcXGQrKVtcXHdcXC5dKykvaSwgICAgICAgICAgICAgICAgICAgICAvLyBWTEMgVmlkZW9sYW5cbiAgICAgICAgICAgIC8odmxjKVxcLygoXFxkKylbXFx3XFwuLV0rKS9pLFxuICAgICAgICAgICAgLyh4Ym1jfGd2ZnN8eGluZXx4bW1zfGlyYXBwKVxcLygoXFxkKylbXFx3XFwuLV0rKS9pLCAgICAgICAgICAgICAgICAgICAgLy8gWEJNQy9ndmZzL1hpbmUvWE1NUy9pcmFwcFxuICAgICAgICAgICAgLyhmb29iYXIyMDAwKVxcLygoXFxkKylbXFxkXFwuXSspL2ksICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gRm9vYmFyMjAwMFxuICAgICAgICAgICAgLyhpdHVuZXMpXFwvKChcXGQrKVtcXGRcXC5dKykvaSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gaVR1bmVzXG4gICAgICAgICAgICBdLCBbTkFNRSwgVkVSU0lPTl0sIFtcblxuICAgICAgICAgICAgLyh3bXBsYXllcilcXC8oKFxcZCspW1xcd1xcLi1dKykvaSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gV2luZG93cyBNZWRpYSBQbGF5ZXJcbiAgICAgICAgICAgIC8od2luZG93cy1tZWRpYS1wbGF5ZXIpXFwvKChcXGQrKVtcXHdcXC4tXSspL2lcbiAgICAgICAgICAgIF0sIFtbTkFNRSwgLy0vZywgJyAnXSwgVkVSU0lPTl0sIFtcblxuICAgICAgICAgICAgL3dpbmRvd3NcXC8oKFxcZCspW1xcd1xcLi1dKykgdXBucFxcL1tcXGRcXC5dKyBkbG5hZG9jXFwvW1xcZFxcLl0rIChob21lIG1lZGlhIHNlcnZlcikvaVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBXaW5kb3dzIE1lZGlhIFNlcnZlclxuICAgICAgICAgICAgXSwgW1ZFUlNJT04sIFtOQU1FLCAnV2luZG93cyddXSwgW1xuXG4gICAgICAgICAgICAvKGNvbVxcLnJpc2V1cHJhZGlvYWxhcm0pXFwvKChcXGQrKVtcXGRcXC5dKikvaSAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gUmlzZVVQIFJhZGlvIEFsYXJtXG4gICAgICAgICAgICBdLCBbTkFNRSwgVkVSU0lPTl0sIFtcblxuICAgICAgICAgICAgLyhyYWQuaW8pXFxzKChcXGQrKVtcXGRcXC5dKykvaSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gUmFkLmlvXG4gICAgICAgICAgICAvKHJhZGlvLig/OmRlfGF0fGZyKSlcXHMoKFxcZCspW1xcZFxcLl0rKS9pXG4gICAgICAgICAgICBdLCBbW05BTUUsICdyYWQuaW8nXSwgVkVSU0lPTl1cblxuICAgICAgICAgICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuICAgICAgICAgICAgLy8gTWVkaWEgcGxheWVycyBFTkRcbiAgICAgICAgICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vKi9cblxuICAgICAgICBdLFxuXG4gICAgICAgIGNwdSA6IFtbXG5cbiAgICAgICAgICAgIC8oPzooYW1kfHgoPzooPzo4Nnw2NClbXy1dKT98d293fHdpbik2NClbO1xcKV0vaSAgICAgICAgICAgICAgICAgICAgIC8vIEFNRDY0XG4gICAgICAgICAgICBdLCBbW0FSQ0hJVEVDVFVSRSwgJ2FtZDY0J11dLCBbXG5cbiAgICAgICAgICAgIC8oaWEzMig/PTspKS9pICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gSUEzMiAocXVpY2t0aW1lKVxuICAgICAgICAgICAgXSwgW1tBUkNISVRFQ1RVUkUsIHV0aWwubG93ZXJpemVdXSwgW1xuXG4gICAgICAgICAgICAvKCg/OmlbMzQ2XXx4KTg2KVs7XFwpXS9pICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBJQTMyXG4gICAgICAgICAgICBdLCBbW0FSQ0hJVEVDVFVSRSwgJ2lhMzInXV0sIFtcblxuICAgICAgICAgICAgLy8gUG9ja2V0UEMgbWlzdGFrZW5seSBpZGVudGlmaWVkIGFzIFBvd2VyUENcbiAgICAgICAgICAgIC93aW5kb3dzXFxzKGNlfG1vYmlsZSk7XFxzcHBjOy9pXG4gICAgICAgICAgICBdLCBbW0FSQ0hJVEVDVFVSRSwgJ2FybSddXSwgW1xuXG4gICAgICAgICAgICAvKCg/OnBwY3xwb3dlcnBjKSg/OjY0KT8pKD86XFxzbWFjfDt8XFwpKS9pICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gUG93ZXJQQ1xuICAgICAgICAgICAgXSwgW1tBUkNISVRFQ1RVUkUsIC9vd2VyLywgJycsIHV0aWwubG93ZXJpemVdXSwgW1xuXG4gICAgICAgICAgICAvKHN1bjRcXHcpWztcXCldL2kgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gU1BBUkNcbiAgICAgICAgICAgIF0sIFtbQVJDSElURUNUVVJFLCAnc3BhcmMnXV0sIFtcblxuICAgICAgICAgICAgLygoPzphdnIzMnxpYTY0KD89OykpfDY4ayg/PVxcKSl8YXJtKD86NjR8KD89dlxcZCs7KSl8KD89YXRtZWxcXHMpYXZyfCg/OmlyaXh8bWlwc3xzcGFyYykoPzo2NCk/KD89Oyl8cGEtcmlzYykvaVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBJQTY0LCA2OEssIEFSTS82NCwgQVZSLzMyLCBJUklYLzY0LCBNSVBTLzY0LCBTUEFSQy82NCwgUEEtUklTQ1xuICAgICAgICAgICAgXSwgW1tBUkNISVRFQ1RVUkUsIHV0aWwubG93ZXJpemVdXVxuICAgICAgICBdLFxuXG4gICAgICAgIGRldmljZSA6IFtbXG5cbiAgICAgICAgICAgIC9cXCgoaXBhZHxwbGF5Ym9vayk7W1xcd1xcc1xcKTstXSsocmltfGFwcGxlKS9pICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGlQYWQvUGxheUJvb2tcbiAgICAgICAgICAgIF0sIFtNT0RFTCwgVkVORE9SLCBbVFlQRSwgVEFCTEVUXV0sIFtcblxuICAgICAgICAgICAgL2FwcGxlY29yZW1lZGlhXFwvW1xcd1xcLl0rIFxcKChpcGFkKS8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gaVBhZFxuICAgICAgICAgICAgXSwgW01PREVMLCBbVkVORE9SLCAnQXBwbGUnXSwgW1RZUEUsIFRBQkxFVF1dLCBbXG5cbiAgICAgICAgICAgIC8oYXBwbGVcXHN7MCwxfXR2KS9pICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEFwcGxlIFRWXG4gICAgICAgICAgICBdLCBbW01PREVMLCAnQXBwbGUgVFYnXSwgW1ZFTkRPUiwgJ0FwcGxlJ11dLCBbXG5cbiAgICAgICAgICAgIC8oYXJjaG9zKVxccyhnYW1lcGFkMj8pL2ksICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEFyY2hvc1xuICAgICAgICAgICAgLyhocCkuKyh0b3VjaHBhZCkvaSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBIUCBUb3VjaFBhZFxuICAgICAgICAgICAgLyhocCkuKyh0YWJsZXQpL2ksICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBIUCBUYWJsZXRcbiAgICAgICAgICAgIC8oa2luZGxlKVxcLyhbXFx3XFwuXSspL2ksICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gS2luZGxlXG4gICAgICAgICAgICAvXFxzKG5vb2spW1xcd1xcc10rYnVpbGRcXC8oXFx3KykvaSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gTm9va1xuICAgICAgICAgICAgLyhkZWxsKVxccyhzdHJlYVtrcHJcXHNcXGRdKltcXGRrb10pL2kgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gRGVsbCBTdHJlYWtcbiAgICAgICAgICAgIF0sIFtWRU5ET1IsIE1PREVMLCBbVFlQRSwgVEFCTEVUXV0sIFtcblxuICAgICAgICAgICAgLyhrZltBLXpdKylcXHNidWlsZFxcL1tcXHdcXC5dKy4qc2lsa1xcLy9pICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEtpbmRsZSBGaXJlIEhEXG4gICAgICAgICAgICBdLCBbTU9ERUwsIFtWRU5ET1IsICdBbWF6b24nXSwgW1RZUEUsIFRBQkxFVF1dLCBbXG4gICAgICAgICAgICAvKHNkfGtmKVswMzQ5aGlqb3JzdHV3XStcXHNidWlsZFxcL1tcXHdcXC5dKy4qc2lsa1xcLy9pICAgICAgICAgICAgICAgICAgLy8gRmlyZSBQaG9uZVxuICAgICAgICAgICAgXSwgW1tNT0RFTCwgbWFwcGVyLnN0ciwgbWFwcy5kZXZpY2UuYW1hem9uLm1vZGVsXSwgW1ZFTkRPUiwgJ0FtYXpvbiddLCBbVFlQRSwgTU9CSUxFXV0sIFtcblxuICAgICAgICAgICAgL1xcKChpcFtob25lZHxcXHNcXHcqXSspOy4rKGFwcGxlKS9pICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBpUG9kL2lQaG9uZVxuICAgICAgICAgICAgXSwgW01PREVMLCBWRU5ET1IsIFtUWVBFLCBNT0JJTEVdXSwgW1xuICAgICAgICAgICAgL1xcKChpcFtob25lZHxcXHNcXHcqXSspOy9pICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBpUG9kL2lQaG9uZVxuICAgICAgICAgICAgXSwgW01PREVMLCBbVkVORE9SLCAnQXBwbGUnXSwgW1RZUEUsIE1PQklMRV1dLCBbXG5cbiAgICAgICAgICAgIC8oYmxhY2tiZXJyeSlbXFxzLV0/KFxcdyspL2ksICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBCbGFja0JlcnJ5XG4gICAgICAgICAgICAvKGJsYWNrYmVycnl8YmVucXxwYWxtKD89XFwtKXxzb255ZXJpY3Nzb258YWNlcnxhc3VzfGRlbGx8bWVpenV8bW90b3JvbGF8cG9seXRyb24pW1xcc18tXT8oW1xcdy1dKykqL2ksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEJlblEvUGFsbS9Tb255LUVyaWNzc29uL0FjZXIvQXN1cy9EZWxsL01laXp1L01vdG9yb2xhL1BvbHl0cm9uXG4gICAgICAgICAgICAvKGhwKVxccyhbXFx3XFxzXStcXHcpL2ksICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBIUCBpUEFRXG4gICAgICAgICAgICAvKGFzdXMpLT8oXFx3KykvaSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBBc3VzXG4gICAgICAgICAgICBdLCBbVkVORE9SLCBNT0RFTCwgW1RZUEUsIE1PQklMRV1dLCBbXG4gICAgICAgICAgICAvXFwoYmIxMDtcXHMoXFx3KykvaSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEJsYWNrQmVycnkgMTBcbiAgICAgICAgICAgIF0sIFtNT0RFTCwgW1ZFTkRPUiwgJ0JsYWNrQmVycnknXSwgW1RZUEUsIE1PQklMRV1dLCBbXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEFzdXMgVGFibGV0c1xuICAgICAgICAgICAgL2FuZHJvaWQuKyh0cmFuc2ZvW3ByaW1lXFxzXXs0LDEwfVxcc1xcdyt8ZWVlcGN8c2xpZGVyXFxzXFx3K3xuZXh1cyA3fHBhZGZvbmUpL2lcbiAgICAgICAgICAgIF0sIFtNT0RFTCwgW1ZFTkRPUiwgJ0FzdXMnXSwgW1RZUEUsIFRBQkxFVF1dLCBbXG5cbiAgICAgICAgICAgIC8oc29ueSlcXHModGFibGV0XFxzW3BzXSlcXHNidWlsZFxcLy9pLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBTb255XG4gICAgICAgICAgICAvKHNvbnkpPyg/OnNncC4rKVxcc2J1aWxkXFwvL2lcbiAgICAgICAgICAgIF0sIFtbVkVORE9SLCAnU29ueSddLCBbTU9ERUwsICdYcGVyaWEgVGFibGV0J10sIFtUWVBFLCBUQUJMRVRdXSwgW1xuICAgICAgICAgICAgL2FuZHJvaWQuK1xccyhbYy1nXVxcZHs0fXxzb1stbF1cXHcrKVxcc2J1aWxkXFwvL2lcbiAgICAgICAgICAgIF0sIFtNT0RFTCwgW1ZFTkRPUiwgJ1NvbnknXSwgW1RZUEUsIE1PQklMRV1dLCBbXG5cbiAgICAgICAgICAgIC9cXHMob3V5YSlcXHMvaSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBPdXlhXG4gICAgICAgICAgICAvKG5pbnRlbmRvKVxccyhbd2lkczN1XSspL2kgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBOaW50ZW5kb1xuICAgICAgICAgICAgXSwgW1ZFTkRPUiwgTU9ERUwsIFtUWVBFLCBDT05TT0xFXV0sIFtcblxuICAgICAgICAgICAgL2FuZHJvaWQuKztcXHMoc2hpZWxkKVxcc2J1aWxkL2kgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE52aWRpYVxuICAgICAgICAgICAgXSwgW01PREVMLCBbVkVORE9SLCAnTnZpZGlhJ10sIFtUWVBFLCBDT05TT0xFXV0sIFtcblxuICAgICAgICAgICAgLyhwbGF5c3RhdGlvblxcc1szNHBvcnRhYmxldmldKykvaSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gUGxheXN0YXRpb25cbiAgICAgICAgICAgIF0sIFtNT0RFTCwgW1ZFTkRPUiwgJ1NvbnknXSwgW1RZUEUsIENPTlNPTEVdXSwgW1xuXG4gICAgICAgICAgICAvKHNwcmludFxccyhcXHcrKSkvaSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gU3ByaW50IFBob25lc1xuICAgICAgICAgICAgXSwgW1tWRU5ET1IsIG1hcHBlci5zdHIsIG1hcHMuZGV2aWNlLnNwcmludC52ZW5kb3JdLCBbTU9ERUwsIG1hcHBlci5zdHIsIG1hcHMuZGV2aWNlLnNwcmludC5tb2RlbF0sIFtUWVBFLCBNT0JJTEVdXSwgW1xuXG4gICAgICAgICAgICAvKGxlbm92bylcXHM/KFMoPzo1MDAwfDYwMDApKyg/OlstXVtcXHcrXSkpL2kgICAgICAgICAgICAgICAgICAgICAgICAgLy8gTGVub3ZvIHRhYmxldHNcbiAgICAgICAgICAgIF0sIFtWRU5ET1IsIE1PREVMLCBbVFlQRSwgVEFCTEVUXV0sIFtcblxuICAgICAgICAgICAgLyhodGMpWztfXFxzLV0rKFtcXHdcXHNdKyg/PVxcKSl8XFx3KykqL2ksICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEhUQ1xuICAgICAgICAgICAgLyh6dGUpLShcXHcrKSovaSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gWlRFXG4gICAgICAgICAgICAvKGFsY2F0ZWx8Z2Vla3NwaG9uZXxsZW5vdm98bmV4aWFufHBhbmFzb25pY3woPz07XFxzKXNvbnkpW19cXHMtXT8oW1xcdy1dKykqL2lcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQWxjYXRlbC9HZWVrc1Bob25lL0xlbm92by9OZXhpYW4vUGFuYXNvbmljL1NvbnlcbiAgICAgICAgICAgIF0sIFtWRU5ET1IsIFtNT0RFTCwgL18vZywgJyAnXSwgW1RZUEUsIE1PQklMRV1dLCBbXG5cbiAgICAgICAgICAgIC8obmV4dXNcXHM5KS9pICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEhUQyBOZXh1cyA5XG4gICAgICAgICAgICBdLCBbTU9ERUwsIFtWRU5ET1IsICdIVEMnXSwgW1RZUEUsIFRBQkxFVF1dLCBbXG5cbiAgICAgICAgICAgIC9kXFwvaHVhd2VpKFtcXHdcXHMtXSspWztcXCldL2ksXG4gICAgICAgICAgICAvKG5leHVzXFxzNnApL2kgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBIdWF3ZWlcbiAgICAgICAgICAgIF0sIFtNT0RFTCwgW1ZFTkRPUiwgJ0h1YXdlaSddLCBbVFlQRSwgTU9CSUxFXV0sIFtcblxuICAgICAgICAgICAgLyhtaWNyb3NvZnQpO1xccyhsdW1pYVtcXHNcXHddKykvaSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBNaWNyb3NvZnQgTHVtaWFcbiAgICAgICAgICAgIF0sIFtWRU5ET1IsIE1PREVMLCBbVFlQRSwgTU9CSUxFXV0sIFtcblxuICAgICAgICAgICAgL1tcXHNcXCg7XSh4Ym94KD86XFxzb25lKT8pW1xcc1xcKTtdL2kgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE1pY3Jvc29mdCBYYm94XG4gICAgICAgICAgICBdLCBbTU9ERUwsIFtWRU5ET1IsICdNaWNyb3NvZnQnXSwgW1RZUEUsIENPTlNPTEVdXSwgW1xuICAgICAgICAgICAgLyhraW5cXC5bb25ldHddezN9KS9pICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gTWljcm9zb2Z0IEtpblxuICAgICAgICAgICAgXSwgW1tNT0RFTCwgL1xcLi9nLCAnICddLCBbVkVORE9SLCAnTWljcm9zb2Z0J10sIFtUWVBFLCBNT0JJTEVdXSwgW1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE1vdG9yb2xhXG4gICAgICAgICAgICAvXFxzKG1pbGVzdG9uZXxkcm9pZCg/OlsyLTR4XXxcXHMoPzpiaW9uaWN8eDJ8cHJvfHJhenIpKT8oOj9cXHM0Zyk/KVtcXHdcXHNdK2J1aWxkXFwvL2ksXG4gICAgICAgICAgICAvbW90W1xccy1dPyhcXHcrKSovaSxcbiAgICAgICAgICAgIC8oWFRcXGR7Myw0fSkgYnVpbGRcXC8vaSxcbiAgICAgICAgICAgIC8obmV4dXNcXHM2KS9pXG4gICAgICAgICAgICBdLCBbTU9ERUwsIFtWRU5ET1IsICdNb3Rvcm9sYSddLCBbVFlQRSwgTU9CSUxFXV0sIFtcbiAgICAgICAgICAgIC9hbmRyb2lkLitcXHMobXo2MFxcZHx4b29tW1xcczJdezAsMn0pXFxzYnVpbGRcXC8vaVxuICAgICAgICAgICAgXSwgW01PREVMLCBbVkVORE9SLCAnTW90b3JvbGEnXSwgW1RZUEUsIFRBQkxFVF1dLCBbXG5cbiAgICAgICAgICAgIC9oYmJ0dlxcL1xcZCtcXC5cXGQrXFwuXFxkK1xccytcXChbXFx3XFxzXSo7XFxzKihcXHdbXjtdKik7KFteO10qKS9pICAgICAgICAgICAgLy8gSGJiVFYgZGV2aWNlc1xuICAgICAgICAgICAgXSwgW1tWRU5ET1IsIHV0aWwudHJpbV0sIFtNT0RFTCwgdXRpbC50cmltXSwgW1RZUEUsIFNNQVJUVFZdXSwgW1xuXG4gICAgICAgICAgICAvaGJidHYuK21hcGxlOyhcXGQrKS9pXG4gICAgICAgICAgICBdLCBbW01PREVMLCAvXi8sICdTbWFydFRWJ10sIFtWRU5ET1IsICdTYW1zdW5nJ10sIFtUWVBFLCBTTUFSVFRWXV0sIFtcblxuICAgICAgICAgICAgL1xcKGR0dltcXCk7XS4rKGFxdW9zKS9pICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFNoYXJwXG4gICAgICAgICAgICBdLCBbTU9ERUwsIFtWRU5ET1IsICdTaGFycCddLCBbVFlQRSwgU01BUlRUVl1dLCBbXG5cbiAgICAgICAgICAgIC9hbmRyb2lkLisoKHNjaC1pWzg5XTBcXGR8c2h3LW0zODBzfGd0LXBcXGR7NH18Z3QtblxcZCt8c2doLXQ4WzU2XTl8bmV4dXMgMTApKS9pLFxuICAgICAgICAgICAgLygoU00tVFxcdyspKS9pXG4gICAgICAgICAgICBdLCBbW1ZFTkRPUiwgJ1NhbXN1bmcnXSwgTU9ERUwsIFtUWVBFLCBUQUJMRVRdXSwgWyAgICAgICAgICAgICAgICAgIC8vIFNhbXN1bmdcbiAgICAgICAgICAgIC9zbWFydC10di4rKHNhbXN1bmcpL2lcbiAgICAgICAgICAgIF0sIFtWRU5ET1IsIFtUWVBFLCBTTUFSVFRWXSwgTU9ERUxdLCBbXG4gICAgICAgICAgICAvKChzW2NncF1oLVxcdyt8Z3QtXFx3K3xnYWxheHlcXHNuZXh1c3xzbS1cXHdbXFx3XFxkXSspKS9pLFxuICAgICAgICAgICAgLyhzYW1bc3VuZ10qKVtcXHMtXSooXFx3Ky0/W1xcdy1dKikqL2ksXG4gICAgICAgICAgICAvc2VjLSgoc2doXFx3KykpL2lcbiAgICAgICAgICAgIF0sIFtbVkVORE9SLCAnU2Ftc3VuZyddLCBNT0RFTCwgW1RZUEUsIE1PQklMRV1dLCBbXG5cbiAgICAgICAgICAgIC9zaWUtKFxcdyspKi9pICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFNpZW1lbnNcbiAgICAgICAgICAgIF0sIFtNT0RFTCwgW1ZFTkRPUiwgJ1NpZW1lbnMnXSwgW1RZUEUsIE1PQklMRV1dLCBbXG5cbiAgICAgICAgICAgIC8obWFlbW98bm9raWEpLioobjkwMHxsdW1pYVxcc1xcZCspL2ksICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBOb2tpYVxuICAgICAgICAgICAgLyhub2tpYSlbXFxzXy1dPyhbXFx3LV0rKSovaVxuICAgICAgICAgICAgXSwgW1tWRU5ET1IsICdOb2tpYSddLCBNT0RFTCwgW1RZUEUsIE1PQklMRV1dLCBbXG5cbiAgICAgICAgICAgIC9hbmRyb2lkXFxzM1xcLltcXHNcXHc7LV17MTB9KGFcXGR7M30pL2kgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBBY2VyXG4gICAgICAgICAgICBdLCBbTU9ERUwsIFtWRU5ET1IsICdBY2VyJ10sIFtUWVBFLCBUQUJMRVRdXSwgW1xuXG4gICAgICAgICAgICAvYW5kcm9pZC4rKFt2bF1rXFwtP1xcZHszfSlcXHMrYnVpbGQvaSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIExHIFRhYmxldFxuICAgICAgICAgICAgXSwgW01PREVMLCBbVkVORE9SLCAnTEcnXSwgW1RZUEUsIFRBQkxFVF1dLCBbXG4gICAgICAgICAgICAvYW5kcm9pZFxcczNcXC5bXFxzXFx3Oy1dezEwfShsZz8pLShbMDZjdjldezMsNH0pL2kgICAgICAgICAgICAgICAgICAgICAvLyBMRyBUYWJsZXRcbiAgICAgICAgICAgIF0sIFtbVkVORE9SLCAnTEcnXSwgTU9ERUwsIFtUWVBFLCBUQUJMRVRdXSwgW1xuICAgICAgICAgICAgLyhsZykgbmV0Y2FzdFxcLnR2L2kgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gTEcgU21hcnRUVlxuICAgICAgICAgICAgXSwgW1ZFTkRPUiwgTU9ERUwsIFtUWVBFLCBTTUFSVFRWXV0sIFtcbiAgICAgICAgICAgIC8obmV4dXNcXHNbNDVdKS9pLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIExHXG4gICAgICAgICAgICAvbGdbZTtcXHNcXC8tXSsoXFx3KykqL2ksXG4gICAgICAgICAgICAvYW5kcm9pZC4rbGcoXFwtP1tcXGRcXHddKylcXHMrYnVpbGQvaVxuICAgICAgICAgICAgXSwgW01PREVMLCBbVkVORE9SLCAnTEcnXSwgW1RZUEUsIE1PQklMRV1dLCBbXG5cbiAgICAgICAgICAgIC9hbmRyb2lkLisoaWRlYXRhYlthLXowLTlcXC1cXHNdKykvaSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBMZW5vdm9cbiAgICAgICAgICAgIF0sIFtNT0RFTCwgW1ZFTkRPUiwgJ0xlbm92byddLCBbVFlQRSwgVEFCTEVUXV0sIFtcblxuICAgICAgICAgICAgL2xpbnV4Oy4rKChqb2xsYSkpOy9pICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBKb2xsYVxuICAgICAgICAgICAgXSwgW1ZFTkRPUiwgTU9ERUwsIFtUWVBFLCBNT0JJTEVdXSwgW1xuXG4gICAgICAgICAgICAvKChwZWJibGUpKWFwcFxcL1tcXGRcXC5dK1xccy9pICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBQZWJibGVcbiAgICAgICAgICAgIF0sIFtWRU5ET1IsIE1PREVMLCBbVFlQRSwgV0VBUkFCTEVdXSwgW1xuXG4gICAgICAgICAgICAvYW5kcm9pZC4rO1xccyhvcHBvKVxccz8oW1xcd1xcc10rKVxcc2J1aWxkL2kgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gT1BQT1xuICAgICAgICAgICAgXSwgW1ZFTkRPUiwgTU9ERUwsIFtUWVBFLCBNT0JJTEVdXSwgW1xuXG4gICAgICAgICAgICAvY3JrZXkvaSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEdvb2dsZSBDaHJvbWVjYXN0XG4gICAgICAgICAgICBdLCBbW01PREVMLCAnQ2hyb21lY2FzdCddLCBbVkVORE9SLCAnR29vZ2xlJ11dLCBbXG5cbiAgICAgICAgICAgIC9hbmRyb2lkLis7XFxzKGdsYXNzKVxcc1xcZC9pICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gR29vZ2xlIEdsYXNzXG4gICAgICAgICAgICBdLCBbTU9ERUwsIFtWRU5ET1IsICdHb29nbGUnXSwgW1RZUEUsIFdFQVJBQkxFXV0sIFtcblxuICAgICAgICAgICAgL2FuZHJvaWQuKztcXHMocGl4ZWwgYylcXHMvaSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEdvb2dsZSBQaXhlbCBDXG4gICAgICAgICAgICBdLCBbTU9ERUwsIFtWRU5ET1IsICdHb29nbGUnXSwgW1RZUEUsIFRBQkxFVF1dLCBbXG5cbiAgICAgICAgICAgIC9hbmRyb2lkLis7XFxzKHBpeGVsIHhsfHBpeGVsKVxccy9pICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBHb29nbGUgUGl4ZWxcbiAgICAgICAgICAgIF0sIFtNT0RFTCwgW1ZFTkRPUiwgJ0dvb2dsZSddLCBbVFlQRSwgTU9CSUxFXV0sIFtcblxuICAgICAgICAgICAgL2FuZHJvaWQuKyhcXHcrKVxccytidWlsZFxcL2htXFwxL2ksICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gWGlhb21pIEhvbmdtaSAnbnVtZXJpYycgbW9kZWxzXG4gICAgICAgICAgICAvYW5kcm9pZC4rKGhtW1xcc1xcLV9dKm5vdGU/W1xcc19dKig/OlxcZFxcdyk/KVxccytidWlsZC9pLCAgICAgICAgICAgICAgIC8vIFhpYW9taSBIb25nbWlcbiAgICAgICAgICAgIC9hbmRyb2lkLisobWlbXFxzXFwtX10qKD86b25lfG9uZVtcXHNfXXBsdXN8bm90ZSBsdGUpP1tcXHNfXSooPzpcXGRcXHcpPylcXHMrYnVpbGQvaSAgICAvLyBYaWFvbWkgTWlcbiAgICAgICAgICAgIF0sIFtbTU9ERUwsIC9fL2csICcgJ10sIFtWRU5ET1IsICdYaWFvbWknXSwgW1RZUEUsIE1PQklMRV1dLCBbXG5cbiAgICAgICAgICAgIC9hbmRyb2lkLis7XFxzKG1bMS01XVxcc25vdGUpXFxzYnVpbGQvaSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gTWVpenUgVGFibGV0XG4gICAgICAgICAgICBdLCBbTU9ERUwsIFtWRU5ET1IsICdNZWl6dSddLCBbVFlQRSwgVEFCTEVUXV0sIFtcblxuICAgICAgICAgICAgL2FuZHJvaWQuK2EwMDAoMSlcXHMrYnVpbGQvaSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gT25lUGx1c1xuICAgICAgICAgICAgXSwgW01PREVMLCBbVkVORE9SLCAnT25lUGx1cyddLCBbVFlQRSwgTU9CSUxFXV0sIFtcblxuICAgICAgICAgICAgL2FuZHJvaWQuK1s7XFwvXVxccyooUkNUW1xcZFxcd10rKVxccytidWlsZC9pICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFJDQSBUYWJsZXRzXG4gICAgICAgICAgICBdLCBbTU9ERUwsIFtWRU5ET1IsICdSQ0EnXSwgW1RZUEUsIFRBQkxFVF1dLCBbXG5cbiAgICAgICAgICAgIC9hbmRyb2lkLitbO1xcL11cXHMqKFZlbnVlW1xcZFxcc10qKVxccytidWlsZC9pICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBEZWxsIFZlbnVlIFRhYmxldHNcbiAgICAgICAgICAgIF0sIFtNT0RFTCwgW1ZFTkRPUiwgJ0RlbGwnXSwgW1RZUEUsIFRBQkxFVF1dLCBbXG5cbiAgICAgICAgICAgIC9hbmRyb2lkLitbO1xcL11cXHMqKFFbVHxNXVtcXGRcXHddKylcXHMrYnVpbGQvaSAgICAgICAgICAgICAgICAgICAgICAgICAvLyBWZXJpem9uIFRhYmxldFxuICAgICAgICAgICAgXSwgW01PREVMLCBbVkVORE9SLCAnVmVyaXpvbiddLCBbVFlQRSwgVEFCTEVUXV0sIFtcblxuICAgICAgICAgICAgL2FuZHJvaWQuK1s7XFwvXVxccysoQmFybmVzWyZcXHNdK05vYmxlXFxzK3xCTltSVF0pKFY/LiopXFxzK2J1aWxkL2kgICAgIC8vIEJhcm5lcyAmIE5vYmxlIFRhYmxldFxuICAgICAgICAgICAgXSwgW1tWRU5ET1IsICdCYXJuZXMgJiBOb2JsZSddLCBNT0RFTCwgW1RZUEUsIFRBQkxFVF1dLCBbXG5cbiAgICAgICAgICAgIC9hbmRyb2lkLitbO1xcL11cXHMrKFRNXFxkezN9LipcXGIpXFxzK2J1aWxkL2kgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBCYXJuZXMgJiBOb2JsZSBUYWJsZXRcbiAgICAgICAgICAgIF0sIFtNT0RFTCwgW1ZFTkRPUiwgJ051VmlzaW9uJ10sIFtUWVBFLCBUQUJMRVRdXSwgW1xuXG4gICAgICAgICAgICAvYW5kcm9pZC4rWztcXC9dXFxzKih6dGUpPy4rKGtcXGR7Mn0pXFxzK2J1aWxkL2kgICAgICAgICAgICAgICAgICAgICAgICAvLyBaVEUgSyBTZXJpZXMgVGFibGV0XG4gICAgICAgICAgICBdLCBbW1ZFTkRPUiwgJ1pURSddLCBNT0RFTCwgW1RZUEUsIFRBQkxFVF1dLCBbXG5cbiAgICAgICAgICAgIC9hbmRyb2lkLitbO1xcL11cXHMqKGdlblxcZHszfSlcXHMrYnVpbGQuKjQ5aC9pICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFN3aXNzIEdFTiBNb2JpbGVcbiAgICAgICAgICAgIF0sIFtNT0RFTCwgW1ZFTkRPUiwgJ1N3aXNzJ10sIFtUWVBFLCBNT0JJTEVdXSwgW1xuXG4gICAgICAgICAgICAvYW5kcm9pZC4rWztcXC9dXFxzKih6dXJcXGR7M30pXFxzK2J1aWxkL2kgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBTd2lzcyBaVVIgVGFibGV0XG4gICAgICAgICAgICBdLCBbTU9ERUwsIFtWRU5ET1IsICdTd2lzcyddLCBbVFlQRSwgVEFCTEVUXV0sIFtcblxuICAgICAgICAgICAgL2FuZHJvaWQuK1s7XFwvXVxccyooKFpla2kpP1RCLipcXGIpXFxzK2J1aWxkL2kgICAgICAgICAgICAgICAgICAgICAgICAgLy8gWmVraSBUYWJsZXRzXG4gICAgICAgICAgICBdLCBbTU9ERUwsIFtWRU5ET1IsICdaZWtpJ10sIFtUWVBFLCBUQUJMRVRdXSwgW1xuXG4gICAgICAgICAgICAvKGFuZHJvaWQpLitbO1xcL11cXHMrKFtZUl1cXGR7Mn14Py4qKVxccytidWlsZC9pLFxuICAgICAgICAgICAgL2FuZHJvaWQuK1s7XFwvXVxccysoRHJhZ29uW1xcLVxcc10rVG91Y2hcXHMrfERUKSguKylcXHMrYnVpbGQvaSAgICAgICAgICAvLyBEcmFnb24gVG91Y2ggVGFibGV0XG4gICAgICAgICAgICBdLCBbW1ZFTkRPUiwgJ0RyYWdvbiBUb3VjaCddLCBNT0RFTCwgW1RZUEUsIFRBQkxFVF1dLCBbXG5cbiAgICAgICAgICAgIC9hbmRyb2lkLitbO1xcL11cXHMqKE5TLT8uKylcXHMrYnVpbGQvaSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gSW5zaWduaWEgVGFibGV0c1xuICAgICAgICAgICAgXSwgW01PREVMLCBbVkVORE9SLCAnSW5zaWduaWEnXSwgW1RZUEUsIFRBQkxFVF1dLCBbXG5cbiAgICAgICAgICAgIC9hbmRyb2lkLitbO1xcL11cXHMqKChOWHxOZXh0KS0/LispXFxzK2J1aWxkL2kgICAgICAgICAgICAgICAgICAgICAgICAgLy8gTmV4dEJvb2sgVGFibGV0c1xuICAgICAgICAgICAgXSwgW01PREVMLCBbVkVORE9SLCAnTmV4dEJvb2snXSwgW1RZUEUsIFRBQkxFVF1dLCBbXG5cbiAgICAgICAgICAgIC9hbmRyb2lkLitbO1xcL11cXHMqKFh0cmVtZVxcXz8pPyhWKDFbMDQ1XXwyWzAxNV18MzB8NDB8NjB8N1swNV18OTApKVxccytidWlsZC9pXG4gICAgICAgICAgICBdLCBbW1ZFTkRPUiwgJ1ZvaWNlJ10sIE1PREVMLCBbVFlQRSwgTU9CSUxFXV0sIFsgICAgICAgICAgICAgICAgICAgIC8vIFZvaWNlIFh0cmVtZSBQaG9uZXNcblxuICAgICAgICAgICAgL2FuZHJvaWQuK1s7XFwvXVxccyooTFZURUxcXC0/KT8oVjFbMTJdKVxccytidWlsZC9pICAgICAgICAgICAgICAgICAgICAgLy8gTHZUZWwgUGhvbmVzXG4gICAgICAgICAgICBdLCBbW1ZFTkRPUiwgJ0x2VGVsJ10sIE1PREVMLCBbVFlQRSwgTU9CSUxFXV0sIFtcblxuICAgICAgICAgICAgL2FuZHJvaWQuK1s7XFwvXVxccyooVigxMDBNRHw3MDBOQXw3MDExfDkxN0cpLipcXGIpXFxzK2J1aWxkL2kgICAgICAgICAgLy8gRW52aXplbiBUYWJsZXRzXG4gICAgICAgICAgICBdLCBbTU9ERUwsIFtWRU5ET1IsICdFbnZpemVuJ10sIFtUWVBFLCBUQUJMRVRdXSwgW1xuXG4gICAgICAgICAgICAvYW5kcm9pZC4rWztcXC9dXFxzKihMZVtcXHNcXC1dK1BhbilbXFxzXFwtXSsoLipcXGIpXFxzK2J1aWxkL2kgICAgICAgICAgICAgLy8gTGUgUGFuIFRhYmxldHNcbiAgICAgICAgICAgIF0sIFtWRU5ET1IsIE1PREVMLCBbVFlQRSwgVEFCTEVUXV0sIFtcblxuICAgICAgICAgICAgL2FuZHJvaWQuK1s7XFwvXVxccyooVHJpb1tcXHNcXC1dKi4qKVxccytidWlsZC9pICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE1hY2hTcGVlZCBUYWJsZXRzXG4gICAgICAgICAgICBdLCBbTU9ERUwsIFtWRU5ET1IsICdNYWNoU3BlZWQnXSwgW1RZUEUsIFRBQkxFVF1dLCBbXG5cbiAgICAgICAgICAgIC9hbmRyb2lkLitbO1xcL11cXHMqKFRyaW5pdHkpW1xcLVxcc10qKFRcXGR7M30pXFxzK2J1aWxkL2kgICAgICAgICAgICAgICAgLy8gVHJpbml0eSBUYWJsZXRzXG4gICAgICAgICAgICBdLCBbVkVORE9SLCBNT0RFTCwgW1RZUEUsIFRBQkxFVF1dLCBbXG5cbiAgICAgICAgICAgIC9hbmRyb2lkLitbO1xcL11cXHMqVFVfKDE0OTEpXFxzK2J1aWxkL2kgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gUm90b3IgVGFibGV0c1xuICAgICAgICAgICAgXSwgW01PREVMLCBbVkVORE9SLCAnUm90b3InXSwgW1RZUEUsIFRBQkxFVF1dLCBbXG5cbiAgICAgICAgICAgIC9hbmRyb2lkLisoS1MoLispKVxccytidWlsZC9pICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEFtYXpvbiBLaW5kbGUgVGFibGV0c1xuICAgICAgICAgICAgXSwgW01PREVMLCBbVkVORE9SLCAnQW1hem9uJ10sIFtUWVBFLCBUQUJMRVRdXSwgW1xuXG4gICAgICAgICAgICAvYW5kcm9pZC4rKEdpZ2FzZXQpW1xcc1xcLV0rKFEuKylcXHMrYnVpbGQvaSAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEdpZ2FzZXQgVGFibGV0c1xuICAgICAgICAgICAgXSwgW1ZFTkRPUiwgTU9ERUwsIFtUWVBFLCBUQUJMRVRdXSwgW1xuXG4gICAgICAgICAgICAvXFxzKHRhYmxldHx0YWIpWztcXC9dL2ksICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gVW5pZGVudGlmaWFibGUgVGFibGV0XG4gICAgICAgICAgICAvXFxzKG1vYmlsZSkoPzpbO1xcL118XFxzc2FmYXJpKS9pICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFVuaWRlbnRpZmlhYmxlIE1vYmlsZVxuICAgICAgICAgICAgXSwgW1tUWVBFLCB1dGlsLmxvd2VyaXplXSwgVkVORE9SLCBNT0RFTF0sIFtcblxuICAgICAgICAgICAgLyhhbmRyb2lkLispWztcXC9dLitidWlsZC9pICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gR2VuZXJpYyBBbmRyb2lkIERldmljZVxuICAgICAgICAgICAgXSwgW01PREVMLCBbVkVORE9SLCAnR2VuZXJpYyddXVxuXG5cbiAgICAgICAgLyovLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuICAgICAgICAgICAgLy8gVE9ETzogbW92ZSB0byBzdHJpbmcgbWFwXG4gICAgICAgICAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbiAgICAgICAgICAgIC8oQzY2MDMpL2kgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gU29ueSBYcGVyaWEgWiBDNjYwM1xuICAgICAgICAgICAgXSwgW1tNT0RFTCwgJ1hwZXJpYSBaIEM2NjAzJ10sIFtWRU5ET1IsICdTb255J10sIFtUWVBFLCBNT0JJTEVdXSwgW1xuICAgICAgICAgICAgLyhDNjkwMykvaSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBTb255IFhwZXJpYSBaIDFcbiAgICAgICAgICAgIF0sIFtbTU9ERUwsICdYcGVyaWEgWiAxJ10sIFtWRU5ET1IsICdTb255J10sIFtUWVBFLCBNT0JJTEVdXSwgW1xuXG4gICAgICAgICAgICAvKFNNLUc5MDBbRnxIXSkvaSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFNhbXN1bmcgR2FsYXh5IFM1XG4gICAgICAgICAgICBdLCBbW01PREVMLCAnR2FsYXh5IFM1J10sIFtWRU5ET1IsICdTYW1zdW5nJ10sIFtUWVBFLCBNT0JJTEVdXSwgW1xuICAgICAgICAgICAgLyhTTS1HNzEwMikvaSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBTYW1zdW5nIEdhbGF4eSBHcmFuZCAyXG4gICAgICAgICAgICBdLCBbW01PREVMLCAnR2FsYXh5IEdyYW5kIDInXSwgW1ZFTkRPUiwgJ1NhbXN1bmcnXSwgW1RZUEUsIE1PQklMRV1dLCBbXG4gICAgICAgICAgICAvKFNNLUc1MzBIKS9pICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFNhbXN1bmcgR2FsYXh5IEdyYW5kIFByaW1lXG4gICAgICAgICAgICBdLCBbW01PREVMLCAnR2FsYXh5IEdyYW5kIFByaW1lJ10sIFtWRU5ET1IsICdTYW1zdW5nJ10sIFtUWVBFLCBNT0JJTEVdXSwgW1xuICAgICAgICAgICAgLyhTTS1HMzEzSFopL2kgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBTYW1zdW5nIEdhbGF4eSBWXG4gICAgICAgICAgICBdLCBbW01PREVMLCAnR2FsYXh5IFYnXSwgW1ZFTkRPUiwgJ1NhbXN1bmcnXSwgW1RZUEUsIE1PQklMRV1dLCBbXG4gICAgICAgICAgICAvKFNNLVQ4MDUpL2kgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFNhbXN1bmcgR2FsYXh5IFRhYiBTIDEwLjVcbiAgICAgICAgICAgIF0sIFtbTU9ERUwsICdHYWxheHkgVGFiIFMgMTAuNSddLCBbVkVORE9SLCAnU2Ftc3VuZyddLCBbVFlQRSwgVEFCTEVUXV0sIFtcbiAgICAgICAgICAgIC8oU00tRzgwMEYpL2kgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gU2Ftc3VuZyBHYWxheHkgUzUgTWluaVxuICAgICAgICAgICAgXSwgW1tNT0RFTCwgJ0dhbGF4eSBTNSBNaW5pJ10sIFtWRU5ET1IsICdTYW1zdW5nJ10sIFtUWVBFLCBNT0JJTEVdXSwgW1xuICAgICAgICAgICAgLyhTTS1UMzExKS9pICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBTYW1zdW5nIEdhbGF4eSBUYWIgMyA4LjBcbiAgICAgICAgICAgIF0sIFtbTU9ERUwsICdHYWxheHkgVGFiIDMgOC4wJ10sIFtWRU5ET1IsICdTYW1zdW5nJ10sIFtUWVBFLCBUQUJMRVRdXSwgW1xuXG4gICAgICAgICAgICAvKFQzQykvaSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEFkdmFuIFZhbmRyb2lkIFQzQ1xuICAgICAgICAgICAgXSwgW01PREVMLCBbVkVORE9SLCAnQWR2YW4nXSwgW1RZUEUsIFRBQkxFVF1dLCBbXG4gICAgICAgICAgICAvKEFEVkFOIFQxSlxcKykvaSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBBZHZhbiBWYW5kcm9pZCBUMUorXG4gICAgICAgICAgICBdLCBbW01PREVMLCAnVmFuZHJvaWQgVDFKKyddLCBbVkVORE9SLCAnQWR2YW4nXSwgW1RZUEUsIFRBQkxFVF1dLCBbXG4gICAgICAgICAgICAvKEFEVkFOIFM0QSkvaSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEFkdmFuIFZhbmRyb2lkIFM0QVxuICAgICAgICAgICAgXSwgW1tNT0RFTCwgJ1ZhbmRyb2lkIFM0QSddLCBbVkVORE9SLCAnQWR2YW4nXSwgW1RZUEUsIE1PQklMRV1dLCBbXG5cbiAgICAgICAgICAgIC8oVjk3Mk0pL2kgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gWlRFIFY5NzJNXG4gICAgICAgICAgICBdLCBbTU9ERUwsIFtWRU5ET1IsICdaVEUnXSwgW1RZUEUsIE1PQklMRV1dLCBbXG5cbiAgICAgICAgICAgIC8oaS1tb2JpbGUpXFxzKElRXFxzW1xcZFxcLl0rKS9pICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGktbW9iaWxlIElRXG4gICAgICAgICAgICBdLCBbVkVORE9SLCBNT0RFTCwgW1RZUEUsIE1PQklMRV1dLCBbXG4gICAgICAgICAgICAvKElRNi4zKS9pICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGktbW9iaWxlIElRIElRIDYuM1xuICAgICAgICAgICAgXSwgW1tNT0RFTCwgJ0lRIDYuMyddLCBbVkVORE9SLCAnaS1tb2JpbGUnXSwgW1RZUEUsIE1PQklMRV1dLCBbXG4gICAgICAgICAgICAvKGktbW9iaWxlKVxccyhpLXN0eWxlXFxzW1xcZFxcLl0rKS9pICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBpLW1vYmlsZSBpLVNUWUxFXG4gICAgICAgICAgICBdLCBbVkVORE9SLCBNT0RFTCwgW1RZUEUsIE1PQklMRV1dLCBbXG4gICAgICAgICAgICAvKGktU1RZTEUyLjEpL2kgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGktbW9iaWxlIGktU1RZTEUgMi4xXG4gICAgICAgICAgICBdLCBbW01PREVMLCAnaS1TVFlMRSAyLjEnXSwgW1ZFTkRPUiwgJ2ktbW9iaWxlJ10sIFtUWVBFLCBNT0JJTEVdXSwgW1xuXG4gICAgICAgICAgICAvKG1vYmlpc3RhciB0b3VjaCBMQUkgNTEyKS9pICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIG1vYmlpc3RhciB0b3VjaCBMQUkgNTEyXG4gICAgICAgICAgICBdLCBbW01PREVMLCAnVG91Y2ggTEFJIDUxMiddLCBbVkVORE9SLCAnbW9iaWlzdGFyJ10sIFtUWVBFLCBNT0JJTEVdXSwgW1xuXG4gICAgICAgICAgICAvLy8vLy8vLy8vLy8vXG4gICAgICAgICAgICAvLyBFTkQgVE9ET1xuICAgICAgICAgICAgLy8vLy8vLy8vLy8qL1xuXG4gICAgICAgIF0sXG5cbiAgICAgICAgZW5naW5lIDogW1tcblxuICAgICAgICAgICAgL3dpbmRvd3MuK1xcc2VkZ2VcXC8oW1xcd1xcLl0rKS9pICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gRWRnZUhUTUxcbiAgICAgICAgICAgIF0sIFtWRVJTSU9OLCBbTkFNRSwgJ0VkZ2VIVE1MJ11dLCBbXG5cbiAgICAgICAgICAgIC8ocHJlc3RvKVxcLyhbXFx3XFwuXSspL2ksICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gUHJlc3RvXG4gICAgICAgICAgICAvKHdlYmtpdHx0cmlkZW50fG5ldGZyb250fG5ldHN1cmZ8YW1heWF8bHlueHx3M20pXFwvKFtcXHdcXC5dKykvaSwgICAgIC8vIFdlYktpdC9UcmlkZW50L05ldEZyb250L05ldFN1cmYvQW1heWEvTHlueC93M21cbiAgICAgICAgICAgIC8oa2h0bWx8dGFzbWFufGxpbmtzKVtcXC9cXHNdXFwoPyhbXFx3XFwuXSspL2ksICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBLSFRNTC9UYXNtYW4vTGlua3NcbiAgICAgICAgICAgIC8oaWNhYilbXFwvXFxzXShbMjNdXFwuW1xcZFxcLl0rKS9pICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBpQ2FiXG4gICAgICAgICAgICBdLCBbTkFNRSwgVkVSU0lPTl0sIFtcblxuICAgICAgICAgICAgL3J2XFw6KFtcXHdcXC5dKykuKihnZWNrbykvaSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBHZWNrb1xuICAgICAgICAgICAgXSwgW1ZFUlNJT04sIE5BTUVdXG4gICAgICAgIF0sXG5cbiAgICAgICAgb3MgOiBbW1xuXG4gICAgICAgICAgICAvLyBXaW5kb3dzIGJhc2VkXG4gICAgICAgICAgICAvbWljcm9zb2Z0XFxzKHdpbmRvd3MpXFxzKHZpc3RhfHhwKS9pICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gV2luZG93cyAoaVR1bmVzKVxuICAgICAgICAgICAgXSwgW05BTUUsIFZFUlNJT05dLCBbXG4gICAgICAgICAgICAvKHdpbmRvd3MpXFxzbnRcXHM2XFwuMjtcXHMoYXJtKS9pLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBXaW5kb3dzIFJUXG4gICAgICAgICAgICAvKHdpbmRvd3NcXHNwaG9uZSg/Olxcc29zKSopW1xcc1xcL10/KFtcXGRcXC5cXHNdK1xcdykqL2ksICAgICAgICAgICAgICAgICAgLy8gV2luZG93cyBQaG9uZVxuICAgICAgICAgICAgLyh3aW5kb3dzXFxzbW9iaWxlfHdpbmRvd3MpW1xcc1xcL10/KFtudGNlXFxkXFwuXFxzXStcXHcpL2lcbiAgICAgICAgICAgIF0sIFtOQU1FLCBbVkVSU0lPTiwgbWFwcGVyLnN0ciwgbWFwcy5vcy53aW5kb3dzLnZlcnNpb25dXSwgW1xuICAgICAgICAgICAgLyh3aW4oPz0zfDl8bil8d2luXFxzOXhcXHMpKFtudFxcZFxcLl0rKS9pXG4gICAgICAgICAgICBdLCBbW05BTUUsICdXaW5kb3dzJ10sIFtWRVJTSU9OLCBtYXBwZXIuc3RyLCBtYXBzLm9zLndpbmRvd3MudmVyc2lvbl1dLCBbXG5cbiAgICAgICAgICAgIC8vIE1vYmlsZS9FbWJlZGRlZCBPU1xuICAgICAgICAgICAgL1xcKChiYikoMTApOy9pICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQmxhY2tCZXJyeSAxMFxuICAgICAgICAgICAgXSwgW1tOQU1FLCAnQmxhY2tCZXJyeSddLCBWRVJTSU9OXSwgW1xuICAgICAgICAgICAgLyhibGFja2JlcnJ5KVxcdypcXC8/KFtcXHdcXC5dKykqL2ksICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQmxhY2tiZXJyeVxuICAgICAgICAgICAgLyh0aXplbilbXFwvXFxzXShbXFx3XFwuXSspL2ksICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gVGl6ZW5cbiAgICAgICAgICAgIC8oYW5kcm9pZHx3ZWJvc3xwYWxtXFxzb3N8cW54fGJhZGF8cmltXFxzdGFibGV0XFxzb3N8bWVlZ298Y29udGlraSlbXFwvXFxzLV0/KFtcXHdcXC5dKykqL2ksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEFuZHJvaWQvV2ViT1MvUGFsbS9RTlgvQmFkYS9SSU0vTWVlR28vQ29udGlraVxuICAgICAgICAgICAgL2xpbnV4Oy4rKHNhaWxmaXNoKTsvaSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBTYWlsZmlzaCBPU1xuICAgICAgICAgICAgXSwgW05BTUUsIFZFUlNJT05dLCBbXG4gICAgICAgICAgICAvKHN5bWJpYW5cXHM/b3N8c3ltYm9zfHM2MCg/PTspKVtcXC9cXHMtXT8oW1xcd1xcLl0rKSovaSAgICAgICAgICAgICAgICAgLy8gU3ltYmlhblxuICAgICAgICAgICAgXSwgW1tOQU1FLCAnU3ltYmlhbiddLCBWRVJTSU9OXSwgW1xuICAgICAgICAgICAgL1xcKChzZXJpZXM0MCk7L2kgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gU2VyaWVzIDQwXG4gICAgICAgICAgICBdLCBbTkFNRV0sIFtcbiAgICAgICAgICAgIC9tb3ppbGxhLitcXChtb2JpbGU7LitnZWNrby4rZmlyZWZveC9pICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEZpcmVmb3ggT1NcbiAgICAgICAgICAgIF0sIFtbTkFNRSwgJ0ZpcmVmb3ggT1MnXSwgVkVSU0lPTl0sIFtcblxuICAgICAgICAgICAgLy8gQ29uc29sZVxuICAgICAgICAgICAgLyhuaW50ZW5kb3xwbGF5c3RhdGlvbilcXHMoW3dpZHMzNHBvcnRhYmxldnVdKykvaSwgICAgICAgICAgICAgICAgICAgLy8gTmludGVuZG8vUGxheXN0YXRpb25cblxuICAgICAgICAgICAgLy8gR05VL0xpbnV4IGJhc2VkXG4gICAgICAgICAgICAvKG1pbnQpW1xcL1xcc1xcKF0/KFxcdyspKi9pLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBNaW50XG4gICAgICAgICAgICAvKG1hZ2VpYXx2ZWN0b3JsaW51eClbO1xcc10vaSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBNYWdlaWEvVmVjdG9yTGludXhcbiAgICAgICAgICAgIC8oam9saXxba3hsbl0/dWJ1bnR1fGRlYmlhbnxbb3Blbl0qc3VzZXxnZW50b298KD89XFxzKWFyY2h8c2xhY2t3YXJlfGZlZG9yYXxtYW5kcml2YXxjZW50b3N8cGNsaW51eG9zfHJlZGhhdHx6ZW53YWxrfGxpbnB1cylbXFwvXFxzLV0/KD8hY2hyb20pKFtcXHdcXC4tXSspKi9pLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBKb2xpL1VidW50dS9EZWJpYW4vU1VTRS9HZW50b28vQXJjaC9TbGFja3dhcmVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gRmVkb3JhL01hbmRyaXZhL0NlbnRPUy9QQ0xpbnV4T1MvUmVkSGF0L1plbndhbGsvTGlucHVzXG4gICAgICAgICAgICAvKGh1cmR8bGludXgpXFxzPyhbXFx3XFwuXSspKi9pLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEh1cmQvTGludXhcbiAgICAgICAgICAgIC8oZ251KVxccz8oW1xcd1xcLl0rKSovaSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gR05VXG4gICAgICAgICAgICBdLCBbTkFNRSwgVkVSU0lPTl0sIFtcblxuICAgICAgICAgICAgLyhjcm9zKVxcc1tcXHddK1xccyhbXFx3XFwuXStcXHcpL2kgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBDaHJvbWl1bSBPU1xuICAgICAgICAgICAgXSwgW1tOQU1FLCAnQ2hyb21pdW0gT1MnXSwgVkVSU0lPTl0sW1xuXG4gICAgICAgICAgICAvLyBTb2xhcmlzXG4gICAgICAgICAgICAvKHN1bm9zKVxccz8oW1xcd1xcLl0rXFxkKSovaSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBTb2xhcmlzXG4gICAgICAgICAgICBdLCBbW05BTUUsICdTb2xhcmlzJ10sIFZFUlNJT05dLCBbXG5cbiAgICAgICAgICAgIC8vIEJTRCBiYXNlZFxuICAgICAgICAgICAgL1xccyhbZnJlbnRvcGMtXXswLDR9YnNkfGRyYWdvbmZseSlcXHM/KFtcXHdcXC5dKykqL2kgICAgICAgICAgICAgICAgICAgLy8gRnJlZUJTRC9OZXRCU0QvT3BlbkJTRC9QQy1CU0QvRHJhZ29uRmx5XG4gICAgICAgICAgICBdLCBbTkFNRSwgVkVSU0lPTl0sW1xuXG4gICAgICAgICAgICAvKGhhaWt1KVxccyhcXHcrKS9pICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBIYWlrdVxuICAgICAgICAgICAgXSwgW05BTUUsIFZFUlNJT05dLFtcblxuICAgICAgICAgICAgL2NmbmV0d29ya1xcLy4rZGFyd2luL2ksXG4gICAgICAgICAgICAvaXBbaG9uZWFkXSsoPzouKm9zXFxzKFtcXHddKykqXFxzbGlrZVxcc21hY3w7XFxzb3BlcmEpL2kgICAgICAgICAgICAgICAgLy8gaU9TXG4gICAgICAgICAgICBdLCBbW1ZFUlNJT04sIC9fL2csICcuJ10sIFtOQU1FLCAnaU9TJ11dLCBbXG5cbiAgICAgICAgICAgIC8obWFjXFxzb3NcXHN4KVxccz8oW1xcd1xcc1xcLl0rXFx3KSovaSxcbiAgICAgICAgICAgIC8obWFjaW50b3NofG1hYyg/PV9wb3dlcnBjKVxccykvaSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE1hYyBPU1xuICAgICAgICAgICAgXSwgW1tOQU1FLCAnTWFjIE9TJ10sIFtWRVJTSU9OLCAvXy9nLCAnLiddXSwgW1xuXG4gICAgICAgICAgICAvLyBPdGhlclxuICAgICAgICAgICAgLygoPzpvcGVuKT9zb2xhcmlzKVtcXC9cXHMtXT8oW1xcd1xcLl0rKSovaSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gU29sYXJpc1xuICAgICAgICAgICAgLyhhaXgpXFxzKChcXGQpKD89XFwufFxcKXxcXHMpW1xcd1xcLl0qKSovaSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQUlYXG4gICAgICAgICAgICAvKHBsYW5cXHM5fG1pbml4fGJlb3N8b3NcXC8yfGFtaWdhb3N8bW9ycGhvc3xyaXNjXFxzb3N8b3BlbnZtcykvaSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gUGxhbjkvTWluaXgvQmVPUy9PUzIvQW1pZ2FPUy9Nb3JwaE9TL1JJU0NPUy9PcGVuVk1TXG4gICAgICAgICAgICAvKHVuaXgpXFxzPyhbXFx3XFwuXSspKi9pICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFVOSVhcbiAgICAgICAgICAgIF0sIFtOQU1FLCBWRVJTSU9OXVxuICAgICAgICBdXG4gICAgfTtcblxuXG4gICAgLy8vLy8vLy8vLy8vLy8vLy9cbiAgICAvLyBDb25zdHJ1Y3RvclxuICAgIC8vLy8vLy8vLy8vLy8vLy9cblxuICAgIHZhciBCcm93c2VyID0gZnVuY3Rpb24gKG5hbWUsIHZlcnNpb24pIHtcbiAgICAgICAgdGhpc1tOQU1FXSA9IG5hbWU7XG4gICAgICAgIHRoaXNbVkVSU0lPTl0gPSB2ZXJzaW9uO1xuICAgIH07XG4gICAgdmFyIENQVSA9IGZ1bmN0aW9uIChhcmNoKSB7XG4gICAgICAgIHRoaXNbQVJDSElURUNUVVJFXSA9IGFyY2g7XG4gICAgfTtcbiAgICB2YXIgRGV2aWNlID0gZnVuY3Rpb24gKHZlbmRvciwgbW9kZWwsIHR5cGUpIHtcbiAgICAgICAgdGhpc1tWRU5ET1JdID0gdmVuZG9yO1xuICAgICAgICB0aGlzW01PREVMXSA9IG1vZGVsO1xuICAgICAgICB0aGlzW1RZUEVdID0gdHlwZTtcbiAgICB9O1xuICAgIHZhciBFbmdpbmUgPSBCcm93c2VyO1xuICAgIHZhciBPUyA9IEJyb3dzZXI7XG5cbiAgICB2YXIgVUFQYXJzZXIgPSBmdW5jdGlvbiAodWFzdHJpbmcsIGV4dGVuc2lvbnMpIHtcblxuICAgICAgICBpZiAodHlwZW9mIHVhc3RyaW5nID09PSAnb2JqZWN0Jykge1xuICAgICAgICAgICAgZXh0ZW5zaW9ucyA9IHVhc3RyaW5nO1xuICAgICAgICAgICAgdWFzdHJpbmcgPSB1bmRlZmluZWQ7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoISh0aGlzIGluc3RhbmNlb2YgVUFQYXJzZXIpKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IFVBUGFyc2VyKHVhc3RyaW5nLCBleHRlbnNpb25zKS5nZXRSZXN1bHQoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciB1YSA9IHVhc3RyaW5nIHx8ICgod2luZG93ICYmIHdpbmRvdy5uYXZpZ2F0b3IgJiYgd2luZG93Lm5hdmlnYXRvci51c2VyQWdlbnQpID8gd2luZG93Lm5hdmlnYXRvci51c2VyQWdlbnQgOiBFTVBUWSk7XG4gICAgICAgIHZhciByZ3htYXAgPSBleHRlbnNpb25zID8gdXRpbC5leHRlbmQocmVnZXhlcywgZXh0ZW5zaW9ucykgOiByZWdleGVzO1xuICAgICAgICB2YXIgYnJvd3NlciA9IG5ldyBCcm93c2VyKCk7XG4gICAgICAgIHZhciBjcHUgPSBuZXcgQ1BVKCk7XG4gICAgICAgIHZhciBkZXZpY2UgPSBuZXcgRGV2aWNlKCk7XG4gICAgICAgIHZhciBlbmdpbmUgPSBuZXcgRW5naW5lKCk7XG4gICAgICAgIHZhciBvcyA9IG5ldyBPUygpO1xuXG4gICAgICAgIHRoaXMuZ2V0QnJvd3NlciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIG1hcHBlci5yZ3guY2FsbChicm93c2VyLCB1YSwgcmd4bWFwLmJyb3dzZXIpO1xuICAgICAgICAgICAgYnJvd3Nlci5tYWpvciA9IHV0aWwubWFqb3IoYnJvd3Nlci52ZXJzaW9uKTsgLy8gZGVwcmVjYXRlZFxuICAgICAgICAgICAgcmV0dXJuIGJyb3dzZXI7XG4gICAgICAgIH07XG4gICAgICAgIHRoaXMuZ2V0Q1BVID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgbWFwcGVyLnJneC5jYWxsKGNwdSwgdWEsIHJneG1hcC5jcHUpO1xuICAgICAgICAgICAgcmV0dXJuIGNwdTtcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5nZXREZXZpY2UgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBtYXBwZXIucmd4LmNhbGwoZGV2aWNlLCB1YSwgcmd4bWFwLmRldmljZSk7XG4gICAgICAgICAgICByZXR1cm4gZGV2aWNlO1xuICAgICAgICB9O1xuICAgICAgICB0aGlzLmdldEVuZ2luZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIG1hcHBlci5yZ3guY2FsbChlbmdpbmUsIHVhLCByZ3htYXAuZW5naW5lKTtcbiAgICAgICAgICAgIHJldHVybiBlbmdpbmU7XG4gICAgICAgIH07XG4gICAgICAgIHRoaXMuZ2V0T1MgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBtYXBwZXIucmd4LmNhbGwob3MsIHVhLCByZ3htYXAub3MpO1xuICAgICAgICAgICAgcmV0dXJuIG9zO1xuICAgICAgICB9O1xuICAgICAgICB0aGlzLmdldFJlc3VsdCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgdWEgICAgICA6IHRoaXMuZ2V0VUEoKSxcbiAgICAgICAgICAgICAgICBicm93c2VyIDogdGhpcy5nZXRCcm93c2VyKCksXG4gICAgICAgICAgICAgICAgZW5naW5lICA6IHRoaXMuZ2V0RW5naW5lKCksXG4gICAgICAgICAgICAgICAgb3MgICAgICA6IHRoaXMuZ2V0T1MoKSxcbiAgICAgICAgICAgICAgICBkZXZpY2UgIDogdGhpcy5nZXREZXZpY2UoKSxcbiAgICAgICAgICAgICAgICBjcHUgICAgIDogdGhpcy5nZXRDUFUoKVxuICAgICAgICAgICAgfTtcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5nZXRVQSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHJldHVybiB1YTtcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5zZXRVQSA9IGZ1bmN0aW9uICh1YXN0cmluZykge1xuICAgICAgICAgICAgdWEgPSB1YXN0cmluZztcbiAgICAgICAgICAgIGJyb3dzZXIgPSBuZXcgQnJvd3NlcigpO1xuICAgICAgICAgICAgY3B1ID0gbmV3IENQVSgpO1xuICAgICAgICAgICAgZGV2aWNlID0gbmV3IERldmljZSgpO1xuICAgICAgICAgICAgZW5naW5lID0gbmV3IEVuZ2luZSgpO1xuICAgICAgICAgICAgb3MgPSBuZXcgT1MoKTtcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICB9O1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG4gICAgVUFQYXJzZXIuVkVSU0lPTiA9IExJQlZFUlNJT047XG4gICAgVUFQYXJzZXIuQlJPV1NFUiA9IHtcbiAgICAgICAgTkFNRSAgICA6IE5BTUUsXG4gICAgICAgIE1BSk9SICAgOiBNQUpPUiwgLy8gZGVwcmVjYXRlZFxuICAgICAgICBWRVJTSU9OIDogVkVSU0lPTlxuICAgIH07XG4gICAgVUFQYXJzZXIuQ1BVID0ge1xuICAgICAgICBBUkNISVRFQ1RVUkUgOiBBUkNISVRFQ1RVUkVcbiAgICB9O1xuICAgIFVBUGFyc2VyLkRFVklDRSA9IHtcbiAgICAgICAgTU9ERUwgICA6IE1PREVMLFxuICAgICAgICBWRU5ET1IgIDogVkVORE9SLFxuICAgICAgICBUWVBFICAgIDogVFlQRSxcbiAgICAgICAgQ09OU09MRSA6IENPTlNPTEUsXG4gICAgICAgIE1PQklMRSAgOiBNT0JJTEUsXG4gICAgICAgIFNNQVJUVFYgOiBTTUFSVFRWLFxuICAgICAgICBUQUJMRVQgIDogVEFCTEVULFxuICAgICAgICBXRUFSQUJMRTogV0VBUkFCTEUsXG4gICAgICAgIEVNQkVEREVEOiBFTUJFRERFRFxuICAgIH07XG4gICAgVUFQYXJzZXIuRU5HSU5FID0ge1xuICAgICAgICBOQU1FICAgIDogTkFNRSxcbiAgICAgICAgVkVSU0lPTiA6IFZFUlNJT05cbiAgICB9O1xuICAgIFVBUGFyc2VyLk9TID0ge1xuICAgICAgICBOQU1FICAgIDogTkFNRSxcbiAgICAgICAgVkVSU0lPTiA6IFZFUlNJT05cbiAgICB9O1xuICAgIC8vVUFQYXJzZXIuVXRpbHMgPSB1dGlsO1xuXG4gICAgLy8vLy8vLy8vLy9cbiAgICAvLyBFeHBvcnRcbiAgICAvLy8vLy8vLy8vXG5cblxuICAgIC8vIGNoZWNrIGpzIGVudmlyb25tZW50XG4gICAgaWYgKHR5cGVvZihleHBvcnRzKSAhPT0gVU5ERUZfVFlQRSkge1xuICAgICAgICAvLyBub2RlanMgZW52XG4gICAgICAgIGlmICh0eXBlb2YgbW9kdWxlICE9PSBVTkRFRl9UWVBFICYmIG1vZHVsZS5leHBvcnRzKSB7XG4gICAgICAgICAgICBleHBvcnRzID0gbW9kdWxlLmV4cG9ydHMgPSBVQVBhcnNlcjtcbiAgICAgICAgfVxuICAgICAgICBleHBvcnRzLlVBUGFyc2VyID0gVUFQYXJzZXI7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgLy8gcmVxdWlyZWpzIGVudiAob3B0aW9uYWwpXG4gICAgICAgIGlmICh0eXBlb2YoZGVmaW5lKSA9PT0gRlVOQ19UWVBFICYmIGRlZmluZS5hbWQpIHtcbiAgICAgICAgICAgIGRlZmluZShmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFVBUGFyc2VyO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSBpZiAod2luZG93KSB7XG4gICAgICAgICAgICAvLyBicm93c2VyIGVudlxuICAgICAgICAgICAgd2luZG93LlVBUGFyc2VyID0gVUFQYXJzZXI7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBqUXVlcnkvWmVwdG8gc3BlY2lmaWMgKG9wdGlvbmFsKVxuICAgIC8vIE5vdGU6XG4gICAgLy8gICBJbiBBTUQgZW52IHRoZSBnbG9iYWwgc2NvcGUgc2hvdWxkIGJlIGtlcHQgY2xlYW4sIGJ1dCBqUXVlcnkgaXMgYW4gZXhjZXB0aW9uLlxuICAgIC8vICAgalF1ZXJ5IGFsd2F5cyBleHBvcnRzIHRvIGdsb2JhbCBzY29wZSwgdW5sZXNzIGpRdWVyeS5ub0NvbmZsaWN0KHRydWUpIGlzIHVzZWQsXG4gICAgLy8gICBhbmQgd2Ugc2hvdWxkIGNhdGNoIHRoYXQuXG4gICAgdmFyICQgPSB3aW5kb3cgJiYgKHdpbmRvdy5qUXVlcnkgfHwgd2luZG93LlplcHRvKTtcbiAgICBpZiAodHlwZW9mICQgIT09IFVOREVGX1RZUEUpIHtcbiAgICAgICAgdmFyIHBhcnNlciA9IG5ldyBVQVBhcnNlcigpO1xuICAgICAgICAkLnVhID0gcGFyc2VyLmdldFJlc3VsdCgpO1xuICAgICAgICAkLnVhLmdldCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHJldHVybiBwYXJzZXIuZ2V0VUEoKTtcbiAgICAgICAgfTtcbiAgICAgICAgJC51YS5zZXQgPSBmdW5jdGlvbiAodWFzdHJpbmcpIHtcbiAgICAgICAgICAgIHBhcnNlci5zZXRVQSh1YXN0cmluZyk7XG4gICAgICAgICAgICB2YXIgcmVzdWx0ID0gcGFyc2VyLmdldFJlc3VsdCgpO1xuICAgICAgICAgICAgZm9yICh2YXIgcHJvcCBpbiByZXN1bHQpIHtcbiAgICAgICAgICAgICAgICAkLnVhW3Byb3BdID0gcmVzdWx0W3Byb3BdO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH1cblxufSkodHlwZW9mIHdpbmRvdyA9PT0gJ29iamVjdCcgPyB3aW5kb3cgOiB0aGlzKTtcbiIsIlxudmFyIHJuZztcblxudmFyIGNyeXB0byA9IGdsb2JhbC5jcnlwdG8gfHwgZ2xvYmFsLm1zQ3J5cHRvOyAvLyBmb3IgSUUgMTFcbmlmIChjcnlwdG8gJiYgY3J5cHRvLmdldFJhbmRvbVZhbHVlcykge1xuICAvLyBXSEFUV0cgY3J5cHRvLWJhc2VkIFJORyAtIGh0dHA6Ly93aWtpLndoYXR3Zy5vcmcvd2lraS9DcnlwdG9cbiAgLy8gTW9kZXJhdGVseSBmYXN0LCBoaWdoIHF1YWxpdHlcbiAgdmFyIF9ybmRzOCA9IG5ldyBVaW50OEFycmF5KDE2KTtcbiAgcm5nID0gZnVuY3Rpb24gd2hhdHdnUk5HKCkge1xuICAgIGNyeXB0by5nZXRSYW5kb21WYWx1ZXMoX3JuZHM4KTtcbiAgICByZXR1cm4gX3JuZHM4O1xuICB9O1xufVxuXG5pZiAoIXJuZykge1xuICAvLyBNYXRoLnJhbmRvbSgpLWJhc2VkIChSTkcpXG4gIC8vXG4gIC8vIElmIGFsbCBlbHNlIGZhaWxzLCB1c2UgTWF0aC5yYW5kb20oKS4gIEl0J3MgZmFzdCwgYnV0IGlzIG9mIHVuc3BlY2lmaWVkXG4gIC8vIHF1YWxpdHkuXG4gIHZhciAgX3JuZHMgPSBuZXcgQXJyYXkoMTYpO1xuICBybmcgPSBmdW5jdGlvbigpIHtcbiAgICBmb3IgKHZhciBpID0gMCwgcjsgaSA8IDE2OyBpKyspIHtcbiAgICAgIGlmICgoaSAmIDB4MDMpID09PSAwKSByID0gTWF0aC5yYW5kb20oKSAqIDB4MTAwMDAwMDAwO1xuICAgICAgX3JuZHNbaV0gPSByID4+PiAoKGkgJiAweDAzKSA8PCAzKSAmIDB4ZmY7XG4gICAgfVxuXG4gICAgcmV0dXJuIF9ybmRzO1xuICB9O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHJuZztcblxuIiwiLy8gICAgIHV1aWQuanNcbi8vXG4vLyAgICAgQ29weXJpZ2h0IChjKSAyMDEwLTIwMTIgUm9iZXJ0IEtpZWZmZXJcbi8vICAgICBNSVQgTGljZW5zZSAtIGh0dHA6Ly9vcGVuc291cmNlLm9yZy9saWNlbnNlcy9taXQtbGljZW5zZS5waHBcblxuLy8gVW5pcXVlIElEIGNyZWF0aW9uIHJlcXVpcmVzIGEgaGlnaCBxdWFsaXR5IHJhbmRvbSAjIGdlbmVyYXRvci4gIFdlIGZlYXR1cmVcbi8vIGRldGVjdCB0byBkZXRlcm1pbmUgdGhlIGJlc3QgUk5HIHNvdXJjZSwgbm9ybWFsaXppbmcgdG8gYSBmdW5jdGlvbiB0aGF0XG4vLyByZXR1cm5zIDEyOC1iaXRzIG9mIHJhbmRvbW5lc3MsIHNpbmNlIHRoYXQncyB3aGF0J3MgdXN1YWxseSByZXF1aXJlZFxudmFyIF9ybmcgPSByZXF1aXJlKCcuL3JuZycpO1xuXG4vLyBNYXBzIGZvciBudW1iZXIgPC0+IGhleCBzdHJpbmcgY29udmVyc2lvblxudmFyIF9ieXRlVG9IZXggPSBbXTtcbnZhciBfaGV4VG9CeXRlID0ge307XG5mb3IgKHZhciBpID0gMDsgaSA8IDI1NjsgaSsrKSB7XG4gIF9ieXRlVG9IZXhbaV0gPSAoaSArIDB4MTAwKS50b1N0cmluZygxNikuc3Vic3RyKDEpO1xuICBfaGV4VG9CeXRlW19ieXRlVG9IZXhbaV1dID0gaTtcbn1cblxuLy8gKipgcGFyc2UoKWAgLSBQYXJzZSBhIFVVSUQgaW50byBpdCdzIGNvbXBvbmVudCBieXRlcyoqXG5mdW5jdGlvbiBwYXJzZShzLCBidWYsIG9mZnNldCkge1xuICB2YXIgaSA9IChidWYgJiYgb2Zmc2V0KSB8fCAwLCBpaSA9IDA7XG5cbiAgYnVmID0gYnVmIHx8IFtdO1xuICBzLnRvTG93ZXJDYXNlKCkucmVwbGFjZSgvWzAtOWEtZl17Mn0vZywgZnVuY3Rpb24ob2N0KSB7XG4gICAgaWYgKGlpIDwgMTYpIHsgLy8gRG9uJ3Qgb3ZlcmZsb3chXG4gICAgICBidWZbaSArIGlpKytdID0gX2hleFRvQnl0ZVtvY3RdO1xuICAgIH1cbiAgfSk7XG5cbiAgLy8gWmVybyBvdXQgcmVtYWluaW5nIGJ5dGVzIGlmIHN0cmluZyB3YXMgc2hvcnRcbiAgd2hpbGUgKGlpIDwgMTYpIHtcbiAgICBidWZbaSArIGlpKytdID0gMDtcbiAgfVxuXG4gIHJldHVybiBidWY7XG59XG5cbi8vICoqYHVucGFyc2UoKWAgLSBDb252ZXJ0IFVVSUQgYnl0ZSBhcnJheSAoYWxhIHBhcnNlKCkpIGludG8gYSBzdHJpbmcqKlxuZnVuY3Rpb24gdW5wYXJzZShidWYsIG9mZnNldCkge1xuICB2YXIgaSA9IG9mZnNldCB8fCAwLCBidGggPSBfYnl0ZVRvSGV4O1xuICByZXR1cm4gIGJ0aFtidWZbaSsrXV0gKyBidGhbYnVmW2krK11dICtcbiAgICAgICAgICBidGhbYnVmW2krK11dICsgYnRoW2J1ZltpKytdXSArICctJyArXG4gICAgICAgICAgYnRoW2J1ZltpKytdXSArIGJ0aFtidWZbaSsrXV0gKyAnLScgK1xuICAgICAgICAgIGJ0aFtidWZbaSsrXV0gKyBidGhbYnVmW2krK11dICsgJy0nICtcbiAgICAgICAgICBidGhbYnVmW2krK11dICsgYnRoW2J1ZltpKytdXSArICctJyArXG4gICAgICAgICAgYnRoW2J1ZltpKytdXSArIGJ0aFtidWZbaSsrXV0gK1xuICAgICAgICAgIGJ0aFtidWZbaSsrXV0gKyBidGhbYnVmW2krK11dICtcbiAgICAgICAgICBidGhbYnVmW2krK11dICsgYnRoW2J1ZltpKytdXTtcbn1cblxuLy8gKipgdjEoKWAgLSBHZW5lcmF0ZSB0aW1lLWJhc2VkIFVVSUQqKlxuLy9cbi8vIEluc3BpcmVkIGJ5IGh0dHBzOi8vZ2l0aHViLmNvbS9MaW9zSy9VVUlELmpzXG4vLyBhbmQgaHR0cDovL2RvY3MucHl0aG9uLm9yZy9saWJyYXJ5L3V1aWQuaHRtbFxuXG4vLyByYW5kb20gIydzIHdlIG5lZWQgdG8gaW5pdCBub2RlIGFuZCBjbG9ja3NlcVxudmFyIF9zZWVkQnl0ZXMgPSBfcm5nKCk7XG5cbi8vIFBlciA0LjUsIGNyZWF0ZSBhbmQgNDgtYml0IG5vZGUgaWQsICg0NyByYW5kb20gYml0cyArIG11bHRpY2FzdCBiaXQgPSAxKVxudmFyIF9ub2RlSWQgPSBbXG4gIF9zZWVkQnl0ZXNbMF0gfCAweDAxLFxuICBfc2VlZEJ5dGVzWzFdLCBfc2VlZEJ5dGVzWzJdLCBfc2VlZEJ5dGVzWzNdLCBfc2VlZEJ5dGVzWzRdLCBfc2VlZEJ5dGVzWzVdXG5dO1xuXG4vLyBQZXIgNC4yLjIsIHJhbmRvbWl6ZSAoMTQgYml0KSBjbG9ja3NlcVxudmFyIF9jbG9ja3NlcSA9IChfc2VlZEJ5dGVzWzZdIDw8IDggfCBfc2VlZEJ5dGVzWzddKSAmIDB4M2ZmZjtcblxuLy8gUHJldmlvdXMgdXVpZCBjcmVhdGlvbiB0aW1lXG52YXIgX2xhc3RNU2VjcyA9IDAsIF9sYXN0TlNlY3MgPSAwO1xuXG4vLyBTZWUgaHR0cHM6Ly9naXRodWIuY29tL2Jyb29mYS9ub2RlLXV1aWQgZm9yIEFQSSBkZXRhaWxzXG5mdW5jdGlvbiB2MShvcHRpb25zLCBidWYsIG9mZnNldCkge1xuICB2YXIgaSA9IGJ1ZiAmJiBvZmZzZXQgfHwgMDtcbiAgdmFyIGIgPSBidWYgfHwgW107XG5cbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG5cbiAgdmFyIGNsb2Nrc2VxID0gb3B0aW9ucy5jbG9ja3NlcSAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5jbG9ja3NlcSA6IF9jbG9ja3NlcTtcblxuICAvLyBVVUlEIHRpbWVzdGFtcHMgYXJlIDEwMCBuYW5vLXNlY29uZCB1bml0cyBzaW5jZSB0aGUgR3JlZ29yaWFuIGVwb2NoLFxuICAvLyAoMTU4Mi0xMC0xNSAwMDowMCkuICBKU051bWJlcnMgYXJlbid0IHByZWNpc2UgZW5vdWdoIGZvciB0aGlzLCBzb1xuICAvLyB0aW1lIGlzIGhhbmRsZWQgaW50ZXJuYWxseSBhcyAnbXNlY3MnIChpbnRlZ2VyIG1pbGxpc2Vjb25kcykgYW5kICduc2VjcydcbiAgLy8gKDEwMC1uYW5vc2Vjb25kcyBvZmZzZXQgZnJvbSBtc2Vjcykgc2luY2UgdW5peCBlcG9jaCwgMTk3MC0wMS0wMSAwMDowMC5cbiAgdmFyIG1zZWNzID0gb3B0aW9ucy5tc2VjcyAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5tc2VjcyA6IG5ldyBEYXRlKCkuZ2V0VGltZSgpO1xuXG4gIC8vIFBlciA0LjIuMS4yLCB1c2UgY291bnQgb2YgdXVpZCdzIGdlbmVyYXRlZCBkdXJpbmcgdGhlIGN1cnJlbnQgY2xvY2tcbiAgLy8gY3ljbGUgdG8gc2ltdWxhdGUgaGlnaGVyIHJlc29sdXRpb24gY2xvY2tcbiAgdmFyIG5zZWNzID0gb3B0aW9ucy5uc2VjcyAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5uc2VjcyA6IF9sYXN0TlNlY3MgKyAxO1xuXG4gIC8vIFRpbWUgc2luY2UgbGFzdCB1dWlkIGNyZWF0aW9uIChpbiBtc2VjcylcbiAgdmFyIGR0ID0gKG1zZWNzIC0gX2xhc3RNU2VjcykgKyAobnNlY3MgLSBfbGFzdE5TZWNzKS8xMDAwMDtcblxuICAvLyBQZXIgNC4yLjEuMiwgQnVtcCBjbG9ja3NlcSBvbiBjbG9jayByZWdyZXNzaW9uXG4gIGlmIChkdCA8IDAgJiYgb3B0aW9ucy5jbG9ja3NlcSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgY2xvY2tzZXEgPSBjbG9ja3NlcSArIDEgJiAweDNmZmY7XG4gIH1cblxuICAvLyBSZXNldCBuc2VjcyBpZiBjbG9jayByZWdyZXNzZXMgKG5ldyBjbG9ja3NlcSkgb3Igd2UndmUgbW92ZWQgb250byBhIG5ld1xuICAvLyB0aW1lIGludGVydmFsXG4gIGlmICgoZHQgPCAwIHx8IG1zZWNzID4gX2xhc3RNU2VjcykgJiYgb3B0aW9ucy5uc2VjcyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgbnNlY3MgPSAwO1xuICB9XG5cbiAgLy8gUGVyIDQuMi4xLjIgVGhyb3cgZXJyb3IgaWYgdG9vIG1hbnkgdXVpZHMgYXJlIHJlcXVlc3RlZFxuICBpZiAobnNlY3MgPj0gMTAwMDApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3V1aWQudjEoKTogQ2FuXFwndCBjcmVhdGUgbW9yZSB0aGFuIDEwTSB1dWlkcy9zZWMnKTtcbiAgfVxuXG4gIF9sYXN0TVNlY3MgPSBtc2VjcztcbiAgX2xhc3ROU2VjcyA9IG5zZWNzO1xuICBfY2xvY2tzZXEgPSBjbG9ja3NlcTtcblxuICAvLyBQZXIgNC4xLjQgLSBDb252ZXJ0IGZyb20gdW5peCBlcG9jaCB0byBHcmVnb3JpYW4gZXBvY2hcbiAgbXNlY3MgKz0gMTIyMTkyOTI4MDAwMDA7XG5cbiAgLy8gYHRpbWVfbG93YFxuICB2YXIgdGwgPSAoKG1zZWNzICYgMHhmZmZmZmZmKSAqIDEwMDAwICsgbnNlY3MpICUgMHgxMDAwMDAwMDA7XG4gIGJbaSsrXSA9IHRsID4+PiAyNCAmIDB4ZmY7XG4gIGJbaSsrXSA9IHRsID4+PiAxNiAmIDB4ZmY7XG4gIGJbaSsrXSA9IHRsID4+PiA4ICYgMHhmZjtcbiAgYltpKytdID0gdGwgJiAweGZmO1xuXG4gIC8vIGB0aW1lX21pZGBcbiAgdmFyIHRtaCA9IChtc2VjcyAvIDB4MTAwMDAwMDAwICogMTAwMDApICYgMHhmZmZmZmZmO1xuICBiW2krK10gPSB0bWggPj4+IDggJiAweGZmO1xuICBiW2krK10gPSB0bWggJiAweGZmO1xuXG4gIC8vIGB0aW1lX2hpZ2hfYW5kX3ZlcnNpb25gXG4gIGJbaSsrXSA9IHRtaCA+Pj4gMjQgJiAweGYgfCAweDEwOyAvLyBpbmNsdWRlIHZlcnNpb25cbiAgYltpKytdID0gdG1oID4+PiAxNiAmIDB4ZmY7XG5cbiAgLy8gYGNsb2NrX3NlcV9oaV9hbmRfcmVzZXJ2ZWRgIChQZXIgNC4yLjIgLSBpbmNsdWRlIHZhcmlhbnQpXG4gIGJbaSsrXSA9IGNsb2Nrc2VxID4+PiA4IHwgMHg4MDtcblxuICAvLyBgY2xvY2tfc2VxX2xvd2BcbiAgYltpKytdID0gY2xvY2tzZXEgJiAweGZmO1xuXG4gIC8vIGBub2RlYFxuICB2YXIgbm9kZSA9IG9wdGlvbnMubm9kZSB8fCBfbm9kZUlkO1xuICBmb3IgKHZhciBuID0gMDsgbiA8IDY7IG4rKykge1xuICAgIGJbaSArIG5dID0gbm9kZVtuXTtcbiAgfVxuXG4gIHJldHVybiBidWYgPyBidWYgOiB1bnBhcnNlKGIpO1xufVxuXG4vLyAqKmB2NCgpYCAtIEdlbmVyYXRlIHJhbmRvbSBVVUlEKipcblxuLy8gU2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9icm9vZmEvbm9kZS11dWlkIGZvciBBUEkgZGV0YWlsc1xuZnVuY3Rpb24gdjQob3B0aW9ucywgYnVmLCBvZmZzZXQpIHtcbiAgLy8gRGVwcmVjYXRlZCAtICdmb3JtYXQnIGFyZ3VtZW50LCBhcyBzdXBwb3J0ZWQgaW4gdjEuMlxuICB2YXIgaSA9IGJ1ZiAmJiBvZmZzZXQgfHwgMDtcblxuICBpZiAodHlwZW9mKG9wdGlvbnMpID09ICdzdHJpbmcnKSB7XG4gICAgYnVmID0gb3B0aW9ucyA9PSAnYmluYXJ5JyA/IG5ldyBBcnJheSgxNikgOiBudWxsO1xuICAgIG9wdGlvbnMgPSBudWxsO1xuICB9XG4gIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuXG4gIHZhciBybmRzID0gb3B0aW9ucy5yYW5kb20gfHwgKG9wdGlvbnMucm5nIHx8IF9ybmcpKCk7XG5cbiAgLy8gUGVyIDQuNCwgc2V0IGJpdHMgZm9yIHZlcnNpb24gYW5kIGBjbG9ja19zZXFfaGlfYW5kX3Jlc2VydmVkYFxuICBybmRzWzZdID0gKHJuZHNbNl0gJiAweDBmKSB8IDB4NDA7XG4gIHJuZHNbOF0gPSAocm5kc1s4XSAmIDB4M2YpIHwgMHg4MDtcblxuICAvLyBDb3B5IGJ5dGVzIHRvIGJ1ZmZlciwgaWYgcHJvdmlkZWRcbiAgaWYgKGJ1Zikge1xuICAgIGZvciAodmFyIGlpID0gMDsgaWkgPCAxNjsgaWkrKykge1xuICAgICAgYnVmW2kgKyBpaV0gPSBybmRzW2lpXTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gYnVmIHx8IHVucGFyc2Uocm5kcyk7XG59XG5cbi8vIEV4cG9ydCBwdWJsaWMgQVBJXG52YXIgdXVpZCA9IHY0O1xudXVpZC52MSA9IHYxO1xudXVpZC52NCA9IHY0O1xudXVpZC5wYXJzZSA9IHBhcnNlO1xudXVpZC51bnBhcnNlID0gdW5wYXJzZTtcblxubW9kdWxlLmV4cG9ydHMgPSB1dWlkO1xuIiwiLypcbiAqICBDb3B5cmlnaHQgKGMpIDIwMTYgVGhlIFdlYlJUQyBwcm9qZWN0IGF1dGhvcnMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKlxuICogIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2VcbiAqICB0aGF0IGNhbiBiZSBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlIGluIHRoZSByb290IG9mIHRoZSBzb3VyY2VcbiAqICB0cmVlLlxuICovXG4gLyogZXNsaW50LWVudiBub2RlICovXG5cbid1c2Ugc3RyaWN0JztcblxuLy8gU2hpbW1pbmcgc3RhcnRzIGhlcmUuXG4oZnVuY3Rpb24oKSB7XG4gIC8vIFV0aWxzLlxuICB2YXIgdXRpbHMgPSByZXF1aXJlKCcuL3V0aWxzJyk7XG4gIHZhciBsb2dnaW5nID0gdXRpbHMubG9nO1xuICB2YXIgYnJvd3NlckRldGFpbHMgPSB1dGlscy5icm93c2VyRGV0YWlscztcbiAgLy8gRXhwb3J0IHRvIHRoZSBhZGFwdGVyIGdsb2JhbCBvYmplY3QgdmlzaWJsZSBpbiB0aGUgYnJvd3Nlci5cbiAgbW9kdWxlLmV4cG9ydHMuYnJvd3NlckRldGFpbHMgPSBicm93c2VyRGV0YWlscztcbiAgbW9kdWxlLmV4cG9ydHMuZXh0cmFjdFZlcnNpb24gPSB1dGlscy5leHRyYWN0VmVyc2lvbjtcbiAgbW9kdWxlLmV4cG9ydHMuZGlzYWJsZUxvZyA9IHV0aWxzLmRpc2FibGVMb2c7XG5cbiAgLy8gVW5jb21tZW50IHRoZSBsaW5lIGJlbG93IGlmIHlvdSB3YW50IGxvZ2dpbmcgdG8gb2NjdXIsIGluY2x1ZGluZyBsb2dnaW5nXG4gIC8vIGZvciB0aGUgc3dpdGNoIHN0YXRlbWVudCBiZWxvdy4gQ2FuIGFsc28gYmUgdHVybmVkIG9uIGluIHRoZSBicm93c2VyIHZpYVxuICAvLyBhZGFwdGVyLmRpc2FibGVMb2coZmFsc2UpLCBidXQgdGhlbiBsb2dnaW5nIGZyb20gdGhlIHN3aXRjaCBzdGF0ZW1lbnQgYmVsb3dcbiAgLy8gd2lsbCBub3QgYXBwZWFyLlxuICAvLyByZXF1aXJlKCcuL3V0aWxzJykuZGlzYWJsZUxvZyhmYWxzZSk7XG5cbiAgLy8gQnJvd3NlciBzaGltcy5cbiAgdmFyIGNocm9tZVNoaW0gPSByZXF1aXJlKCcuL2Nocm9tZS9jaHJvbWVfc2hpbScpIHx8IG51bGw7XG4gIHZhciBlZGdlU2hpbSA9IHJlcXVpcmUoJy4vZWRnZS9lZGdlX3NoaW0nKSB8fCBudWxsO1xuICB2YXIgZmlyZWZveFNoaW0gPSByZXF1aXJlKCcuL2ZpcmVmb3gvZmlyZWZveF9zaGltJykgfHwgbnVsbDtcbiAgdmFyIHNhZmFyaVNoaW0gPSByZXF1aXJlKCcuL3NhZmFyaS9zYWZhcmlfc2hpbScpIHx8IG51bGw7XG5cbiAgLy8gU2hpbSBicm93c2VyIGlmIGZvdW5kLlxuICBzd2l0Y2ggKGJyb3dzZXJEZXRhaWxzLmJyb3dzZXIpIHtcbiAgICBjYXNlICdjaHJvbWUnOlxuICAgICAgaWYgKCFjaHJvbWVTaGltIHx8ICFjaHJvbWVTaGltLnNoaW1QZWVyQ29ubmVjdGlvbikge1xuICAgICAgICBsb2dnaW5nKCdDaHJvbWUgc2hpbSBpcyBub3QgaW5jbHVkZWQgaW4gdGhpcyBhZGFwdGVyIHJlbGVhc2UuJyk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGxvZ2dpbmcoJ2FkYXB0ZXIuanMgc2hpbW1pbmcgY2hyb21lLicpO1xuICAgICAgLy8gRXhwb3J0IHRvIHRoZSBhZGFwdGVyIGdsb2JhbCBvYmplY3QgdmlzaWJsZSBpbiB0aGUgYnJvd3Nlci5cbiAgICAgIG1vZHVsZS5leHBvcnRzLmJyb3dzZXJTaGltID0gY2hyb21lU2hpbTtcblxuICAgICAgY2hyb21lU2hpbS5zaGltR2V0VXNlck1lZGlhKCk7XG4gICAgICBjaHJvbWVTaGltLnNoaW1NZWRpYVN0cmVhbSgpO1xuICAgICAgdXRpbHMuc2hpbUNyZWF0ZU9iamVjdFVSTCgpO1xuICAgICAgY2hyb21lU2hpbS5zaGltU291cmNlT2JqZWN0KCk7XG4gICAgICBjaHJvbWVTaGltLnNoaW1QZWVyQ29ubmVjdGlvbigpO1xuICAgICAgY2hyb21lU2hpbS5zaGltT25UcmFjaygpO1xuICAgICAgY2hyb21lU2hpbS5zaGltR2V0U2VuZGVyc1dpdGhEdG1mKCk7XG4gICAgICBicmVhaztcbiAgICBjYXNlICdmaXJlZm94JzpcbiAgICAgIGlmICghZmlyZWZveFNoaW0gfHwgIWZpcmVmb3hTaGltLnNoaW1QZWVyQ29ubmVjdGlvbikge1xuICAgICAgICBsb2dnaW5nKCdGaXJlZm94IHNoaW0gaXMgbm90IGluY2x1ZGVkIGluIHRoaXMgYWRhcHRlciByZWxlYXNlLicpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBsb2dnaW5nKCdhZGFwdGVyLmpzIHNoaW1taW5nIGZpcmVmb3guJyk7XG4gICAgICAvLyBFeHBvcnQgdG8gdGhlIGFkYXB0ZXIgZ2xvYmFsIG9iamVjdCB2aXNpYmxlIGluIHRoZSBicm93c2VyLlxuICAgICAgbW9kdWxlLmV4cG9ydHMuYnJvd3NlclNoaW0gPSBmaXJlZm94U2hpbTtcblxuICAgICAgZmlyZWZveFNoaW0uc2hpbUdldFVzZXJNZWRpYSgpO1xuICAgICAgdXRpbHMuc2hpbUNyZWF0ZU9iamVjdFVSTCgpO1xuICAgICAgZmlyZWZveFNoaW0uc2hpbVNvdXJjZU9iamVjdCgpO1xuICAgICAgZmlyZWZveFNoaW0uc2hpbVBlZXJDb25uZWN0aW9uKCk7XG4gICAgICBmaXJlZm94U2hpbS5zaGltT25UcmFjaygpO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAnZWRnZSc6XG4gICAgICBpZiAoIWVkZ2VTaGltIHx8ICFlZGdlU2hpbS5zaGltUGVlckNvbm5lY3Rpb24pIHtcbiAgICAgICAgbG9nZ2luZygnTVMgZWRnZSBzaGltIGlzIG5vdCBpbmNsdWRlZCBpbiB0aGlzIGFkYXB0ZXIgcmVsZWFzZS4nKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgbG9nZ2luZygnYWRhcHRlci5qcyBzaGltbWluZyBlZGdlLicpO1xuICAgICAgLy8gRXhwb3J0IHRvIHRoZSBhZGFwdGVyIGdsb2JhbCBvYmplY3QgdmlzaWJsZSBpbiB0aGUgYnJvd3Nlci5cbiAgICAgIG1vZHVsZS5leHBvcnRzLmJyb3dzZXJTaGltID0gZWRnZVNoaW07XG5cbiAgICAgIGVkZ2VTaGltLnNoaW1HZXRVc2VyTWVkaWEoKTtcbiAgICAgIHV0aWxzLnNoaW1DcmVhdGVPYmplY3RVUkwoKTtcbiAgICAgIGVkZ2VTaGltLnNoaW1QZWVyQ29ubmVjdGlvbigpO1xuICAgICAgZWRnZVNoaW0uc2hpbVJlcGxhY2VUcmFjaygpO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAnc2FmYXJpJzpcbiAgICAgIGlmICghc2FmYXJpU2hpbSkge1xuICAgICAgICBsb2dnaW5nKCdTYWZhcmkgc2hpbSBpcyBub3QgaW5jbHVkZWQgaW4gdGhpcyBhZGFwdGVyIHJlbGVhc2UuJyk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGxvZ2dpbmcoJ2FkYXB0ZXIuanMgc2hpbW1pbmcgc2FmYXJpLicpO1xuICAgICAgLy8gRXhwb3J0IHRvIHRoZSBhZGFwdGVyIGdsb2JhbCBvYmplY3QgdmlzaWJsZSBpbiB0aGUgYnJvd3Nlci5cbiAgICAgIG1vZHVsZS5leHBvcnRzLmJyb3dzZXJTaGltID0gc2FmYXJpU2hpbTtcblxuICAgICAgc2FmYXJpU2hpbS5zaGltT25BZGRTdHJlYW0oKTtcbiAgICAgIHNhZmFyaVNoaW0uc2hpbUdldFVzZXJNZWRpYSgpO1xuICAgICAgYnJlYWs7XG4gICAgZGVmYXVsdDpcbiAgICAgIGxvZ2dpbmcoJ1Vuc3VwcG9ydGVkIGJyb3dzZXIhJyk7XG4gIH1cbn0pKCk7XG4iLCJcbi8qXG4gKiAgQ29weXJpZ2h0IChjKSAyMDE2IFRoZSBXZWJSVEMgcHJvamVjdCBhdXRob3JzLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICpcbiAqICBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlXG4gKiAgdGhhdCBjYW4gYmUgZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZSBpbiB0aGUgcm9vdCBvZiB0aGUgc291cmNlXG4gKiAgdHJlZS5cbiAqL1xuIC8qIGVzbGludC1lbnYgbm9kZSAqL1xuJ3VzZSBzdHJpY3QnO1xudmFyIGxvZ2dpbmcgPSByZXF1aXJlKCcuLi91dGlscy5qcycpLmxvZztcbnZhciBicm93c2VyRGV0YWlscyA9IHJlcXVpcmUoJy4uL3V0aWxzLmpzJykuYnJvd3NlckRldGFpbHM7XG5cbnZhciBjaHJvbWVTaGltID0ge1xuICBzaGltTWVkaWFTdHJlYW06IGZ1bmN0aW9uKCkge1xuICAgIHdpbmRvdy5NZWRpYVN0cmVhbSA9IHdpbmRvdy5NZWRpYVN0cmVhbSB8fCB3aW5kb3cud2Via2l0TWVkaWFTdHJlYW07XG4gIH0sXG5cbiAgc2hpbU9uVHJhY2s6IGZ1bmN0aW9uKCkge1xuICAgIGlmICh0eXBlb2Ygd2luZG93ID09PSAnb2JqZWN0JyAmJiB3aW5kb3cuUlRDUGVlckNvbm5lY3Rpb24gJiYgISgnb250cmFjaycgaW5cbiAgICAgICAgd2luZG93LlJUQ1BlZXJDb25uZWN0aW9uLnByb3RvdHlwZSkpIHtcbiAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh3aW5kb3cuUlRDUGVlckNvbm5lY3Rpb24ucHJvdG90eXBlLCAnb250cmFjaycsIHtcbiAgICAgICAgZ2V0OiBmdW5jdGlvbigpIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy5fb250cmFjaztcbiAgICAgICAgfSxcbiAgICAgICAgc2V0OiBmdW5jdGlvbihmKSB7XG4gICAgICAgICAgdmFyIHNlbGYgPSB0aGlzO1xuICAgICAgICAgIGlmICh0aGlzLl9vbnRyYWNrKSB7XG4gICAgICAgICAgICB0aGlzLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3RyYWNrJywgdGhpcy5fb250cmFjayk7XG4gICAgICAgICAgICB0aGlzLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2FkZHN0cmVhbScsIHRoaXMuX29udHJhY2twb2x5KTtcbiAgICAgICAgICB9XG4gICAgICAgICAgdGhpcy5hZGRFdmVudExpc3RlbmVyKCd0cmFjaycsIHRoaXMuX29udHJhY2sgPSBmKTtcbiAgICAgICAgICB0aGlzLmFkZEV2ZW50TGlzdGVuZXIoJ2FkZHN0cmVhbScsIHRoaXMuX29udHJhY2twb2x5ID0gZnVuY3Rpb24oZSkge1xuICAgICAgICAgICAgLy8gb25hZGRzdHJlYW0gZG9lcyBub3QgZmlyZSB3aGVuIGEgdHJhY2sgaXMgYWRkZWQgdG8gYW4gZXhpc3RpbmdcbiAgICAgICAgICAgIC8vIHN0cmVhbS4gQnV0IHN0cmVhbS5vbmFkZHRyYWNrIGlzIGltcGxlbWVudGVkIHNvIHdlIHVzZSB0aGF0LlxuICAgICAgICAgICAgZS5zdHJlYW0uYWRkRXZlbnRMaXN0ZW5lcignYWRkdHJhY2snLCBmdW5jdGlvbih0ZSkge1xuICAgICAgICAgICAgICB2YXIgZXZlbnQgPSBuZXcgRXZlbnQoJ3RyYWNrJyk7XG4gICAgICAgICAgICAgIGV2ZW50LnRyYWNrID0gdGUudHJhY2s7XG4gICAgICAgICAgICAgIGV2ZW50LnJlY2VpdmVyID0ge3RyYWNrOiB0ZS50cmFja307XG4gICAgICAgICAgICAgIGV2ZW50LnN0cmVhbXMgPSBbZS5zdHJlYW1dO1xuICAgICAgICAgICAgICBzZWxmLmRpc3BhdGNoRXZlbnQoZXZlbnQpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBlLnN0cmVhbS5nZXRUcmFja3MoKS5mb3JFYWNoKGZ1bmN0aW9uKHRyYWNrKSB7XG4gICAgICAgICAgICAgIHZhciBldmVudCA9IG5ldyBFdmVudCgndHJhY2snKTtcbiAgICAgICAgICAgICAgZXZlbnQudHJhY2sgPSB0cmFjaztcbiAgICAgICAgICAgICAgZXZlbnQucmVjZWl2ZXIgPSB7dHJhY2s6IHRyYWNrfTtcbiAgICAgICAgICAgICAgZXZlbnQuc3RyZWFtcyA9IFtlLnN0cmVhbV07XG4gICAgICAgICAgICAgIHRoaXMuZGlzcGF0Y2hFdmVudChldmVudCk7XG4gICAgICAgICAgICB9LmJpbmQodGhpcykpO1xuICAgICAgICAgIH0uYmluZCh0aGlzKSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cbiAgfSxcblxuICBzaGltR2V0U2VuZGVyc1dpdGhEdG1mOiBmdW5jdGlvbigpIHtcbiAgICBpZiAodHlwZW9mIHdpbmRvdyA9PT0gJ29iamVjdCcgJiYgd2luZG93LlJUQ1BlZXJDb25uZWN0aW9uICYmXG4gICAgICAgICEoJ2dldFNlbmRlcnMnIGluIFJUQ1BlZXJDb25uZWN0aW9uLnByb3RvdHlwZSkgJiZcbiAgICAgICAgJ2NyZWF0ZURUTUZTZW5kZXInIGluIFJUQ1BlZXJDb25uZWN0aW9uLnByb3RvdHlwZSkge1xuICAgICAgUlRDUGVlckNvbm5lY3Rpb24ucHJvdG90eXBlLmdldFNlbmRlcnMgPSBmdW5jdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3NlbmRlcnM7XG4gICAgICB9O1xuICAgICAgdmFyIG9yaWdBZGRTdHJlYW0gPSBSVENQZWVyQ29ubmVjdGlvbi5wcm90b3R5cGUuYWRkU3RyZWFtO1xuICAgICAgdmFyIG9yaWdSZW1vdmVTdHJlYW0gPSBSVENQZWVyQ29ubmVjdGlvbi5wcm90b3R5cGUucmVtb3ZlU3RyZWFtO1xuXG4gICAgICBSVENQZWVyQ29ubmVjdGlvbi5wcm90b3R5cGUuYWRkU3RyZWFtID0gZnVuY3Rpb24oc3RyZWFtKSB7XG4gICAgICAgIHZhciBwYyA9IHRoaXM7XG4gICAgICAgIHBjLl9zZW5kZXJzID0gcGMuX3NlbmRlcnMgfHwgW107XG4gICAgICAgIG9yaWdBZGRTdHJlYW0uYXBwbHkocGMsIFtzdHJlYW1dKTtcbiAgICAgICAgc3RyZWFtLmdldFRyYWNrcygpLmZvckVhY2goZnVuY3Rpb24odHJhY2spIHtcbiAgICAgICAgICBwYy5fc2VuZGVycy5wdXNoKHtcbiAgICAgICAgICAgIHRyYWNrOiB0cmFjayxcbiAgICAgICAgICAgIGdldCBkdG1mKCkge1xuICAgICAgICAgICAgICBpZiAodGhpcy5fZHRtZiA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgaWYgKHRyYWNrLmtpbmQgPT09ICdhdWRpbycpIHtcbiAgICAgICAgICAgICAgICAgIHRoaXMuX2R0bWYgPSBwYy5jcmVhdGVEVE1GU2VuZGVyKHRyYWNrKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgdGhpcy5fZHRtZiA9IG51bGw7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHJldHVybiB0aGlzLl9kdG1mO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICAgIH07XG5cbiAgICAgIFJUQ1BlZXJDb25uZWN0aW9uLnByb3RvdHlwZS5yZW1vdmVTdHJlYW0gPSBmdW5jdGlvbihzdHJlYW0pIHtcbiAgICAgICAgdmFyIHBjID0gdGhpcztcbiAgICAgICAgcGMuX3NlbmRlcnMgPSBwYy5fc2VuZGVycyB8fCBbXTtcbiAgICAgICAgb3JpZ1JlbW92ZVN0cmVhbS5hcHBseShwYywgW3N0cmVhbV0pO1xuICAgICAgICBzdHJlYW0uZ2V0VHJhY2tzKCkuZm9yRWFjaChmdW5jdGlvbih0cmFjaykge1xuICAgICAgICAgIHZhciBzZW5kZXIgPSBwYy5fc2VuZGVycy5maW5kKGZ1bmN0aW9uKHMpIHtcbiAgICAgICAgICAgIHJldHVybiBzLnRyYWNrID09PSB0cmFjaztcbiAgICAgICAgICB9KTtcbiAgICAgICAgICBpZiAoc2VuZGVyKSB7XG4gICAgICAgICAgICBwYy5fc2VuZGVycy5zcGxpY2UocGMuX3NlbmRlcnMuaW5kZXhPZihzZW5kZXIpLCAxKTsgLy8gcmVtb3ZlIHNlbmRlclxuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9O1xuICAgIH1cbiAgfSxcblxuICBzaGltU291cmNlT2JqZWN0OiBmdW5jdGlvbigpIHtcbiAgICBpZiAodHlwZW9mIHdpbmRvdyA9PT0gJ29iamVjdCcpIHtcbiAgICAgIGlmICh3aW5kb3cuSFRNTE1lZGlhRWxlbWVudCAmJlxuICAgICAgICAhKCdzcmNPYmplY3QnIGluIHdpbmRvdy5IVE1MTWVkaWFFbGVtZW50LnByb3RvdHlwZSkpIHtcbiAgICAgICAgLy8gU2hpbSB0aGUgc3JjT2JqZWN0IHByb3BlcnR5LCBvbmNlLCB3aGVuIEhUTUxNZWRpYUVsZW1lbnQgaXMgZm91bmQuXG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh3aW5kb3cuSFRNTE1lZGlhRWxlbWVudC5wcm90b3R5cGUsICdzcmNPYmplY3QnLCB7XG4gICAgICAgICAgZ2V0OiBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9zcmNPYmplY3Q7XG4gICAgICAgICAgfSxcbiAgICAgICAgICBzZXQ6IGZ1bmN0aW9uKHN0cmVhbSkge1xuICAgICAgICAgICAgdmFyIHNlbGYgPSB0aGlzO1xuICAgICAgICAgICAgLy8gVXNlIF9zcmNPYmplY3QgYXMgYSBwcml2YXRlIHByb3BlcnR5IGZvciB0aGlzIHNoaW1cbiAgICAgICAgICAgIHRoaXMuX3NyY09iamVjdCA9IHN0cmVhbTtcbiAgICAgICAgICAgIGlmICh0aGlzLnNyYykge1xuICAgICAgICAgICAgICBVUkwucmV2b2tlT2JqZWN0VVJMKHRoaXMuc3JjKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKCFzdHJlYW0pIHtcbiAgICAgICAgICAgICAgdGhpcy5zcmMgPSAnJztcbiAgICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuc3JjID0gVVJMLmNyZWF0ZU9iamVjdFVSTChzdHJlYW0pO1xuICAgICAgICAgICAgLy8gV2UgbmVlZCB0byByZWNyZWF0ZSB0aGUgYmxvYiB1cmwgd2hlbiBhIHRyYWNrIGlzIGFkZGVkIG9yXG4gICAgICAgICAgICAvLyByZW1vdmVkLiBEb2luZyBpdCBtYW51YWxseSBzaW5jZSB3ZSB3YW50IHRvIGF2b2lkIGEgcmVjdXJzaW9uLlxuICAgICAgICAgICAgc3RyZWFtLmFkZEV2ZW50TGlzdGVuZXIoJ2FkZHRyYWNrJywgZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICAgIGlmIChzZWxmLnNyYykge1xuICAgICAgICAgICAgICAgIFVSTC5yZXZva2VPYmplY3RVUkwoc2VsZi5zcmMpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHNlbGYuc3JjID0gVVJMLmNyZWF0ZU9iamVjdFVSTChzdHJlYW0pO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBzdHJlYW0uYWRkRXZlbnRMaXN0ZW5lcigncmVtb3ZldHJhY2snLCBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgICAgaWYgKHNlbGYuc3JjKSB7XG4gICAgICAgICAgICAgICAgVVJMLnJldm9rZU9iamVjdFVSTChzZWxmLnNyYyk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgc2VsZi5zcmMgPSBVUkwuY3JlYXRlT2JqZWN0VVJMKHN0cmVhbSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cbiAgfSxcblxuICBzaGltUGVlckNvbm5lY3Rpb246IGZ1bmN0aW9uKCkge1xuICAgIC8vIFRoZSBSVENQZWVyQ29ubmVjdGlvbiBvYmplY3QuXG4gICAgaWYgKCF3aW5kb3cuUlRDUGVlckNvbm5lY3Rpb24pIHtcbiAgICAgIHdpbmRvdy5SVENQZWVyQ29ubmVjdGlvbiA9IGZ1bmN0aW9uKHBjQ29uZmlnLCBwY0NvbnN0cmFpbnRzKSB7XG4gICAgICAgIC8vIFRyYW5zbGF0ZSBpY2VUcmFuc3BvcnRQb2xpY3kgdG8gaWNlVHJhbnNwb3J0cyxcbiAgICAgICAgLy8gc2VlIGh0dHBzOi8vY29kZS5nb29nbGUuY29tL3Avd2VicnRjL2lzc3Vlcy9kZXRhaWw/aWQ9NDg2OVxuICAgICAgICAvLyB0aGlzIHdhcyBmaXhlZCBpbiBNNTYgYWxvbmcgd2l0aCB1bnByZWZpeGluZyBSVENQZWVyQ29ubmVjdGlvbi5cbiAgICAgICAgbG9nZ2luZygnUGVlckNvbm5lY3Rpb24nKTtcbiAgICAgICAgaWYgKHBjQ29uZmlnICYmIHBjQ29uZmlnLmljZVRyYW5zcG9ydFBvbGljeSkge1xuICAgICAgICAgIHBjQ29uZmlnLmljZVRyYW5zcG9ydHMgPSBwY0NvbmZpZy5pY2VUcmFuc3BvcnRQb2xpY3k7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbmV3IHdlYmtpdFJUQ1BlZXJDb25uZWN0aW9uKHBjQ29uZmlnLCBwY0NvbnN0cmFpbnRzKTtcbiAgICAgIH07XG4gICAgICB3aW5kb3cuUlRDUGVlckNvbm5lY3Rpb24ucHJvdG90eXBlID0gd2Via2l0UlRDUGVlckNvbm5lY3Rpb24ucHJvdG90eXBlO1xuICAgICAgLy8gd3JhcCBzdGF0aWMgbWV0aG9kcy4gQ3VycmVudGx5IGp1c3QgZ2VuZXJhdGVDZXJ0aWZpY2F0ZS5cbiAgICAgIGlmICh3ZWJraXRSVENQZWVyQ29ubmVjdGlvbi5nZW5lcmF0ZUNlcnRpZmljYXRlKSB7XG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh3aW5kb3cuUlRDUGVlckNvbm5lY3Rpb24sICdnZW5lcmF0ZUNlcnRpZmljYXRlJywge1xuICAgICAgICAgIGdldDogZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICByZXR1cm4gd2Via2l0UlRDUGVlckNvbm5lY3Rpb24uZ2VuZXJhdGVDZXJ0aWZpY2F0ZTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICAvLyBtaWdyYXRlIGZyb20gbm9uLXNwZWMgUlRDSWNlU2VydmVyLnVybCB0byBSVENJY2VTZXJ2ZXIudXJsc1xuICAgICAgdmFyIE9yaWdQZWVyQ29ubmVjdGlvbiA9IFJUQ1BlZXJDb25uZWN0aW9uO1xuICAgICAgd2luZG93LlJUQ1BlZXJDb25uZWN0aW9uID0gZnVuY3Rpb24ocGNDb25maWcsIHBjQ29uc3RyYWludHMpIHtcbiAgICAgICAgaWYgKHBjQ29uZmlnICYmIHBjQ29uZmlnLmljZVNlcnZlcnMpIHtcbiAgICAgICAgICB2YXIgbmV3SWNlU2VydmVycyA9IFtdO1xuICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcGNDb25maWcuaWNlU2VydmVycy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgdmFyIHNlcnZlciA9IHBjQ29uZmlnLmljZVNlcnZlcnNbaV07XG4gICAgICAgICAgICBpZiAoIXNlcnZlci5oYXNPd25Qcm9wZXJ0eSgndXJscycpICYmXG4gICAgICAgICAgICAgICAgc2VydmVyLmhhc093blByb3BlcnR5KCd1cmwnKSkge1xuICAgICAgICAgICAgICBjb25zb2xlLndhcm4oJ1JUQ0ljZVNlcnZlci51cmwgaXMgZGVwcmVjYXRlZCEgVXNlIHVybHMgaW5zdGVhZC4nKTtcbiAgICAgICAgICAgICAgc2VydmVyID0gSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeShzZXJ2ZXIpKTtcbiAgICAgICAgICAgICAgc2VydmVyLnVybHMgPSBzZXJ2ZXIudXJsO1xuICAgICAgICAgICAgICBuZXdJY2VTZXJ2ZXJzLnB1c2goc2VydmVyKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIG5ld0ljZVNlcnZlcnMucHVzaChwY0NvbmZpZy5pY2VTZXJ2ZXJzW2ldKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgcGNDb25maWcuaWNlU2VydmVycyA9IG5ld0ljZVNlcnZlcnM7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG5ldyBPcmlnUGVlckNvbm5lY3Rpb24ocGNDb25maWcsIHBjQ29uc3RyYWludHMpO1xuICAgICAgfTtcbiAgICAgIHdpbmRvdy5SVENQZWVyQ29ubmVjdGlvbi5wcm90b3R5cGUgPSBPcmlnUGVlckNvbm5lY3Rpb24ucHJvdG90eXBlO1xuICAgICAgLy8gd3JhcCBzdGF0aWMgbWV0aG9kcy4gQ3VycmVudGx5IGp1c3QgZ2VuZXJhdGVDZXJ0aWZpY2F0ZS5cbiAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh3aW5kb3cuUlRDUGVlckNvbm5lY3Rpb24sICdnZW5lcmF0ZUNlcnRpZmljYXRlJywge1xuICAgICAgICBnZXQ6IGZ1bmN0aW9uKCkge1xuICAgICAgICAgIHJldHVybiBPcmlnUGVlckNvbm5lY3Rpb24uZ2VuZXJhdGVDZXJ0aWZpY2F0ZTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgdmFyIG9yaWdHZXRTdGF0cyA9IFJUQ1BlZXJDb25uZWN0aW9uLnByb3RvdHlwZS5nZXRTdGF0cztcbiAgICBSVENQZWVyQ29ubmVjdGlvbi5wcm90b3R5cGUuZ2V0U3RhdHMgPSBmdW5jdGlvbihzZWxlY3RvcixcbiAgICAgICAgc3VjY2Vzc0NhbGxiYWNrLCBlcnJvckNhbGxiYWNrKSB7XG4gICAgICB2YXIgc2VsZiA9IHRoaXM7XG4gICAgICB2YXIgYXJncyA9IGFyZ3VtZW50cztcblxuICAgICAgLy8gSWYgc2VsZWN0b3IgaXMgYSBmdW5jdGlvbiB0aGVuIHdlIGFyZSBpbiB0aGUgb2xkIHN0eWxlIHN0YXRzIHNvIGp1c3RcbiAgICAgIC8vIHBhc3MgYmFjayB0aGUgb3JpZ2luYWwgZ2V0U3RhdHMgZm9ybWF0IHRvIGF2b2lkIGJyZWFraW5nIG9sZCB1c2Vycy5cbiAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID4gMCAmJiB0eXBlb2Ygc2VsZWN0b3IgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgcmV0dXJuIG9yaWdHZXRTdGF0cy5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgfVxuXG4gICAgICAvLyBXaGVuIHNwZWMtc3R5bGUgZ2V0U3RhdHMgaXMgc3VwcG9ydGVkLCByZXR1cm4gdGhvc2Ugd2hlbiBjYWxsZWQgd2l0aFxuICAgICAgLy8gZWl0aGVyIG5vIGFyZ3VtZW50cyBvciB0aGUgc2VsZWN0b3IgYXJndW1lbnQgaXMgbnVsbC5cbiAgICAgIGlmIChvcmlnR2V0U3RhdHMubGVuZ3RoID09PSAwICYmIChhcmd1bWVudHMubGVuZ3RoID09PSAwIHx8XG4gICAgICAgICAgdHlwZW9mIGFyZ3VtZW50c1swXSAhPT0gJ2Z1bmN0aW9uJykpIHtcbiAgICAgICAgcmV0dXJuIG9yaWdHZXRTdGF0cy5hcHBseSh0aGlzLCBbXSk7XG4gICAgICB9XG5cbiAgICAgIHZhciBmaXhDaHJvbWVTdGF0c18gPSBmdW5jdGlvbihyZXNwb25zZSkge1xuICAgICAgICB2YXIgc3RhbmRhcmRSZXBvcnQgPSB7fTtcbiAgICAgICAgdmFyIHJlcG9ydHMgPSByZXNwb25zZS5yZXN1bHQoKTtcbiAgICAgICAgcmVwb3J0cy5mb3JFYWNoKGZ1bmN0aW9uKHJlcG9ydCkge1xuICAgICAgICAgIHZhciBzdGFuZGFyZFN0YXRzID0ge1xuICAgICAgICAgICAgaWQ6IHJlcG9ydC5pZCxcbiAgICAgICAgICAgIHRpbWVzdGFtcDogcmVwb3J0LnRpbWVzdGFtcCxcbiAgICAgICAgICAgIHR5cGU6IHtcbiAgICAgICAgICAgICAgbG9jYWxjYW5kaWRhdGU6ICdsb2NhbC1jYW5kaWRhdGUnLFxuICAgICAgICAgICAgICByZW1vdGVjYW5kaWRhdGU6ICdyZW1vdGUtY2FuZGlkYXRlJ1xuICAgICAgICAgICAgfVtyZXBvcnQudHlwZV0gfHwgcmVwb3J0LnR5cGVcbiAgICAgICAgICB9O1xuICAgICAgICAgIHJlcG9ydC5uYW1lcygpLmZvckVhY2goZnVuY3Rpb24obmFtZSkge1xuICAgICAgICAgICAgc3RhbmRhcmRTdGF0c1tuYW1lXSA9IHJlcG9ydC5zdGF0KG5hbWUpO1xuICAgICAgICAgIH0pO1xuICAgICAgICAgIHN0YW5kYXJkUmVwb3J0W3N0YW5kYXJkU3RhdHMuaWRdID0gc3RhbmRhcmRTdGF0cztcbiAgICAgICAgfSk7XG5cbiAgICAgICAgcmV0dXJuIHN0YW5kYXJkUmVwb3J0O1xuICAgICAgfTtcblxuICAgICAgLy8gc2hpbSBnZXRTdGF0cyB3aXRoIG1hcGxpa2Ugc3VwcG9ydFxuICAgICAgdmFyIG1ha2VNYXBTdGF0cyA9IGZ1bmN0aW9uKHN0YXRzKSB7XG4gICAgICAgIHJldHVybiBuZXcgTWFwKE9iamVjdC5rZXlzKHN0YXRzKS5tYXAoZnVuY3Rpb24oa2V5KSB7XG4gICAgICAgICAgcmV0dXJuW2tleSwgc3RhdHNba2V5XV07XG4gICAgICAgIH0pKTtcbiAgICAgIH07XG5cbiAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID49IDIpIHtcbiAgICAgICAgdmFyIHN1Y2Nlc3NDYWxsYmFja1dyYXBwZXJfID0gZnVuY3Rpb24ocmVzcG9uc2UpIHtcbiAgICAgICAgICBhcmdzWzFdKG1ha2VNYXBTdGF0cyhmaXhDaHJvbWVTdGF0c18ocmVzcG9uc2UpKSk7XG4gICAgICAgIH07XG5cbiAgICAgICAgcmV0dXJuIG9yaWdHZXRTdGF0cy5hcHBseSh0aGlzLCBbc3VjY2Vzc0NhbGxiYWNrV3JhcHBlcl8sXG4gICAgICAgICAgICBhcmd1bWVudHNbMF1dKTtcbiAgICAgIH1cblxuICAgICAgLy8gcHJvbWlzZS1zdXBwb3J0XG4gICAgICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24ocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgICAgIG9yaWdHZXRTdGF0cy5hcHBseShzZWxmLCBbXG4gICAgICAgICAgZnVuY3Rpb24ocmVzcG9uc2UpIHtcbiAgICAgICAgICAgIHJlc29sdmUobWFrZU1hcFN0YXRzKGZpeENocm9tZVN0YXRzXyhyZXNwb25zZSkpKTtcbiAgICAgICAgICB9LCByZWplY3RdKTtcbiAgICAgIH0pLnRoZW4oc3VjY2Vzc0NhbGxiYWNrLCBlcnJvckNhbGxiYWNrKTtcbiAgICB9O1xuXG4gICAgLy8gYWRkIHByb21pc2Ugc3VwcG9ydCAtLSBuYXRpdmVseSBhdmFpbGFibGUgaW4gQ2hyb21lIDUxXG4gICAgaWYgKGJyb3dzZXJEZXRhaWxzLnZlcnNpb24gPCA1MSkge1xuICAgICAgWydzZXRMb2NhbERlc2NyaXB0aW9uJywgJ3NldFJlbW90ZURlc2NyaXB0aW9uJywgJ2FkZEljZUNhbmRpZGF0ZSddXG4gICAgICAgICAgLmZvckVhY2goZnVuY3Rpb24obWV0aG9kKSB7XG4gICAgICAgICAgICB2YXIgbmF0aXZlTWV0aG9kID0gUlRDUGVlckNvbm5lY3Rpb24ucHJvdG90eXBlW21ldGhvZF07XG4gICAgICAgICAgICBSVENQZWVyQ29ubmVjdGlvbi5wcm90b3R5cGVbbWV0aG9kXSA9IGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgICB2YXIgYXJncyA9IGFyZ3VtZW50cztcbiAgICAgICAgICAgICAgdmFyIHNlbGYgPSB0aGlzO1xuICAgICAgICAgICAgICB2YXIgcHJvbWlzZSA9IG5ldyBQcm9taXNlKGZ1bmN0aW9uKHJlc29sdmUsIHJlamVjdCkge1xuICAgICAgICAgICAgICAgIG5hdGl2ZU1ldGhvZC5hcHBseShzZWxmLCBbYXJnc1swXSwgcmVzb2x2ZSwgcmVqZWN0XSk7XG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICBpZiAoYXJncy5sZW5ndGggPCAyKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHByb21pc2U7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgcmV0dXJuIHByb21pc2UudGhlbihmdW5jdGlvbigpIHtcbiAgICAgICAgICAgICAgICBhcmdzWzFdLmFwcGx5KG51bGwsIFtdKTtcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgZnVuY3Rpb24oZXJyKSB7XG4gICAgICAgICAgICAgICAgaWYgKGFyZ3MubGVuZ3RoID49IDMpIHtcbiAgICAgICAgICAgICAgICAgIGFyZ3NbMl0uYXBwbHkobnVsbCwgW2Vycl0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8vIHByb21pc2Ugc3VwcG9ydCBmb3IgY3JlYXRlT2ZmZXIgYW5kIGNyZWF0ZUFuc3dlci4gQXZhaWxhYmxlICh3aXRob3V0XG4gICAgLy8gYnVncykgc2luY2UgTTUyOiBjcmJ1Zy82MTkyODlcbiAgICBpZiAoYnJvd3NlckRldGFpbHMudmVyc2lvbiA8IDUyKSB7XG4gICAgICBbJ2NyZWF0ZU9mZmVyJywgJ2NyZWF0ZUFuc3dlciddLmZvckVhY2goZnVuY3Rpb24obWV0aG9kKSB7XG4gICAgICAgIHZhciBuYXRpdmVNZXRob2QgPSBSVENQZWVyQ29ubmVjdGlvbi5wcm90b3R5cGVbbWV0aG9kXTtcbiAgICAgICAgUlRDUGVlckNvbm5lY3Rpb24ucHJvdG90eXBlW21ldGhvZF0gPSBmdW5jdGlvbigpIHtcbiAgICAgICAgICB2YXIgc2VsZiA9IHRoaXM7XG4gICAgICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPCAxIHx8IChhcmd1bWVudHMubGVuZ3RoID09PSAxICYmXG4gICAgICAgICAgICAgIHR5cGVvZiBhcmd1bWVudHNbMF0gPT09ICdvYmplY3QnKSkge1xuICAgICAgICAgICAgdmFyIG9wdHMgPSBhcmd1bWVudHMubGVuZ3RoID09PSAxID8gYXJndW1lbnRzWzBdIDogdW5kZWZpbmVkO1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uKHJlc29sdmUsIHJlamVjdCkge1xuICAgICAgICAgICAgICBuYXRpdmVNZXRob2QuYXBwbHkoc2VsZiwgW3Jlc29sdmUsIHJlamVjdCwgb3B0c10pO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiBuYXRpdmVNZXRob2QuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgICAgfTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8vIHNoaW0gaW1wbGljaXQgY3JlYXRpb24gb2YgUlRDU2Vzc2lvbkRlc2NyaXB0aW9uL1JUQ0ljZUNhbmRpZGF0ZVxuICAgIFsnc2V0TG9jYWxEZXNjcmlwdGlvbicsICdzZXRSZW1vdGVEZXNjcmlwdGlvbicsICdhZGRJY2VDYW5kaWRhdGUnXVxuICAgICAgICAuZm9yRWFjaChmdW5jdGlvbihtZXRob2QpIHtcbiAgICAgICAgICB2YXIgbmF0aXZlTWV0aG9kID0gUlRDUGVlckNvbm5lY3Rpb24ucHJvdG90eXBlW21ldGhvZF07XG4gICAgICAgICAgUlRDUGVlckNvbm5lY3Rpb24ucHJvdG90eXBlW21ldGhvZF0gPSBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgIGFyZ3VtZW50c1swXSA9IG5ldyAoKG1ldGhvZCA9PT0gJ2FkZEljZUNhbmRpZGF0ZScpID9cbiAgICAgICAgICAgICAgICBSVENJY2VDYW5kaWRhdGUgOiBSVENTZXNzaW9uRGVzY3JpcHRpb24pKGFyZ3VtZW50c1swXSk7XG4gICAgICAgICAgICByZXR1cm4gbmF0aXZlTWV0aG9kLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICAgICAgfTtcbiAgICAgICAgfSk7XG5cbiAgICAvLyBzdXBwb3J0IGZvciBhZGRJY2VDYW5kaWRhdGUobnVsbCBvciB1bmRlZmluZWQpXG4gICAgdmFyIG5hdGl2ZUFkZEljZUNhbmRpZGF0ZSA9XG4gICAgICAgIFJUQ1BlZXJDb25uZWN0aW9uLnByb3RvdHlwZS5hZGRJY2VDYW5kaWRhdGU7XG4gICAgUlRDUGVlckNvbm5lY3Rpb24ucHJvdG90eXBlLmFkZEljZUNhbmRpZGF0ZSA9IGZ1bmN0aW9uKCkge1xuICAgICAgaWYgKCFhcmd1bWVudHNbMF0pIHtcbiAgICAgICAgaWYgKGFyZ3VtZW50c1sxXSkge1xuICAgICAgICAgIGFyZ3VtZW50c1sxXS5hcHBseShudWxsKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgICB9XG4gICAgICByZXR1cm4gbmF0aXZlQWRkSWNlQ2FuZGlkYXRlLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgfTtcbiAgfVxufTtcblxuXG4vLyBFeHBvc2UgcHVibGljIG1ldGhvZHMuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgc2hpbU1lZGlhU3RyZWFtOiBjaHJvbWVTaGltLnNoaW1NZWRpYVN0cmVhbSxcbiAgc2hpbU9uVHJhY2s6IGNocm9tZVNoaW0uc2hpbU9uVHJhY2ssXG4gIHNoaW1HZXRTZW5kZXJzV2l0aER0bWY6IGNocm9tZVNoaW0uc2hpbUdldFNlbmRlcnNXaXRoRHRtZixcbiAgc2hpbVNvdXJjZU9iamVjdDogY2hyb21lU2hpbS5zaGltU291cmNlT2JqZWN0LFxuICBzaGltUGVlckNvbm5lY3Rpb246IGNocm9tZVNoaW0uc2hpbVBlZXJDb25uZWN0aW9uLFxuICBzaGltR2V0VXNlck1lZGlhOiByZXF1aXJlKCcuL2dldHVzZXJtZWRpYScpXG59O1xuIiwiLypcbiAqICBDb3B5cmlnaHQgKGMpIDIwMTYgVGhlIFdlYlJUQyBwcm9qZWN0IGF1dGhvcnMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKlxuICogIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2VcbiAqICB0aGF0IGNhbiBiZSBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlIGluIHRoZSByb290IG9mIHRoZSBzb3VyY2VcbiAqICB0cmVlLlxuICovXG4gLyogZXNsaW50LWVudiBub2RlICovXG4ndXNlIHN0cmljdCc7XG52YXIgbG9nZ2luZyA9IHJlcXVpcmUoJy4uL3V0aWxzLmpzJykubG9nO1xudmFyIGJyb3dzZXJEZXRhaWxzID0gcmVxdWlyZSgnLi4vdXRpbHMuanMnKS5icm93c2VyRGV0YWlscztcblxuLy8gRXhwb3NlIHB1YmxpYyBtZXRob2RzLlxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbigpIHtcbiAgdmFyIGNvbnN0cmFpbnRzVG9DaHJvbWVfID0gZnVuY3Rpb24oYykge1xuICAgIGlmICh0eXBlb2YgYyAhPT0gJ29iamVjdCcgfHwgYy5tYW5kYXRvcnkgfHwgYy5vcHRpb25hbCkge1xuICAgICAgcmV0dXJuIGM7XG4gICAgfVxuICAgIHZhciBjYyA9IHt9O1xuICAgIE9iamVjdC5rZXlzKGMpLmZvckVhY2goZnVuY3Rpb24oa2V5KSB7XG4gICAgICBpZiAoa2V5ID09PSAncmVxdWlyZScgfHwga2V5ID09PSAnYWR2YW5jZWQnIHx8IGtleSA9PT0gJ21lZGlhU291cmNlJykge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICB2YXIgciA9ICh0eXBlb2YgY1trZXldID09PSAnb2JqZWN0JykgPyBjW2tleV0gOiB7aWRlYWw6IGNba2V5XX07XG4gICAgICBpZiAoci5leGFjdCAhPT0gdW5kZWZpbmVkICYmIHR5cGVvZiByLmV4YWN0ID09PSAnbnVtYmVyJykge1xuICAgICAgICByLm1pbiA9IHIubWF4ID0gci5leGFjdDtcbiAgICAgIH1cbiAgICAgIHZhciBvbGRuYW1lXyA9IGZ1bmN0aW9uKHByZWZpeCwgbmFtZSkge1xuICAgICAgICBpZiAocHJlZml4KSB7XG4gICAgICAgICAgcmV0dXJuIHByZWZpeCArIG5hbWUuY2hhckF0KDApLnRvVXBwZXJDYXNlKCkgKyBuYW1lLnNsaWNlKDEpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiAobmFtZSA9PT0gJ2RldmljZUlkJykgPyAnc291cmNlSWQnIDogbmFtZTtcbiAgICAgIH07XG4gICAgICBpZiAoci5pZGVhbCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGNjLm9wdGlvbmFsID0gY2Mub3B0aW9uYWwgfHwgW107XG4gICAgICAgIHZhciBvYyA9IHt9O1xuICAgICAgICBpZiAodHlwZW9mIHIuaWRlYWwgPT09ICdudW1iZXInKSB7XG4gICAgICAgICAgb2Nbb2xkbmFtZV8oJ21pbicsIGtleSldID0gci5pZGVhbDtcbiAgICAgICAgICBjYy5vcHRpb25hbC5wdXNoKG9jKTtcbiAgICAgICAgICBvYyA9IHt9O1xuICAgICAgICAgIG9jW29sZG5hbWVfKCdtYXgnLCBrZXkpXSA9IHIuaWRlYWw7XG4gICAgICAgICAgY2Mub3B0aW9uYWwucHVzaChvYyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgb2Nbb2xkbmFtZV8oJycsIGtleSldID0gci5pZGVhbDtcbiAgICAgICAgICBjYy5vcHRpb25hbC5wdXNoKG9jKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKHIuZXhhY3QgIT09IHVuZGVmaW5lZCAmJiB0eXBlb2Ygci5leGFjdCAhPT0gJ251bWJlcicpIHtcbiAgICAgICAgY2MubWFuZGF0b3J5ID0gY2MubWFuZGF0b3J5IHx8IHt9O1xuICAgICAgICBjYy5tYW5kYXRvcnlbb2xkbmFtZV8oJycsIGtleSldID0gci5leGFjdDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIFsnbWluJywgJ21heCddLmZvckVhY2goZnVuY3Rpb24obWl4KSB7XG4gICAgICAgICAgaWYgKHJbbWl4XSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBjYy5tYW5kYXRvcnkgPSBjYy5tYW5kYXRvcnkgfHwge307XG4gICAgICAgICAgICBjYy5tYW5kYXRvcnlbb2xkbmFtZV8obWl4LCBrZXkpXSA9IHJbbWl4XTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0pO1xuICAgIGlmIChjLmFkdmFuY2VkKSB7XG4gICAgICBjYy5vcHRpb25hbCA9IChjYy5vcHRpb25hbCB8fCBbXSkuY29uY2F0KGMuYWR2YW5jZWQpO1xuICAgIH1cbiAgICByZXR1cm4gY2M7XG4gIH07XG5cbiAgdmFyIHNoaW1Db25zdHJhaW50c18gPSBmdW5jdGlvbihjb25zdHJhaW50cywgZnVuYykge1xuICAgIGNvbnN0cmFpbnRzID0gSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeShjb25zdHJhaW50cykpO1xuICAgIGlmIChjb25zdHJhaW50cyAmJiBjb25zdHJhaW50cy5hdWRpbykge1xuICAgICAgY29uc3RyYWludHMuYXVkaW8gPSBjb25zdHJhaW50c1RvQ2hyb21lXyhjb25zdHJhaW50cy5hdWRpbyk7XG4gICAgfVxuICAgIGlmIChjb25zdHJhaW50cyAmJiB0eXBlb2YgY29uc3RyYWludHMudmlkZW8gPT09ICdvYmplY3QnKSB7XG4gICAgICAvLyBTaGltIGZhY2luZ01vZGUgZm9yIG1vYmlsZSAmIHN1cmZhY2UgcHJvLlxuICAgICAgdmFyIGZhY2UgPSBjb25zdHJhaW50cy52aWRlby5mYWNpbmdNb2RlO1xuICAgICAgZmFjZSA9IGZhY2UgJiYgKCh0eXBlb2YgZmFjZSA9PT0gJ29iamVjdCcpID8gZmFjZSA6IHtpZGVhbDogZmFjZX0pO1xuICAgICAgdmFyIGdldFN1cHBvcnRlZEZhY2luZ01vZGVMaWVzID0gYnJvd3NlckRldGFpbHMudmVyc2lvbiA8IDYxO1xuXG4gICAgICBpZiAoKGZhY2UgJiYgKGZhY2UuZXhhY3QgPT09ICd1c2VyJyB8fCBmYWNlLmV4YWN0ID09PSAnZW52aXJvbm1lbnQnIHx8XG4gICAgICAgICAgICAgICAgICAgIGZhY2UuaWRlYWwgPT09ICd1c2VyJyB8fCBmYWNlLmlkZWFsID09PSAnZW52aXJvbm1lbnQnKSkgJiZcbiAgICAgICAgICAhKG5hdmlnYXRvci5tZWRpYURldmljZXMuZ2V0U3VwcG9ydGVkQ29uc3RyYWludHMgJiZcbiAgICAgICAgICAgIG5hdmlnYXRvci5tZWRpYURldmljZXMuZ2V0U3VwcG9ydGVkQ29uc3RyYWludHMoKS5mYWNpbmdNb2RlICYmXG4gICAgICAgICAgICAhZ2V0U3VwcG9ydGVkRmFjaW5nTW9kZUxpZXMpKSB7XG4gICAgICAgIGRlbGV0ZSBjb25zdHJhaW50cy52aWRlby5mYWNpbmdNb2RlO1xuICAgICAgICB2YXIgbWF0Y2hlcztcbiAgICAgICAgaWYgKGZhY2UuZXhhY3QgPT09ICdlbnZpcm9ubWVudCcgfHwgZmFjZS5pZGVhbCA9PT0gJ2Vudmlyb25tZW50Jykge1xuICAgICAgICAgIG1hdGNoZXMgPSBbJ2JhY2snLCAncmVhciddO1xuICAgICAgICB9IGVsc2UgaWYgKGZhY2UuZXhhY3QgPT09ICd1c2VyJyB8fCBmYWNlLmlkZWFsID09PSAndXNlcicpIHtcbiAgICAgICAgICBtYXRjaGVzID0gWydmcm9udCddO1xuICAgICAgICB9XG4gICAgICAgIGlmIChtYXRjaGVzKSB7XG4gICAgICAgICAgLy8gTG9vayBmb3IgbWF0Y2hlcyBpbiBsYWJlbCwgb3IgdXNlIGxhc3QgY2FtIGZvciBiYWNrICh0eXBpY2FsKS5cbiAgICAgICAgICByZXR1cm4gbmF2aWdhdG9yLm1lZGlhRGV2aWNlcy5lbnVtZXJhdGVEZXZpY2VzKClcbiAgICAgICAgICAudGhlbihmdW5jdGlvbihkZXZpY2VzKSB7XG4gICAgICAgICAgICBkZXZpY2VzID0gZGV2aWNlcy5maWx0ZXIoZnVuY3Rpb24oZCkge1xuICAgICAgICAgICAgICByZXR1cm4gZC5raW5kID09PSAndmlkZW9pbnB1dCc7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHZhciBkZXYgPSBkZXZpY2VzLmZpbmQoZnVuY3Rpb24oZCkge1xuICAgICAgICAgICAgICByZXR1cm4gbWF0Y2hlcy5zb21lKGZ1bmN0aW9uKG1hdGNoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGQubGFiZWwudG9Mb3dlckNhc2UoKS5pbmRleE9mKG1hdGNoKSAhPT0gLTE7XG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBpZiAoIWRldiAmJiBkZXZpY2VzLmxlbmd0aCAmJiBtYXRjaGVzLmluZGV4T2YoJ2JhY2snKSAhPT0gLTEpIHtcbiAgICAgICAgICAgICAgZGV2ID0gZGV2aWNlc1tkZXZpY2VzLmxlbmd0aCAtIDFdOyAvLyBtb3JlIGxpa2VseSB0aGUgYmFjayBjYW1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChkZXYpIHtcbiAgICAgICAgICAgICAgY29uc3RyYWludHMudmlkZW8uZGV2aWNlSWQgPSBmYWNlLmV4YWN0ID8ge2V4YWN0OiBkZXYuZGV2aWNlSWR9IDpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge2lkZWFsOiBkZXYuZGV2aWNlSWR9O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3RyYWludHMudmlkZW8gPSBjb25zdHJhaW50c1RvQ2hyb21lXyhjb25zdHJhaW50cy52aWRlbyk7XG4gICAgICAgICAgICBsb2dnaW5nKCdjaHJvbWU6ICcgKyBKU09OLnN0cmluZ2lmeShjb25zdHJhaW50cykpO1xuICAgICAgICAgICAgcmV0dXJuIGZ1bmMoY29uc3RyYWludHMpO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBjb25zdHJhaW50cy52aWRlbyA9IGNvbnN0cmFpbnRzVG9DaHJvbWVfKGNvbnN0cmFpbnRzLnZpZGVvKTtcbiAgICB9XG4gICAgbG9nZ2luZygnY2hyb21lOiAnICsgSlNPTi5zdHJpbmdpZnkoY29uc3RyYWludHMpKTtcbiAgICByZXR1cm4gZnVuYyhjb25zdHJhaW50cyk7XG4gIH07XG5cbiAgdmFyIHNoaW1FcnJvcl8gPSBmdW5jdGlvbihlKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIG5hbWU6IHtcbiAgICAgICAgUGVybWlzc2lvbkRlbmllZEVycm9yOiAnTm90QWxsb3dlZEVycm9yJyxcbiAgICAgICAgQ29uc3RyYWludE5vdFNhdGlzZmllZEVycm9yOiAnT3ZlcmNvbnN0cmFpbmVkRXJyb3InXG4gICAgICB9W2UubmFtZV0gfHwgZS5uYW1lLFxuICAgICAgbWVzc2FnZTogZS5tZXNzYWdlLFxuICAgICAgY29uc3RyYWludDogZS5jb25zdHJhaW50TmFtZSxcbiAgICAgIHRvU3RyaW5nOiBmdW5jdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubmFtZSArICh0aGlzLm1lc3NhZ2UgJiYgJzogJykgKyB0aGlzLm1lc3NhZ2U7XG4gICAgICB9XG4gICAgfTtcbiAgfTtcblxuICB2YXIgZ2V0VXNlck1lZGlhXyA9IGZ1bmN0aW9uKGNvbnN0cmFpbnRzLCBvblN1Y2Nlc3MsIG9uRXJyb3IpIHtcbiAgICBzaGltQ29uc3RyYWludHNfKGNvbnN0cmFpbnRzLCBmdW5jdGlvbihjKSB7XG4gICAgICBuYXZpZ2F0b3Iud2Via2l0R2V0VXNlck1lZGlhKGMsIG9uU3VjY2VzcywgZnVuY3Rpb24oZSkge1xuICAgICAgICBvbkVycm9yKHNoaW1FcnJvcl8oZSkpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH07XG5cbiAgbmF2aWdhdG9yLmdldFVzZXJNZWRpYSA9IGdldFVzZXJNZWRpYV87XG5cbiAgLy8gUmV0dXJucyB0aGUgcmVzdWx0IG9mIGdldFVzZXJNZWRpYSBhcyBhIFByb21pc2UuXG4gIHZhciBnZXRVc2VyTWVkaWFQcm9taXNlXyA9IGZ1bmN0aW9uKGNvbnN0cmFpbnRzKSB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uKHJlc29sdmUsIHJlamVjdCkge1xuICAgICAgbmF2aWdhdG9yLmdldFVzZXJNZWRpYShjb25zdHJhaW50cywgcmVzb2x2ZSwgcmVqZWN0KTtcbiAgICB9KTtcbiAgfTtcblxuICBpZiAoIW5hdmlnYXRvci5tZWRpYURldmljZXMpIHtcbiAgICBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzID0ge1xuICAgICAgZ2V0VXNlck1lZGlhOiBnZXRVc2VyTWVkaWFQcm9taXNlXyxcbiAgICAgIGVudW1lcmF0ZURldmljZXM6IGZ1bmN0aW9uKCkge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24ocmVzb2x2ZSkge1xuICAgICAgICAgIHZhciBraW5kcyA9IHthdWRpbzogJ2F1ZGlvaW5wdXQnLCB2aWRlbzogJ3ZpZGVvaW5wdXQnfTtcbiAgICAgICAgICByZXR1cm4gTWVkaWFTdHJlYW1UcmFjay5nZXRTb3VyY2VzKGZ1bmN0aW9uKGRldmljZXMpIHtcbiAgICAgICAgICAgIHJlc29sdmUoZGV2aWNlcy5tYXAoZnVuY3Rpb24oZGV2aWNlKSB7XG4gICAgICAgICAgICAgIHJldHVybiB7bGFiZWw6IGRldmljZS5sYWJlbCxcbiAgICAgICAgICAgICAgICAgICAgICBraW5kOiBraW5kc1tkZXZpY2Uua2luZF0sXG4gICAgICAgICAgICAgICAgICAgICAgZGV2aWNlSWQ6IGRldmljZS5pZCxcbiAgICAgICAgICAgICAgICAgICAgICBncm91cElkOiAnJ307XG4gICAgICAgICAgICB9KSk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgICAgfSxcbiAgICAgIGdldFN1cHBvcnRlZENvbnN0cmFpbnRzOiBmdW5jdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBkZXZpY2VJZDogdHJ1ZSwgZWNob0NhbmNlbGxhdGlvbjogdHJ1ZSwgZmFjaW5nTW9kZTogdHJ1ZSxcbiAgICAgICAgICBmcmFtZVJhdGU6IHRydWUsIGhlaWdodDogdHJ1ZSwgd2lkdGg6IHRydWVcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICB9O1xuICB9XG5cbiAgLy8gQSBzaGltIGZvciBnZXRVc2VyTWVkaWEgbWV0aG9kIG9uIHRoZSBtZWRpYURldmljZXMgb2JqZWN0LlxuICAvLyBUT0RPKEthcHRlbkphbnNzb24pIHJlbW92ZSBvbmNlIGltcGxlbWVudGVkIGluIENocm9tZSBzdGFibGUuXG4gIGlmICghbmF2aWdhdG9yLm1lZGlhRGV2aWNlcy5nZXRVc2VyTWVkaWEpIHtcbiAgICBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmdldFVzZXJNZWRpYSA9IGZ1bmN0aW9uKGNvbnN0cmFpbnRzKSB7XG4gICAgICByZXR1cm4gZ2V0VXNlck1lZGlhUHJvbWlzZV8oY29uc3RyYWludHMpO1xuICAgIH07XG4gIH0gZWxzZSB7XG4gICAgLy8gRXZlbiB0aG91Z2ggQ2hyb21lIDQ1IGhhcyBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzIGFuZCBhIGdldFVzZXJNZWRpYVxuICAgIC8vIGZ1bmN0aW9uIHdoaWNoIHJldHVybnMgYSBQcm9taXNlLCBpdCBkb2VzIG5vdCBhY2NlcHQgc3BlYy1zdHlsZVxuICAgIC8vIGNvbnN0cmFpbnRzLlxuICAgIHZhciBvcmlnR2V0VXNlck1lZGlhID0gbmF2aWdhdG9yLm1lZGlhRGV2aWNlcy5nZXRVc2VyTWVkaWEuXG4gICAgICAgIGJpbmQobmF2aWdhdG9yLm1lZGlhRGV2aWNlcyk7XG4gICAgbmF2aWdhdG9yLm1lZGlhRGV2aWNlcy5nZXRVc2VyTWVkaWEgPSBmdW5jdGlvbihjcykge1xuICAgICAgcmV0dXJuIHNoaW1Db25zdHJhaW50c18oY3MsIGZ1bmN0aW9uKGMpIHtcbiAgICAgICAgcmV0dXJuIG9yaWdHZXRVc2VyTWVkaWEoYykudGhlbihmdW5jdGlvbihzdHJlYW0pIHtcbiAgICAgICAgICBpZiAoYy5hdWRpbyAmJiAhc3RyZWFtLmdldEF1ZGlvVHJhY2tzKCkubGVuZ3RoIHx8XG4gICAgICAgICAgICAgIGMudmlkZW8gJiYgIXN0cmVhbS5nZXRWaWRlb1RyYWNrcygpLmxlbmd0aCkge1xuICAgICAgICAgICAgc3RyZWFtLmdldFRyYWNrcygpLmZvckVhY2goZnVuY3Rpb24odHJhY2spIHtcbiAgICAgICAgICAgICAgdHJhY2suc3RvcCgpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKCcnLCAnTm90Rm91bmRFcnJvcicpO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gc3RyZWFtO1xuICAgICAgICB9LCBmdW5jdGlvbihlKSB7XG4gICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KHNoaW1FcnJvcl8oZSkpO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH07XG4gIH1cblxuICAvLyBEdW1teSBkZXZpY2VjaGFuZ2UgZXZlbnQgbWV0aG9kcy5cbiAgLy8gVE9ETyhLYXB0ZW5KYW5zc29uKSByZW1vdmUgb25jZSBpbXBsZW1lbnRlZCBpbiBDaHJvbWUgc3RhYmxlLlxuICBpZiAodHlwZW9mIG5hdmlnYXRvci5tZWRpYURldmljZXMuYWRkRXZlbnRMaXN0ZW5lciA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmFkZEV2ZW50TGlzdGVuZXIgPSBmdW5jdGlvbigpIHtcbiAgICAgIGxvZ2dpbmcoJ0R1bW15IG1lZGlhRGV2aWNlcy5hZGRFdmVudExpc3RlbmVyIGNhbGxlZC4nKTtcbiAgICB9O1xuICB9XG4gIGlmICh0eXBlb2YgbmF2aWdhdG9yLm1lZGlhRGV2aWNlcy5yZW1vdmVFdmVudExpc3RlbmVyID09PSAndW5kZWZpbmVkJykge1xuICAgIG5hdmlnYXRvci5tZWRpYURldmljZXMucmVtb3ZlRXZlbnRMaXN0ZW5lciA9IGZ1bmN0aW9uKCkge1xuICAgICAgbG9nZ2luZygnRHVtbXkgbWVkaWFEZXZpY2VzLnJlbW92ZUV2ZW50TGlzdGVuZXIgY2FsbGVkLicpO1xuICAgIH07XG4gIH1cbn07XG4iLCIvKlxuICogIENvcHlyaWdodCAoYykgMjAxNiBUaGUgV2ViUlRDIHByb2plY3QgYXV0aG9ycy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqXG4gKiAgVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZVxuICogIHRoYXQgY2FuIGJlIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgaW4gdGhlIHJvb3Qgb2YgdGhlIHNvdXJjZVxuICogIHRyZWUuXG4gKi9cbiAvKiBlc2xpbnQtZW52IG5vZGUgKi9cbid1c2Ugc3RyaWN0JztcblxudmFyIGJyb3dzZXJEZXRhaWxzID0gcmVxdWlyZSgnLi4vdXRpbHMnKS5icm93c2VyRGV0YWlscztcbnZhciBzaGltUlRDUGVlckNvbm5lY3Rpb24gPSByZXF1aXJlKCcuL3J0Y3BlZXJjb25uZWN0aW9uX3NoaW0nKTtcblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIHNoaW1HZXRVc2VyTWVkaWE6IHJlcXVpcmUoJy4vZ2V0dXNlcm1lZGlhJyksXG4gIHNoaW1QZWVyQ29ubmVjdGlvbjogZnVuY3Rpb24oKSB7XG4gICAgaWYgKHdpbmRvdy5SVENJY2VHYXRoZXJlcikge1xuICAgICAgLy8gT1JUQyBkZWZpbmVzIGFuIFJUQ0ljZUNhbmRpZGF0ZSBvYmplY3QgYnV0IG5vIGNvbnN0cnVjdG9yLlxuICAgICAgLy8gTm90IGltcGxlbWVudGVkIGluIEVkZ2UuXG4gICAgICBpZiAoIXdpbmRvdy5SVENJY2VDYW5kaWRhdGUpIHtcbiAgICAgICAgd2luZG93LlJUQ0ljZUNhbmRpZGF0ZSA9IGZ1bmN0aW9uKGFyZ3MpIHtcbiAgICAgICAgICByZXR1cm4gYXJncztcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICAgIC8vIE9SVEMgZG9lcyBub3QgaGF2ZSBhIHNlc3Npb24gZGVzY3JpcHRpb24gb2JqZWN0IGJ1dFxuICAgICAgLy8gb3RoZXIgYnJvd3NlcnMgKGkuZS4gQ2hyb21lKSB0aGF0IHdpbGwgc3VwcG9ydCBib3RoIFBDIGFuZCBPUlRDXG4gICAgICAvLyBpbiB0aGUgZnV0dXJlIG1pZ2h0IGhhdmUgdGhpcyBkZWZpbmVkIGFscmVhZHkuXG4gICAgICBpZiAoIXdpbmRvdy5SVENTZXNzaW9uRGVzY3JpcHRpb24pIHtcbiAgICAgICAgd2luZG93LlJUQ1Nlc3Npb25EZXNjcmlwdGlvbiA9IGZ1bmN0aW9uKGFyZ3MpIHtcbiAgICAgICAgICByZXR1cm4gYXJncztcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICAgIC8vIHRoaXMgYWRkcyBhbiBhZGRpdGlvbmFsIGV2ZW50IGxpc3RlbmVyIHRvIE1lZGlhU3RyYWNrVHJhY2sgdGhhdCBzaWduYWxzXG4gICAgICAvLyB3aGVuIGEgdHJhY2tzIGVuYWJsZWQgcHJvcGVydHkgd2FzIGNoYW5nZWQuIFdvcmthcm91bmQgZm9yIGEgYnVnIGluXG4gICAgICAvLyBhZGRTdHJlYW0sIHNlZSBiZWxvdy4gTm8gbG9uZ2VyIHJlcXVpcmVkIGluIDE1MDI1K1xuICAgICAgaWYgKGJyb3dzZXJEZXRhaWxzLnZlcnNpb24gPCAxNTAyNSkge1xuICAgICAgICB2YXIgb3JpZ01TVEVuYWJsZWQgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKFxuICAgICAgICAgICAgTWVkaWFTdHJlYW1UcmFjay5wcm90b3R5cGUsICdlbmFibGVkJyk7XG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShNZWRpYVN0cmVhbVRyYWNrLnByb3RvdHlwZSwgJ2VuYWJsZWQnLCB7XG4gICAgICAgICAgc2V0OiBmdW5jdGlvbih2YWx1ZSkge1xuICAgICAgICAgICAgb3JpZ01TVEVuYWJsZWQuc2V0LmNhbGwodGhpcywgdmFsdWUpO1xuICAgICAgICAgICAgdmFyIGV2ID0gbmV3IEV2ZW50KCdlbmFibGVkJyk7XG4gICAgICAgICAgICBldi5lbmFibGVkID0gdmFsdWU7XG4gICAgICAgICAgICB0aGlzLmRpc3BhdGNoRXZlbnQoZXYpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuICAgIHdpbmRvdy5SVENQZWVyQ29ubmVjdGlvbiA9IHNoaW1SVENQZWVyQ29ubmVjdGlvbihicm93c2VyRGV0YWlscy52ZXJzaW9uKTtcbiAgfSxcbiAgc2hpbVJlcGxhY2VUcmFjazogZnVuY3Rpb24oKSB7XG4gICAgLy8gT1JUQyBoYXMgcmVwbGFjZVRyYWNrIC0tIGh0dHBzOi8vZ2l0aHViLmNvbS93M2Mvb3J0Yy9pc3N1ZXMvNjE0XG4gICAgaWYgKHdpbmRvdy5SVENSdHBTZW5kZXIgJiYgISgncmVwbGFjZVRyYWNrJyBpbiBSVENSdHBTZW5kZXIucHJvdG90eXBlKSkge1xuICAgICAgUlRDUnRwU2VuZGVyLnByb3RvdHlwZS5yZXBsYWNlVHJhY2sgPSBSVENSdHBTZW5kZXIucHJvdG90eXBlLnNldFRyYWNrO1xuICAgIH1cbiAgfVxufTtcbiIsIi8qXG4gKiAgQ29weXJpZ2h0IChjKSAyMDE2IFRoZSBXZWJSVEMgcHJvamVjdCBhdXRob3JzLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICpcbiAqICBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlXG4gKiAgdGhhdCBjYW4gYmUgZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZSBpbiB0aGUgcm9vdCBvZiB0aGUgc291cmNlXG4gKiAgdHJlZS5cbiAqL1xuIC8qIGVzbGludC1lbnYgbm9kZSAqL1xuJ3VzZSBzdHJpY3QnO1xuXG4vLyBFeHBvc2UgcHVibGljIG1ldGhvZHMuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKCkge1xuICB2YXIgc2hpbUVycm9yXyA9IGZ1bmN0aW9uKGUpIHtcbiAgICByZXR1cm4ge1xuICAgICAgbmFtZToge1Blcm1pc3Npb25EZW5pZWRFcnJvcjogJ05vdEFsbG93ZWRFcnJvcid9W2UubmFtZV0gfHwgZS5uYW1lLFxuICAgICAgbWVzc2FnZTogZS5tZXNzYWdlLFxuICAgICAgY29uc3RyYWludDogZS5jb25zdHJhaW50LFxuICAgICAgdG9TdHJpbmc6IGZ1bmN0aW9uKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5uYW1lO1xuICAgICAgfVxuICAgIH07XG4gIH07XG5cbiAgLy8gZ2V0VXNlck1lZGlhIGVycm9yIHNoaW0uXG4gIHZhciBvcmlnR2V0VXNlck1lZGlhID0gbmF2aWdhdG9yLm1lZGlhRGV2aWNlcy5nZXRVc2VyTWVkaWEuXG4gICAgICBiaW5kKG5hdmlnYXRvci5tZWRpYURldmljZXMpO1xuICBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmdldFVzZXJNZWRpYSA9IGZ1bmN0aW9uKGMpIHtcbiAgICByZXR1cm4gb3JpZ0dldFVzZXJNZWRpYShjKS5jYXRjaChmdW5jdGlvbihlKSB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3Qoc2hpbUVycm9yXyhlKSk7XG4gICAgfSk7XG4gIH07XG59O1xuIiwiLypcbiAqICBDb3B5cmlnaHQgKGMpIDIwMTcgVGhlIFdlYlJUQyBwcm9qZWN0IGF1dGhvcnMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKlxuICogIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2VcbiAqICB0aGF0IGNhbiBiZSBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlIGluIHRoZSByb290IG9mIHRoZSBzb3VyY2VcbiAqICB0cmVlLlxuICovXG4gLyogZXNsaW50LWVudiBub2RlICovXG4ndXNlIHN0cmljdCc7XG5cbnZhciBTRFBVdGlscyA9IHJlcXVpcmUoJ3NkcCcpO1xuXG4vLyBzb3J0IHRyYWNrcyBzdWNoIHRoYXQgdGhleSBmb2xsb3cgYW4gYS12LWEtdi4uLlxuLy8gcGF0dGVybi5cbmZ1bmN0aW9uIHNvcnRUcmFja3ModHJhY2tzKSB7XG4gIHZhciBhdWRpb1RyYWNrcyA9IHRyYWNrcy5maWx0ZXIoZnVuY3Rpb24odHJhY2spIHtcbiAgICByZXR1cm4gdHJhY2sua2luZCA9PT0gJ2F1ZGlvJztcbiAgfSk7XG4gIHZhciB2aWRlb1RyYWNrcyA9IHRyYWNrcy5maWx0ZXIoZnVuY3Rpb24odHJhY2spIHtcbiAgICByZXR1cm4gdHJhY2sua2luZCA9PT0gJ3ZpZGVvJztcbiAgfSk7XG4gIHRyYWNrcyA9IFtdO1xuICB3aGlsZSAoYXVkaW9UcmFja3MubGVuZ3RoIHx8IHZpZGVvVHJhY2tzLmxlbmd0aCkge1xuICAgIGlmIChhdWRpb1RyYWNrcy5sZW5ndGgpIHtcbiAgICAgIHRyYWNrcy5wdXNoKGF1ZGlvVHJhY2tzLnNoaWZ0KCkpO1xuICAgIH1cbiAgICBpZiAodmlkZW9UcmFja3MubGVuZ3RoKSB7XG4gICAgICB0cmFja3MucHVzaCh2aWRlb1RyYWNrcy5zaGlmdCgpKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHRyYWNrcztcbn1cblxuLy8gRWRnZSBkb2VzIG5vdCBsaWtlXG4vLyAxKSBzdHVuOlxuLy8gMikgdHVybjogdGhhdCBkb2VzIG5vdCBoYXZlIGFsbCBvZiB0dXJuOmhvc3Q6cG9ydD90cmFuc3BvcnQ9dWRwXG4vLyAzKSB0dXJuOiB3aXRoIGlwdjYgYWRkcmVzc2VzXG4vLyA0KSB0dXJuOiBvY2N1cnJpbmcgbXVsaXBsZSB0aW1lc1xuZnVuY3Rpb24gZmlsdGVySWNlU2VydmVycyhpY2VTZXJ2ZXJzLCBlZGdlVmVyc2lvbikge1xuICB2YXIgaGFzVHVybiA9IGZhbHNlO1xuICBpY2VTZXJ2ZXJzID0gSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeShpY2VTZXJ2ZXJzKSk7XG4gIHJldHVybiBpY2VTZXJ2ZXJzLmZpbHRlcihmdW5jdGlvbihzZXJ2ZXIpIHtcbiAgICBpZiAoc2VydmVyICYmIChzZXJ2ZXIudXJscyB8fCBzZXJ2ZXIudXJsKSkge1xuICAgICAgdmFyIHVybHMgPSBzZXJ2ZXIudXJscyB8fCBzZXJ2ZXIudXJsO1xuICAgICAgaWYgKHNlcnZlci51cmwgJiYgIXNlcnZlci51cmxzKSB7XG4gICAgICAgIGNvbnNvbGUud2FybignUlRDSWNlU2VydmVyLnVybCBpcyBkZXByZWNhdGVkISBVc2UgdXJscyBpbnN0ZWFkLicpO1xuICAgICAgfVxuICAgICAgdmFyIGlzU3RyaW5nID0gdHlwZW9mIHVybHMgPT09ICdzdHJpbmcnO1xuICAgICAgaWYgKGlzU3RyaW5nKSB7XG4gICAgICAgIHVybHMgPSBbdXJsc107XG4gICAgICB9XG4gICAgICB1cmxzID0gdXJscy5maWx0ZXIoZnVuY3Rpb24odXJsKSB7XG4gICAgICAgIHZhciB2YWxpZFR1cm4gPSB1cmwuaW5kZXhPZigndHVybjonKSA9PT0gMCAmJlxuICAgICAgICAgICAgdXJsLmluZGV4T2YoJ3RyYW5zcG9ydD11ZHAnKSAhPT0gLTEgJiZcbiAgICAgICAgICAgIHVybC5pbmRleE9mKCd0dXJuOlsnKSA9PT0gLTEgJiZcbiAgICAgICAgICAgICFoYXNUdXJuO1xuXG4gICAgICAgIGlmICh2YWxpZFR1cm4pIHtcbiAgICAgICAgICBoYXNUdXJuID0gdHJ1ZTtcbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdXJsLmluZGV4T2YoJ3N0dW46JykgPT09IDAgJiYgZWRnZVZlcnNpb24gPj0gMTQzOTM7XG4gICAgICB9KTtcblxuICAgICAgZGVsZXRlIHNlcnZlci51cmw7XG4gICAgICBzZXJ2ZXIudXJscyA9IGlzU3RyaW5nID8gdXJsc1swXSA6IHVybHM7XG4gICAgICByZXR1cm4gISF1cmxzLmxlbmd0aDtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9KTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihlZGdlVmVyc2lvbikge1xuICB2YXIgUlRDUGVlckNvbm5lY3Rpb24gPSBmdW5jdGlvbihjb25maWcpIHtcbiAgICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgICB2YXIgX2V2ZW50VGFyZ2V0ID0gZG9jdW1lbnQuY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpO1xuICAgIFsnYWRkRXZlbnRMaXN0ZW5lcicsICdyZW1vdmVFdmVudExpc3RlbmVyJywgJ2Rpc3BhdGNoRXZlbnQnXVxuICAgICAgICAuZm9yRWFjaChmdW5jdGlvbihtZXRob2QpIHtcbiAgICAgICAgICBzZWxmW21ldGhvZF0gPSBfZXZlbnRUYXJnZXRbbWV0aG9kXS5iaW5kKF9ldmVudFRhcmdldCk7XG4gICAgICAgIH0pO1xuXG4gICAgdGhpcy5vbmljZWNhbmRpZGF0ZSA9IG51bGw7XG4gICAgdGhpcy5vbmFkZHN0cmVhbSA9IG51bGw7XG4gICAgdGhpcy5vbnRyYWNrID0gbnVsbDtcbiAgICB0aGlzLm9ucmVtb3Zlc3RyZWFtID0gbnVsbDtcbiAgICB0aGlzLm9uc2lnbmFsaW5nc3RhdGVjaGFuZ2UgPSBudWxsO1xuICAgIHRoaXMub25pY2Vjb25uZWN0aW9uc3RhdGVjaGFuZ2UgPSBudWxsO1xuICAgIHRoaXMub25pY2VnYXRoZXJpbmdzdGF0ZWNoYW5nZSA9IG51bGw7XG4gICAgdGhpcy5vbm5lZ290aWF0aW9ubmVlZGVkID0gbnVsbDtcbiAgICB0aGlzLm9uZGF0YWNoYW5uZWwgPSBudWxsO1xuICAgIHRoaXMuY2FuVHJpY2tsZUljZUNhbmRpZGF0ZXMgPSBudWxsO1xuXG4gICAgdGhpcy5sb2NhbFN0cmVhbXMgPSBbXTtcbiAgICB0aGlzLnJlbW90ZVN0cmVhbXMgPSBbXTtcbiAgICB0aGlzLmdldExvY2FsU3RyZWFtcyA9IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHNlbGYubG9jYWxTdHJlYW1zO1xuICAgIH07XG4gICAgdGhpcy5nZXRSZW1vdGVTdHJlYW1zID0gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gc2VsZi5yZW1vdGVTdHJlYW1zO1xuICAgIH07XG5cbiAgICB0aGlzLmxvY2FsRGVzY3JpcHRpb24gPSBuZXcgUlRDU2Vzc2lvbkRlc2NyaXB0aW9uKHtcbiAgICAgIHR5cGU6ICcnLFxuICAgICAgc2RwOiAnJ1xuICAgIH0pO1xuICAgIHRoaXMucmVtb3RlRGVzY3JpcHRpb24gPSBuZXcgUlRDU2Vzc2lvbkRlc2NyaXB0aW9uKHtcbiAgICAgIHR5cGU6ICcnLFxuICAgICAgc2RwOiAnJ1xuICAgIH0pO1xuICAgIHRoaXMuc2lnbmFsaW5nU3RhdGUgPSAnc3RhYmxlJztcbiAgICB0aGlzLmljZUNvbm5lY3Rpb25TdGF0ZSA9ICduZXcnO1xuICAgIHRoaXMuaWNlR2F0aGVyaW5nU3RhdGUgPSAnbmV3JztcblxuICAgIHRoaXMuaWNlT3B0aW9ucyA9IHtcbiAgICAgIGdhdGhlclBvbGljeTogJ2FsbCcsXG4gICAgICBpY2VTZXJ2ZXJzOiBbXVxuICAgIH07XG4gICAgaWYgKGNvbmZpZyAmJiBjb25maWcuaWNlVHJhbnNwb3J0UG9saWN5KSB7XG4gICAgICBzd2l0Y2ggKGNvbmZpZy5pY2VUcmFuc3BvcnRQb2xpY3kpIHtcbiAgICAgICAgY2FzZSAnYWxsJzpcbiAgICAgICAgY2FzZSAncmVsYXknOlxuICAgICAgICAgIHRoaXMuaWNlT3B0aW9ucy5nYXRoZXJQb2xpY3kgPSBjb25maWcuaWNlVHJhbnNwb3J0UG9saWN5O1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIC8vIGRvbid0IHNldCBpY2VUcmFuc3BvcnRQb2xpY3kuXG4gICAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuICAgIHRoaXMudXNpbmdCdW5kbGUgPSBjb25maWcgJiYgY29uZmlnLmJ1bmRsZVBvbGljeSA9PT0gJ21heC1idW5kbGUnO1xuXG4gICAgaWYgKGNvbmZpZyAmJiBjb25maWcuaWNlU2VydmVycykge1xuICAgICAgdGhpcy5pY2VPcHRpb25zLmljZVNlcnZlcnMgPSBmaWx0ZXJJY2VTZXJ2ZXJzKGNvbmZpZy5pY2VTZXJ2ZXJzLFxuICAgICAgICAgIGVkZ2VWZXJzaW9uKTtcbiAgICB9XG4gICAgdGhpcy5fY29uZmlnID0gY29uZmlnIHx8IHt9O1xuXG4gICAgLy8gcGVyLXRyYWNrIGljZUdhdGhlcnMsIGljZVRyYW5zcG9ydHMsIGR0bHNUcmFuc3BvcnRzLCBydHBTZW5kZXJzLCAuLi5cbiAgICAvLyBldmVyeXRoaW5nIHRoYXQgaXMgbmVlZGVkIHRvIGRlc2NyaWJlIGEgU0RQIG0tbGluZS5cbiAgICB0aGlzLnRyYW5zY2VpdmVycyA9IFtdO1xuXG4gICAgLy8gc2luY2UgdGhlIGljZUdhdGhlcmVyIGlzIGN1cnJlbnRseSBjcmVhdGVkIGluIGNyZWF0ZU9mZmVyIGJ1dCB3ZVxuICAgIC8vIG11c3Qgbm90IGVtaXQgY2FuZGlkYXRlcyB1bnRpbCBhZnRlciBzZXRMb2NhbERlc2NyaXB0aW9uIHdlIGJ1ZmZlclxuICAgIC8vIHRoZW0gaW4gdGhpcyBhcnJheS5cbiAgICB0aGlzLl9sb2NhbEljZUNhbmRpZGF0ZXNCdWZmZXIgPSBbXTtcbiAgfTtcblxuICBSVENQZWVyQ29ubmVjdGlvbi5wcm90b3R5cGUuX2VtaXRHYXRoZXJpbmdTdGF0ZUNoYW5nZSA9IGZ1bmN0aW9uKCkge1xuICAgIHZhciBldmVudCA9IG5ldyBFdmVudCgnaWNlZ2F0aGVyaW5nc3RhdGVjaGFuZ2UnKTtcbiAgICB0aGlzLmRpc3BhdGNoRXZlbnQoZXZlbnQpO1xuICAgIGlmICh0aGlzLm9uaWNlZ2F0aGVyaW5nc3RhdGVjaGFuZ2UgIT09IG51bGwpIHtcbiAgICAgIHRoaXMub25pY2VnYXRoZXJpbmdzdGF0ZWNoYW5nZShldmVudCk7XG4gICAgfVxuICB9O1xuXG4gIFJUQ1BlZXJDb25uZWN0aW9uLnByb3RvdHlwZS5fZW1pdEJ1ZmZlcmVkQ2FuZGlkYXRlcyA9IGZ1bmN0aW9uKCkge1xuICAgIHZhciBzZWxmID0gdGhpcztcbiAgICB2YXIgc2VjdGlvbnMgPSBTRFBVdGlscy5zcGxpdFNlY3Rpb25zKHNlbGYubG9jYWxEZXNjcmlwdGlvbi5zZHApO1xuICAgIC8vIEZJWE1FOiBuZWVkIHRvIGFwcGx5IGljZSBjYW5kaWRhdGVzIGluIGEgd2F5IHdoaWNoIGlzIGFzeW5jIGJ1dFxuICAgIC8vIGluLW9yZGVyXG4gICAgdGhpcy5fbG9jYWxJY2VDYW5kaWRhdGVzQnVmZmVyLmZvckVhY2goZnVuY3Rpb24oZXZlbnQpIHtcbiAgICAgIHZhciBlbmQgPSAhZXZlbnQuY2FuZGlkYXRlIHx8IE9iamVjdC5rZXlzKGV2ZW50LmNhbmRpZGF0ZSkubGVuZ3RoID09PSAwO1xuICAgICAgaWYgKGVuZCkge1xuICAgICAgICBmb3IgKHZhciBqID0gMTsgaiA8IHNlY3Rpb25zLmxlbmd0aDsgaisrKSB7XG4gICAgICAgICAgaWYgKHNlY3Rpb25zW2pdLmluZGV4T2YoJ1xcclxcbmE9ZW5kLW9mLWNhbmRpZGF0ZXNcXHJcXG4nKSA9PT0gLTEpIHtcbiAgICAgICAgICAgIHNlY3Rpb25zW2pdICs9ICdhPWVuZC1vZi1jYW5kaWRhdGVzXFxyXFxuJztcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHNlY3Rpb25zW2V2ZW50LmNhbmRpZGF0ZS5zZHBNTGluZUluZGV4ICsgMV0gKz1cbiAgICAgICAgICAgICdhPScgKyBldmVudC5jYW5kaWRhdGUuY2FuZGlkYXRlICsgJ1xcclxcbic7XG4gICAgICB9XG4gICAgICBzZWxmLmxvY2FsRGVzY3JpcHRpb24uc2RwID0gc2VjdGlvbnMuam9pbignJyk7XG4gICAgICBzZWxmLmRpc3BhdGNoRXZlbnQoZXZlbnQpO1xuICAgICAgaWYgKHNlbGYub25pY2VjYW5kaWRhdGUgIT09IG51bGwpIHtcbiAgICAgICAgc2VsZi5vbmljZWNhbmRpZGF0ZShldmVudCk7XG4gICAgICB9XG4gICAgICBpZiAoIWV2ZW50LmNhbmRpZGF0ZSAmJiBzZWxmLmljZUdhdGhlcmluZ1N0YXRlICE9PSAnY29tcGxldGUnKSB7XG4gICAgICAgIHZhciBjb21wbGV0ZSA9IHNlbGYudHJhbnNjZWl2ZXJzLmV2ZXJ5KGZ1bmN0aW9uKHRyYW5zY2VpdmVyKSB7XG4gICAgICAgICAgcmV0dXJuIHRyYW5zY2VpdmVyLmljZUdhdGhlcmVyICYmXG4gICAgICAgICAgICAgIHRyYW5zY2VpdmVyLmljZUdhdGhlcmVyLnN0YXRlID09PSAnY29tcGxldGVkJztcbiAgICAgICAgfSk7XG4gICAgICAgIGlmIChjb21wbGV0ZSAmJiBzZWxmLmljZUdhdGhlcmluZ1N0YXRlQ2hhbmdlICE9PSAnY29tcGxldGUnKSB7XG4gICAgICAgICAgc2VsZi5pY2VHYXRoZXJpbmdTdGF0ZSA9ICdjb21wbGV0ZSc7XG4gICAgICAgICAgc2VsZi5fZW1pdEdhdGhlcmluZ1N0YXRlQ2hhbmdlKCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcbiAgICB0aGlzLl9sb2NhbEljZUNhbmRpZGF0ZXNCdWZmZXIgPSBbXTtcbiAgfTtcblxuICBSVENQZWVyQ29ubmVjdGlvbi5wcm90b3R5cGUuZ2V0Q29uZmlndXJhdGlvbiA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLl9jb25maWc7XG4gIH07XG5cbiAgUlRDUGVlckNvbm5lY3Rpb24ucHJvdG90eXBlLmFkZFN0cmVhbSA9IGZ1bmN0aW9uKHN0cmVhbSkge1xuICAgIGlmIChlZGdlVmVyc2lvbiA+PSAxNTAyNSkge1xuICAgICAgdGhpcy5sb2NhbFN0cmVhbXMucHVzaChzdHJlYW0pO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBDbG9uZSBpcyBuZWNlc3NhcnkgZm9yIGxvY2FsIGRlbW9zIG1vc3RseSwgYXR0YWNoaW5nIGRpcmVjdGx5XG4gICAgICAvLyB0byB0d28gZGlmZmVyZW50IHNlbmRlcnMgZG9lcyBub3Qgd29yayAoYnVpbGQgMTA1NDcpLlxuICAgICAgLy8gRml4ZWQgaW4gMTUwMjUgKG9yIGVhcmxpZXIpXG4gICAgICB2YXIgY2xvbmVkU3RyZWFtID0gc3RyZWFtLmNsb25lKCk7XG4gICAgICBzdHJlYW0uZ2V0VHJhY2tzKCkuZm9yRWFjaChmdW5jdGlvbih0cmFjaywgaWR4KSB7XG4gICAgICAgIHZhciBjbG9uZWRUcmFjayA9IGNsb25lZFN0cmVhbS5nZXRUcmFja3MoKVtpZHhdO1xuICAgICAgICB0cmFjay5hZGRFdmVudExpc3RlbmVyKCdlbmFibGVkJywgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICAgICAgICBjbG9uZWRUcmFjay5lbmFibGVkID0gZXZlbnQuZW5hYmxlZDtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICAgIHRoaXMubG9jYWxTdHJlYW1zLnB1c2goY2xvbmVkU3RyZWFtKTtcbiAgICB9XG4gICAgdGhpcy5fbWF5YmVGaXJlTmVnb3RpYXRpb25OZWVkZWQoKTtcbiAgfTtcblxuICBSVENQZWVyQ29ubmVjdGlvbi5wcm90b3R5cGUucmVtb3ZlU3RyZWFtID0gZnVuY3Rpb24oc3RyZWFtKSB7XG4gICAgdmFyIGlkeCA9IHRoaXMubG9jYWxTdHJlYW1zLmluZGV4T2Yoc3RyZWFtKTtcbiAgICBpZiAoaWR4ID4gLTEpIHtcbiAgICAgIHRoaXMubG9jYWxTdHJlYW1zLnNwbGljZShpZHgsIDEpO1xuICAgICAgdGhpcy5fbWF5YmVGaXJlTmVnb3RpYXRpb25OZWVkZWQoKTtcbiAgICB9XG4gIH07XG5cbiAgUlRDUGVlckNvbm5lY3Rpb24ucHJvdG90eXBlLmdldFNlbmRlcnMgPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gdGhpcy50cmFuc2NlaXZlcnMuZmlsdGVyKGZ1bmN0aW9uKHRyYW5zY2VpdmVyKSB7XG4gICAgICByZXR1cm4gISF0cmFuc2NlaXZlci5ydHBTZW5kZXI7XG4gICAgfSlcbiAgICAubWFwKGZ1bmN0aW9uKHRyYW5zY2VpdmVyKSB7XG4gICAgICByZXR1cm4gdHJhbnNjZWl2ZXIucnRwU2VuZGVyO1xuICAgIH0pO1xuICB9O1xuXG4gIFJUQ1BlZXJDb25uZWN0aW9uLnByb3RvdHlwZS5nZXRSZWNlaXZlcnMgPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gdGhpcy50cmFuc2NlaXZlcnMuZmlsdGVyKGZ1bmN0aW9uKHRyYW5zY2VpdmVyKSB7XG4gICAgICByZXR1cm4gISF0cmFuc2NlaXZlci5ydHBSZWNlaXZlcjtcbiAgICB9KVxuICAgIC5tYXAoZnVuY3Rpb24odHJhbnNjZWl2ZXIpIHtcbiAgICAgIHJldHVybiB0cmFuc2NlaXZlci5ydHBSZWNlaXZlcjtcbiAgICB9KTtcbiAgfTtcblxuICAvLyBEZXRlcm1pbmVzIHRoZSBpbnRlcnNlY3Rpb24gb2YgbG9jYWwgYW5kIHJlbW90ZSBjYXBhYmlsaXRpZXMuXG4gIFJUQ1BlZXJDb25uZWN0aW9uLnByb3RvdHlwZS5fZ2V0Q29tbW9uQ2FwYWJpbGl0aWVzID0gZnVuY3Rpb24oXG4gICAgICBsb2NhbENhcGFiaWxpdGllcywgcmVtb3RlQ2FwYWJpbGl0aWVzKSB7XG4gICAgdmFyIGNvbW1vbkNhcGFiaWxpdGllcyA9IHtcbiAgICAgIGNvZGVjczogW10sXG4gICAgICBoZWFkZXJFeHRlbnNpb25zOiBbXSxcbiAgICAgIGZlY01lY2hhbmlzbXM6IFtdXG4gICAgfTtcblxuICAgIHZhciBmaW5kQ29kZWNCeVBheWxvYWRUeXBlID0gZnVuY3Rpb24ocHQsIGNvZGVjcykge1xuICAgICAgcHQgPSBwYXJzZUludChwdCwgMTApO1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBjb2RlY3MubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgaWYgKGNvZGVjc1tpXS5wYXlsb2FkVHlwZSA9PT0gcHQgfHxcbiAgICAgICAgICAgIGNvZGVjc1tpXS5wcmVmZXJyZWRQYXlsb2FkVHlwZSA9PT0gcHQpIHtcbiAgICAgICAgICByZXR1cm4gY29kZWNzW2ldO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfTtcblxuICAgIHZhciBydHhDYXBhYmlsaXR5TWF0Y2hlcyA9IGZ1bmN0aW9uKGxSdHgsIHJSdHgsIGxDb2RlY3MsIHJDb2RlY3MpIHtcbiAgICAgIHZhciBsQ29kZWMgPSBmaW5kQ29kZWNCeVBheWxvYWRUeXBlKGxSdHgucGFyYW1ldGVycy5hcHQsIGxDb2RlY3MpO1xuICAgICAgdmFyIHJDb2RlYyA9IGZpbmRDb2RlY0J5UGF5bG9hZFR5cGUoclJ0eC5wYXJhbWV0ZXJzLmFwdCwgckNvZGVjcyk7XG4gICAgICByZXR1cm4gbENvZGVjICYmIHJDb2RlYyAmJlxuICAgICAgICAgIGxDb2RlYy5uYW1lLnRvTG93ZXJDYXNlKCkgPT09IHJDb2RlYy5uYW1lLnRvTG93ZXJDYXNlKCk7XG4gICAgfTtcblxuICAgIGxvY2FsQ2FwYWJpbGl0aWVzLmNvZGVjcy5mb3JFYWNoKGZ1bmN0aW9uKGxDb2RlYykge1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCByZW1vdGVDYXBhYmlsaXRpZXMuY29kZWNzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHZhciByQ29kZWMgPSByZW1vdGVDYXBhYmlsaXRpZXMuY29kZWNzW2ldO1xuICAgICAgICBpZiAobENvZGVjLm5hbWUudG9Mb3dlckNhc2UoKSA9PT0gckNvZGVjLm5hbWUudG9Mb3dlckNhc2UoKSAmJlxuICAgICAgICAgICAgbENvZGVjLmNsb2NrUmF0ZSA9PT0gckNvZGVjLmNsb2NrUmF0ZSkge1xuICAgICAgICAgIGlmIChsQ29kZWMubmFtZS50b0xvd2VyQ2FzZSgpID09PSAncnR4JyAmJlxuICAgICAgICAgICAgICBsQ29kZWMucGFyYW1ldGVycyAmJiByQ29kZWMucGFyYW1ldGVycy5hcHQpIHtcbiAgICAgICAgICAgIC8vIGZvciBSVFggd2UgbmVlZCB0byBmaW5kIHRoZSBsb2NhbCBydHggdGhhdCBoYXMgYSBhcHRcbiAgICAgICAgICAgIC8vIHdoaWNoIHBvaW50cyB0byB0aGUgc2FtZSBsb2NhbCBjb2RlYyBhcyB0aGUgcmVtb3RlIG9uZS5cbiAgICAgICAgICAgIGlmICghcnR4Q2FwYWJpbGl0eU1hdGNoZXMobENvZGVjLCByQ29kZWMsXG4gICAgICAgICAgICAgICAgbG9jYWxDYXBhYmlsaXRpZXMuY29kZWNzLCByZW1vdGVDYXBhYmlsaXRpZXMuY29kZWNzKSkge1xuICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgckNvZGVjID0gSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeShyQ29kZWMpKTsgLy8gZGVlcGNvcHlcbiAgICAgICAgICAvLyBudW1iZXIgb2YgY2hhbm5lbHMgaXMgdGhlIGhpZ2hlc3QgY29tbW9uIG51bWJlciBvZiBjaGFubmVsc1xuICAgICAgICAgIHJDb2RlYy5udW1DaGFubmVscyA9IE1hdGgubWluKGxDb2RlYy5udW1DaGFubmVscyxcbiAgICAgICAgICAgICAgckNvZGVjLm51bUNoYW5uZWxzKTtcbiAgICAgICAgICAvLyBwdXNoIHJDb2RlYyBzbyB3ZSByZXBseSB3aXRoIG9mZmVyZXIgcGF5bG9hZCB0eXBlXG4gICAgICAgICAgY29tbW9uQ2FwYWJpbGl0aWVzLmNvZGVjcy5wdXNoKHJDb2RlYyk7XG5cbiAgICAgICAgICAvLyBkZXRlcm1pbmUgY29tbW9uIGZlZWRiYWNrIG1lY2hhbmlzbXNcbiAgICAgICAgICByQ29kZWMucnRjcEZlZWRiYWNrID0gckNvZGVjLnJ0Y3BGZWVkYmFjay5maWx0ZXIoZnVuY3Rpb24oZmIpIHtcbiAgICAgICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgbENvZGVjLnJ0Y3BGZWVkYmFjay5sZW5ndGg7IGorKykge1xuICAgICAgICAgICAgICBpZiAobENvZGVjLnJ0Y3BGZWVkYmFja1tqXS50eXBlID09PSBmYi50eXBlICYmXG4gICAgICAgICAgICAgICAgICBsQ29kZWMucnRjcEZlZWRiYWNrW2pdLnBhcmFtZXRlciA9PT0gZmIucGFyYW1ldGVyKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgICAvLyBGSVhNRTogYWxzbyBuZWVkIHRvIGRldGVybWluZSAucGFyYW1ldGVyc1xuICAgICAgICAgIC8vICBzZWUgaHR0cHM6Ly9naXRodWIuY29tL29wZW5wZWVyL29ydGMvaXNzdWVzLzU2OVxuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBsb2NhbENhcGFiaWxpdGllcy5oZWFkZXJFeHRlbnNpb25zXG4gICAgICAgIC5mb3JFYWNoKGZ1bmN0aW9uKGxIZWFkZXJFeHRlbnNpb24pIHtcbiAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHJlbW90ZUNhcGFiaWxpdGllcy5oZWFkZXJFeHRlbnNpb25zLmxlbmd0aDtcbiAgICAgICAgICAgICAgIGkrKykge1xuICAgICAgICAgICAgdmFyIHJIZWFkZXJFeHRlbnNpb24gPSByZW1vdGVDYXBhYmlsaXRpZXMuaGVhZGVyRXh0ZW5zaW9uc1tpXTtcbiAgICAgICAgICAgIGlmIChsSGVhZGVyRXh0ZW5zaW9uLnVyaSA9PT0gckhlYWRlckV4dGVuc2lvbi51cmkpIHtcbiAgICAgICAgICAgICAgY29tbW9uQ2FwYWJpbGl0aWVzLmhlYWRlckV4dGVuc2lvbnMucHVzaChySGVhZGVyRXh0ZW5zaW9uKTtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgIC8vIEZJWE1FOiBmZWNNZWNoYW5pc21zXG4gICAgcmV0dXJuIGNvbW1vbkNhcGFiaWxpdGllcztcbiAgfTtcblxuICAvLyBDcmVhdGUgSUNFIGdhdGhlcmVyLCBJQ0UgdHJhbnNwb3J0IGFuZCBEVExTIHRyYW5zcG9ydC5cbiAgUlRDUGVlckNvbm5lY3Rpb24ucHJvdG90eXBlLl9jcmVhdGVJY2VBbmREdGxzVHJhbnNwb3J0cyA9IGZ1bmN0aW9uKG1pZCxcbiAgICAgIHNkcE1MaW5lSW5kZXgpIHtcbiAgICB2YXIgc2VsZiA9IHRoaXM7XG4gICAgdmFyIGljZUdhdGhlcmVyID0gbmV3IFJUQ0ljZUdhdGhlcmVyKHNlbGYuaWNlT3B0aW9ucyk7XG4gICAgdmFyIGljZVRyYW5zcG9ydCA9IG5ldyBSVENJY2VUcmFuc3BvcnQoaWNlR2F0aGVyZXIpO1xuICAgIGljZUdhdGhlcmVyLm9ubG9jYWxjYW5kaWRhdGUgPSBmdW5jdGlvbihldnQpIHtcbiAgICAgIHZhciBldmVudCA9IG5ldyBFdmVudCgnaWNlY2FuZGlkYXRlJyk7XG4gICAgICBldmVudC5jYW5kaWRhdGUgPSB7c2RwTWlkOiBtaWQsIHNkcE1MaW5lSW5kZXg6IHNkcE1MaW5lSW5kZXh9O1xuXG4gICAgICB2YXIgY2FuZCA9IGV2dC5jYW5kaWRhdGU7XG4gICAgICB2YXIgZW5kID0gIWNhbmQgfHwgT2JqZWN0LmtleXMoY2FuZCkubGVuZ3RoID09PSAwO1xuICAgICAgLy8gRWRnZSBlbWl0cyBhbiBlbXB0eSBvYmplY3QgZm9yIFJUQ0ljZUNhbmRpZGF0ZUNvbXBsZXRl4oClXG4gICAgICBpZiAoZW5kKSB7XG4gICAgICAgIC8vIHBvbHlmaWxsIHNpbmNlIFJUQ0ljZUdhdGhlcmVyLnN0YXRlIGlzIG5vdCBpbXBsZW1lbnRlZCBpblxuICAgICAgICAvLyBFZGdlIDEwNTQ3IHlldC5cbiAgICAgICAgaWYgKGljZUdhdGhlcmVyLnN0YXRlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICBpY2VHYXRoZXJlci5zdGF0ZSA9ICdjb21wbGV0ZWQnO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBSVENJY2VDYW5kaWRhdGUgZG9lc24ndCBoYXZlIGEgY29tcG9uZW50LCBuZWVkcyB0byBiZSBhZGRlZFxuICAgICAgICBjYW5kLmNvbXBvbmVudCA9IGljZVRyYW5zcG9ydC5jb21wb25lbnQgPT09ICdSVENQJyA/IDIgOiAxO1xuICAgICAgICBldmVudC5jYW5kaWRhdGUuY2FuZGlkYXRlID0gU0RQVXRpbHMud3JpdGVDYW5kaWRhdGUoY2FuZCk7XG4gICAgICB9XG5cbiAgICAgIC8vIHVwZGF0ZSBsb2NhbCBkZXNjcmlwdGlvbi5cbiAgICAgIHZhciBzZWN0aW9ucyA9IFNEUFV0aWxzLnNwbGl0U2VjdGlvbnMoc2VsZi5sb2NhbERlc2NyaXB0aW9uLnNkcCk7XG4gICAgICBpZiAoIWVuZCkge1xuICAgICAgICBzZWN0aW9uc1tldmVudC5jYW5kaWRhdGUuc2RwTUxpbmVJbmRleCArIDFdICs9XG4gICAgICAgICAgICAnYT0nICsgZXZlbnQuY2FuZGlkYXRlLmNhbmRpZGF0ZSArICdcXHJcXG4nO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc2VjdGlvbnNbZXZlbnQuY2FuZGlkYXRlLnNkcE1MaW5lSW5kZXggKyAxXSArPVxuICAgICAgICAgICAgJ2E9ZW5kLW9mLWNhbmRpZGF0ZXNcXHJcXG4nO1xuICAgICAgfVxuICAgICAgc2VsZi5sb2NhbERlc2NyaXB0aW9uLnNkcCA9IHNlY3Rpb25zLmpvaW4oJycpO1xuICAgICAgdmFyIHRyYW5zY2VpdmVycyA9IHNlbGYuX3BlbmRpbmdPZmZlciA/IHNlbGYuX3BlbmRpbmdPZmZlciA6XG4gICAgICAgICAgc2VsZi50cmFuc2NlaXZlcnM7XG4gICAgICB2YXIgY29tcGxldGUgPSB0cmFuc2NlaXZlcnMuZXZlcnkoZnVuY3Rpb24odHJhbnNjZWl2ZXIpIHtcbiAgICAgICAgcmV0dXJuIHRyYW5zY2VpdmVyLmljZUdhdGhlcmVyICYmXG4gICAgICAgICAgICB0cmFuc2NlaXZlci5pY2VHYXRoZXJlci5zdGF0ZSA9PT0gJ2NvbXBsZXRlZCc7XG4gICAgICB9KTtcblxuICAgICAgLy8gRW1pdCBjYW5kaWRhdGUgaWYgbG9jYWxEZXNjcmlwdGlvbiBpcyBzZXQuXG4gICAgICAvLyBBbHNvIGVtaXRzIG51bGwgY2FuZGlkYXRlIHdoZW4gYWxsIGdhdGhlcmVycyBhcmUgY29tcGxldGUuXG4gICAgICBzd2l0Y2ggKHNlbGYuaWNlR2F0aGVyaW5nU3RhdGUpIHtcbiAgICAgICAgY2FzZSAnbmV3JzpcbiAgICAgICAgICBpZiAoIWVuZCkge1xuICAgICAgICAgICAgc2VsZi5fbG9jYWxJY2VDYW5kaWRhdGVzQnVmZmVyLnB1c2goZXZlbnQpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoZW5kICYmIGNvbXBsZXRlKSB7XG4gICAgICAgICAgICBzZWxmLl9sb2NhbEljZUNhbmRpZGF0ZXNCdWZmZXIucHVzaChcbiAgICAgICAgICAgICAgICBuZXcgRXZlbnQoJ2ljZWNhbmRpZGF0ZScpKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ2dhdGhlcmluZyc6XG4gICAgICAgICAgc2VsZi5fZW1pdEJ1ZmZlcmVkQ2FuZGlkYXRlcygpO1xuICAgICAgICAgIGlmICghZW5kKSB7XG4gICAgICAgICAgICBzZWxmLmRpc3BhdGNoRXZlbnQoZXZlbnQpO1xuICAgICAgICAgICAgaWYgKHNlbGYub25pY2VjYW5kaWRhdGUgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgc2VsZi5vbmljZWNhbmRpZGF0ZShldmVudCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChjb21wbGV0ZSkge1xuICAgICAgICAgICAgc2VsZi5kaXNwYXRjaEV2ZW50KG5ldyBFdmVudCgnaWNlY2FuZGlkYXRlJykpO1xuICAgICAgICAgICAgaWYgKHNlbGYub25pY2VjYW5kaWRhdGUgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgc2VsZi5vbmljZWNhbmRpZGF0ZShuZXcgRXZlbnQoJ2ljZWNhbmRpZGF0ZScpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHNlbGYuaWNlR2F0aGVyaW5nU3RhdGUgPSAnY29tcGxldGUnO1xuICAgICAgICAgICAgc2VsZi5fZW1pdEdhdGhlcmluZ1N0YXRlQ2hhbmdlKCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdjb21wbGV0ZSc6XG4gICAgICAgICAgLy8gc2hvdWxkIG5vdCBoYXBwZW4uLi4gY3VycmVudGx5IVxuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBkZWZhdWx0OiAvLyBuby1vcC5cbiAgICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9O1xuICAgIGljZVRyYW5zcG9ydC5vbmljZXN0YXRlY2hhbmdlID0gZnVuY3Rpb24oKSB7XG4gICAgICBzZWxmLl91cGRhdGVDb25uZWN0aW9uU3RhdGUoKTtcbiAgICB9O1xuXG4gICAgdmFyIGR0bHNUcmFuc3BvcnQgPSBuZXcgUlRDRHRsc1RyYW5zcG9ydChpY2VUcmFuc3BvcnQpO1xuICAgIGR0bHNUcmFuc3BvcnQub25kdGxzc3RhdGVjaGFuZ2UgPSBmdW5jdGlvbigpIHtcbiAgICAgIHNlbGYuX3VwZGF0ZUNvbm5lY3Rpb25TdGF0ZSgpO1xuICAgIH07XG4gICAgZHRsc1RyYW5zcG9ydC5vbmVycm9yID0gZnVuY3Rpb24oKSB7XG4gICAgICAvLyBvbmVycm9yIGRvZXMgbm90IHNldCBzdGF0ZSB0byBmYWlsZWQgYnkgaXRzZWxmLlxuICAgICAgZHRsc1RyYW5zcG9ydC5zdGF0ZSA9ICdmYWlsZWQnO1xuICAgICAgc2VsZi5fdXBkYXRlQ29ubmVjdGlvblN0YXRlKCk7XG4gICAgfTtcblxuICAgIHJldHVybiB7XG4gICAgICBpY2VHYXRoZXJlcjogaWNlR2F0aGVyZXIsXG4gICAgICBpY2VUcmFuc3BvcnQ6IGljZVRyYW5zcG9ydCxcbiAgICAgIGR0bHNUcmFuc3BvcnQ6IGR0bHNUcmFuc3BvcnRcbiAgICB9O1xuICB9O1xuXG4gIC8vIERlc3Ryb3kgSUNFIGdhdGhlcmVyLCBJQ0UgdHJhbnNwb3J0IGFuZCBEVExTIHRyYW5zcG9ydC5cbiAgLy8gV2l0aG91dCB0cmlnZ2VyaW5nIHRoZSBjYWxsYmFja3MuXG4gIFJUQ1BlZXJDb25uZWN0aW9uLnByb3RvdHlwZS5fZGlzcG9zZUljZUFuZER0bHNUcmFuc3BvcnRzID0gZnVuY3Rpb24oXG4gICAgICBzZHBNTGluZUluZGV4KSB7XG4gICAgdmFyIGljZUdhdGhlcmVyID0gdGhpcy50cmFuc2NlaXZlcnNbc2RwTUxpbmVJbmRleF0uaWNlR2F0aGVyZXI7XG4gICAgaWYgKGljZUdhdGhlcmVyKSB7XG4gICAgICBkZWxldGUgaWNlR2F0aGVyZXIub25sb2NhbGNhbmRpZGF0ZTtcbiAgICAgIGRlbGV0ZSB0aGlzLnRyYW5zY2VpdmVyc1tzZHBNTGluZUluZGV4XS5pY2VHYXRoZXJlcjtcbiAgICB9XG4gICAgdmFyIGljZVRyYW5zcG9ydCA9IHRoaXMudHJhbnNjZWl2ZXJzW3NkcE1MaW5lSW5kZXhdLmljZVRyYW5zcG9ydDtcbiAgICBpZiAoaWNlVHJhbnNwb3J0KSB7XG4gICAgICBkZWxldGUgaWNlVHJhbnNwb3J0Lm9uaWNlc3RhdGVjaGFuZ2U7XG4gICAgICBkZWxldGUgdGhpcy50cmFuc2NlaXZlcnNbc2RwTUxpbmVJbmRleF0uaWNlVHJhbnNwb3J0O1xuICAgIH1cbiAgICB2YXIgZHRsc1RyYW5zcG9ydCA9IHRoaXMudHJhbnNjZWl2ZXJzW3NkcE1MaW5lSW5kZXhdLmR0bHNUcmFuc3BvcnQ7XG4gICAgaWYgKGR0bHNUcmFuc3BvcnQpIHtcbiAgICAgIGRlbGV0ZSBkdGxzVHJhbnNwb3J0Lm9uZHRsc3N0dGF0ZWNoYW5nZTtcbiAgICAgIGRlbGV0ZSBkdGxzVHJhbnNwb3J0Lm9uZXJyb3I7XG4gICAgICBkZWxldGUgdGhpcy50cmFuc2NlaXZlcnNbc2RwTUxpbmVJbmRleF0uZHRsc1RyYW5zcG9ydDtcbiAgICB9XG4gIH07XG5cbiAgLy8gU3RhcnQgdGhlIFJUUCBTZW5kZXIgYW5kIFJlY2VpdmVyIGZvciBhIHRyYW5zY2VpdmVyLlxuICBSVENQZWVyQ29ubmVjdGlvbi5wcm90b3R5cGUuX3RyYW5zY2VpdmUgPSBmdW5jdGlvbih0cmFuc2NlaXZlcixcbiAgICAgIHNlbmQsIHJlY3YpIHtcbiAgICB2YXIgcGFyYW1zID0gdGhpcy5fZ2V0Q29tbW9uQ2FwYWJpbGl0aWVzKHRyYW5zY2VpdmVyLmxvY2FsQ2FwYWJpbGl0aWVzLFxuICAgICAgICB0cmFuc2NlaXZlci5yZW1vdGVDYXBhYmlsaXRpZXMpO1xuICAgIGlmIChzZW5kICYmIHRyYW5zY2VpdmVyLnJ0cFNlbmRlcikge1xuICAgICAgcGFyYW1zLmVuY29kaW5ncyA9IHRyYW5zY2VpdmVyLnNlbmRFbmNvZGluZ1BhcmFtZXRlcnM7XG4gICAgICBwYXJhbXMucnRjcCA9IHtcbiAgICAgICAgY25hbWU6IFNEUFV0aWxzLmxvY2FsQ05hbWUsXG4gICAgICAgIGNvbXBvdW5kOiB0cmFuc2NlaXZlci5ydGNwUGFyYW1ldGVycy5jb21wb3VuZFxuICAgICAgfTtcbiAgICAgIGlmICh0cmFuc2NlaXZlci5yZWN2RW5jb2RpbmdQYXJhbWV0ZXJzLmxlbmd0aCkge1xuICAgICAgICBwYXJhbXMucnRjcC5zc3JjID0gdHJhbnNjZWl2ZXIucmVjdkVuY29kaW5nUGFyYW1ldGVyc1swXS5zc3JjO1xuICAgICAgfVxuICAgICAgdHJhbnNjZWl2ZXIucnRwU2VuZGVyLnNlbmQocGFyYW1zKTtcbiAgICB9XG4gICAgaWYgKHJlY3YgJiYgdHJhbnNjZWl2ZXIucnRwUmVjZWl2ZXIpIHtcbiAgICAgIC8vIHJlbW92ZSBSVFggZmllbGQgaW4gRWRnZSAxNDk0MlxuICAgICAgaWYgKHRyYW5zY2VpdmVyLmtpbmQgPT09ICd2aWRlbydcbiAgICAgICAgICAmJiB0cmFuc2NlaXZlci5yZWN2RW5jb2RpbmdQYXJhbWV0ZXJzXG4gICAgICAgICAgJiYgZWRnZVZlcnNpb24gPCAxNTAxOSkge1xuICAgICAgICB0cmFuc2NlaXZlci5yZWN2RW5jb2RpbmdQYXJhbWV0ZXJzLmZvckVhY2goZnVuY3Rpb24ocCkge1xuICAgICAgICAgIGRlbGV0ZSBwLnJ0eDtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICBwYXJhbXMuZW5jb2RpbmdzID0gdHJhbnNjZWl2ZXIucmVjdkVuY29kaW5nUGFyYW1ldGVycztcbiAgICAgIHBhcmFtcy5ydGNwID0ge1xuICAgICAgICBjbmFtZTogdHJhbnNjZWl2ZXIucnRjcFBhcmFtZXRlcnMuY25hbWUsXG4gICAgICAgIGNvbXBvdW5kOiB0cmFuc2NlaXZlci5ydGNwUGFyYW1ldGVycy5jb21wb3VuZFxuICAgICAgfTtcbiAgICAgIGlmICh0cmFuc2NlaXZlci5zZW5kRW5jb2RpbmdQYXJhbWV0ZXJzLmxlbmd0aCkge1xuICAgICAgICBwYXJhbXMucnRjcC5zc3JjID0gdHJhbnNjZWl2ZXIuc2VuZEVuY29kaW5nUGFyYW1ldGVyc1swXS5zc3JjO1xuICAgICAgfVxuICAgICAgdHJhbnNjZWl2ZXIucnRwUmVjZWl2ZXIucmVjZWl2ZShwYXJhbXMpO1xuICAgIH1cbiAgfTtcblxuICBSVENQZWVyQ29ubmVjdGlvbi5wcm90b3R5cGUuc2V0TG9jYWxEZXNjcmlwdGlvbiA9IGZ1bmN0aW9uKGRlc2NyaXB0aW9uKSB7XG4gICAgdmFyIHNlbGYgPSB0aGlzO1xuICAgIHZhciBzZWN0aW9ucztcbiAgICB2YXIgc2Vzc2lvbnBhcnQ7XG4gICAgaWYgKGRlc2NyaXB0aW9uLnR5cGUgPT09ICdvZmZlcicpIHtcbiAgICAgIC8vIEZJWE1FOiBXaGF0IHdhcyB0aGUgcHVycG9zZSBvZiB0aGlzIGVtcHR5IGlmIHN0YXRlbWVudD9cbiAgICAgIC8vIGlmICghdGhpcy5fcGVuZGluZ09mZmVyKSB7XG4gICAgICAvLyB9IGVsc2Uge1xuICAgICAgaWYgKHRoaXMuX3BlbmRpbmdPZmZlcikge1xuICAgICAgICAvLyBWRVJZIGxpbWl0ZWQgc3VwcG9ydCBmb3IgU0RQIG11bmdpbmcuIExpbWl0ZWQgdG86XG4gICAgICAgIC8vICogY2hhbmdpbmcgdGhlIG9yZGVyIG9mIGNvZGVjc1xuICAgICAgICBzZWN0aW9ucyA9IFNEUFV0aWxzLnNwbGl0U2VjdGlvbnMoZGVzY3JpcHRpb24uc2RwKTtcbiAgICAgICAgc2Vzc2lvbnBhcnQgPSBzZWN0aW9ucy5zaGlmdCgpO1xuICAgICAgICBzZWN0aW9ucy5mb3JFYWNoKGZ1bmN0aW9uKG1lZGlhU2VjdGlvbiwgc2RwTUxpbmVJbmRleCkge1xuICAgICAgICAgIHZhciBjYXBzID0gU0RQVXRpbHMucGFyc2VSdHBQYXJhbWV0ZXJzKG1lZGlhU2VjdGlvbik7XG4gICAgICAgICAgc2VsZi5fcGVuZGluZ09mZmVyW3NkcE1MaW5lSW5kZXhdLmxvY2FsQ2FwYWJpbGl0aWVzID0gY2FwcztcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMudHJhbnNjZWl2ZXJzID0gdGhpcy5fcGVuZGluZ09mZmVyO1xuICAgICAgICBkZWxldGUgdGhpcy5fcGVuZGluZ09mZmVyO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoZGVzY3JpcHRpb24udHlwZSA9PT0gJ2Fuc3dlcicpIHtcbiAgICAgIHNlY3Rpb25zID0gU0RQVXRpbHMuc3BsaXRTZWN0aW9ucyhzZWxmLnJlbW90ZURlc2NyaXB0aW9uLnNkcCk7XG4gICAgICBzZXNzaW9ucGFydCA9IHNlY3Rpb25zLnNoaWZ0KCk7XG4gICAgICB2YXIgaXNJY2VMaXRlID0gU0RQVXRpbHMubWF0Y2hQcmVmaXgoc2Vzc2lvbnBhcnQsXG4gICAgICAgICAgJ2E9aWNlLWxpdGUnKS5sZW5ndGggPiAwO1xuICAgICAgc2VjdGlvbnMuZm9yRWFjaChmdW5jdGlvbihtZWRpYVNlY3Rpb24sIHNkcE1MaW5lSW5kZXgpIHtcbiAgICAgICAgdmFyIHRyYW5zY2VpdmVyID0gc2VsZi50cmFuc2NlaXZlcnNbc2RwTUxpbmVJbmRleF07XG4gICAgICAgIHZhciBpY2VHYXRoZXJlciA9IHRyYW5zY2VpdmVyLmljZUdhdGhlcmVyO1xuICAgICAgICB2YXIgaWNlVHJhbnNwb3J0ID0gdHJhbnNjZWl2ZXIuaWNlVHJhbnNwb3J0O1xuICAgICAgICB2YXIgZHRsc1RyYW5zcG9ydCA9IHRyYW5zY2VpdmVyLmR0bHNUcmFuc3BvcnQ7XG4gICAgICAgIHZhciBsb2NhbENhcGFiaWxpdGllcyA9IHRyYW5zY2VpdmVyLmxvY2FsQ2FwYWJpbGl0aWVzO1xuICAgICAgICB2YXIgcmVtb3RlQ2FwYWJpbGl0aWVzID0gdHJhbnNjZWl2ZXIucmVtb3RlQ2FwYWJpbGl0aWVzO1xuXG4gICAgICAgIHZhciByZWplY3RlZCA9IG1lZGlhU2VjdGlvbi5zcGxpdCgnXFxuJywgMSlbMF1cbiAgICAgICAgICAgIC5zcGxpdCgnICcsIDIpWzFdID09PSAnMCc7XG5cbiAgICAgICAgaWYgKCFyZWplY3RlZCAmJiAhdHJhbnNjZWl2ZXIuaXNEYXRhY2hhbm5lbCkge1xuICAgICAgICAgIHZhciByZW1vdGVJY2VQYXJhbWV0ZXJzID0gU0RQVXRpbHMuZ2V0SWNlUGFyYW1ldGVycyhcbiAgICAgICAgICAgICAgbWVkaWFTZWN0aW9uLCBzZXNzaW9ucGFydCk7XG4gICAgICAgICAgdmFyIHJlbW90ZUR0bHNQYXJhbWV0ZXJzID0gU0RQVXRpbHMuZ2V0RHRsc1BhcmFtZXRlcnMoXG4gICAgICAgICAgICAgIG1lZGlhU2VjdGlvbiwgc2Vzc2lvbnBhcnQpO1xuICAgICAgICAgIGlmIChpc0ljZUxpdGUpIHtcbiAgICAgICAgICAgIHJlbW90ZUR0bHNQYXJhbWV0ZXJzLnJvbGUgPSAnc2VydmVyJztcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAoIXNlbGYudXNpbmdCdW5kbGUgfHwgc2RwTUxpbmVJbmRleCA9PT0gMCkge1xuICAgICAgICAgICAgaWNlVHJhbnNwb3J0LnN0YXJ0KGljZUdhdGhlcmVyLCByZW1vdGVJY2VQYXJhbWV0ZXJzLFxuICAgICAgICAgICAgICAgIGlzSWNlTGl0ZSA/ICdjb250cm9sbGluZycgOiAnY29udHJvbGxlZCcpO1xuICAgICAgICAgICAgZHRsc1RyYW5zcG9ydC5zdGFydChyZW1vdGVEdGxzUGFyYW1ldGVycyk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgLy8gQ2FsY3VsYXRlIGludGVyc2VjdGlvbiBvZiBjYXBhYmlsaXRpZXMuXG4gICAgICAgICAgdmFyIHBhcmFtcyA9IHNlbGYuX2dldENvbW1vbkNhcGFiaWxpdGllcyhsb2NhbENhcGFiaWxpdGllcyxcbiAgICAgICAgICAgICAgcmVtb3RlQ2FwYWJpbGl0aWVzKTtcblxuICAgICAgICAgIC8vIFN0YXJ0IHRoZSBSVENSdHBTZW5kZXIuIFRoZSBSVENSdHBSZWNlaXZlciBmb3IgdGhpc1xuICAgICAgICAgIC8vIHRyYW5zY2VpdmVyIGhhcyBhbHJlYWR5IGJlZW4gc3RhcnRlZCBpbiBzZXRSZW1vdGVEZXNjcmlwdGlvbi5cbiAgICAgICAgICBzZWxmLl90cmFuc2NlaXZlKHRyYW5zY2VpdmVyLFxuICAgICAgICAgICAgICBwYXJhbXMuY29kZWNzLmxlbmd0aCA+IDAsXG4gICAgICAgICAgICAgIGZhbHNlKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgdGhpcy5sb2NhbERlc2NyaXB0aW9uID0ge1xuICAgICAgdHlwZTogZGVzY3JpcHRpb24udHlwZSxcbiAgICAgIHNkcDogZGVzY3JpcHRpb24uc2RwXG4gICAgfTtcbiAgICBzd2l0Y2ggKGRlc2NyaXB0aW9uLnR5cGUpIHtcbiAgICAgIGNhc2UgJ29mZmVyJzpcbiAgICAgICAgdGhpcy5fdXBkYXRlU2lnbmFsaW5nU3RhdGUoJ2hhdmUtbG9jYWwtb2ZmZXInKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdhbnN3ZXInOlxuICAgICAgICB0aGlzLl91cGRhdGVTaWduYWxpbmdTdGF0ZSgnc3RhYmxlJyk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcigndW5zdXBwb3J0ZWQgdHlwZSBcIicgKyBkZXNjcmlwdGlvbi50eXBlICtcbiAgICAgICAgICAgICdcIicpO1xuICAgIH1cblxuICAgIC8vIElmIGEgc3VjY2VzcyBjYWxsYmFjayB3YXMgcHJvdmlkZWQsIGVtaXQgSUNFIGNhbmRpZGF0ZXMgYWZ0ZXIgaXRcbiAgICAvLyBoYXMgYmVlbiBleGVjdXRlZC4gT3RoZXJ3aXNlLCBlbWl0IGNhbGxiYWNrIGFmdGVyIHRoZSBQcm9taXNlIGlzXG4gICAgLy8gcmVzb2x2ZWQuXG4gICAgdmFyIGhhc0NhbGxiYWNrID0gYXJndW1lbnRzLmxlbmd0aCA+IDEgJiZcbiAgICAgIHR5cGVvZiBhcmd1bWVudHNbMV0gPT09ICdmdW5jdGlvbic7XG4gICAgaWYgKGhhc0NhbGxiYWNrKSB7XG4gICAgICB2YXIgY2IgPSBhcmd1bWVudHNbMV07XG4gICAgICB3aW5kb3cuc2V0VGltZW91dChmdW5jdGlvbigpIHtcbiAgICAgICAgY2IoKTtcbiAgICAgICAgaWYgKHNlbGYuaWNlR2F0aGVyaW5nU3RhdGUgPT09ICduZXcnKSB7XG4gICAgICAgICAgc2VsZi5pY2VHYXRoZXJpbmdTdGF0ZSA9ICdnYXRoZXJpbmcnO1xuICAgICAgICAgIHNlbGYuX2VtaXRHYXRoZXJpbmdTdGF0ZUNoYW5nZSgpO1xuICAgICAgICB9XG4gICAgICAgIHNlbGYuX2VtaXRCdWZmZXJlZENhbmRpZGF0ZXMoKTtcbiAgICAgIH0sIDApO1xuICAgIH1cbiAgICB2YXIgcCA9IFByb21pc2UucmVzb2x2ZSgpO1xuICAgIHAudGhlbihmdW5jdGlvbigpIHtcbiAgICAgIGlmICghaGFzQ2FsbGJhY2spIHtcbiAgICAgICAgaWYgKHNlbGYuaWNlR2F0aGVyaW5nU3RhdGUgPT09ICduZXcnKSB7XG4gICAgICAgICAgc2VsZi5pY2VHYXRoZXJpbmdTdGF0ZSA9ICdnYXRoZXJpbmcnO1xuICAgICAgICAgIHNlbGYuX2VtaXRHYXRoZXJpbmdTdGF0ZUNoYW5nZSgpO1xuICAgICAgICB9XG4gICAgICAgIC8vIFVzdWFsbHkgY2FuZGlkYXRlcyB3aWxsIGJlIGVtaXR0ZWQgZWFybGllci5cbiAgICAgICAgd2luZG93LnNldFRpbWVvdXQoc2VsZi5fZW1pdEJ1ZmZlcmVkQ2FuZGlkYXRlcy5iaW5kKHNlbGYpLCA1MDApO1xuICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiBwO1xuICB9O1xuXG4gIFJUQ1BlZXJDb25uZWN0aW9uLnByb3RvdHlwZS5zZXRSZW1vdGVEZXNjcmlwdGlvbiA9IGZ1bmN0aW9uKGRlc2NyaXB0aW9uKSB7XG4gICAgdmFyIHNlbGYgPSB0aGlzO1xuICAgIHZhciBzdHJlYW1zID0ge307XG4gICAgdmFyIHJlY2VpdmVyTGlzdCA9IFtdO1xuICAgIHZhciBzZWN0aW9ucyA9IFNEUFV0aWxzLnNwbGl0U2VjdGlvbnMoZGVzY3JpcHRpb24uc2RwKTtcbiAgICB2YXIgc2Vzc2lvbnBhcnQgPSBzZWN0aW9ucy5zaGlmdCgpO1xuICAgIHZhciBpc0ljZUxpdGUgPSBTRFBVdGlscy5tYXRjaFByZWZpeChzZXNzaW9ucGFydCxcbiAgICAgICAgJ2E9aWNlLWxpdGUnKS5sZW5ndGggPiAwO1xuICAgIHZhciB1c2luZ0J1bmRsZSA9IFNEUFV0aWxzLm1hdGNoUHJlZml4KHNlc3Npb25wYXJ0LFxuICAgICAgICAnYT1ncm91cDpCVU5ETEUgJykubGVuZ3RoID4gMDtcbiAgICB2YXIgaWNlT3B0aW9ucyA9IFNEUFV0aWxzLm1hdGNoUHJlZml4KHNlc3Npb25wYXJ0LFxuICAgICAgICAnYT1pY2Utb3B0aW9uczonKVswXTtcbiAgICBpZiAoaWNlT3B0aW9ucykge1xuICAgICAgdGhpcy5jYW5Ucmlja2xlSWNlQ2FuZGlkYXRlcyA9IGljZU9wdGlvbnMuc3Vic3RyKDE0KS5zcGxpdCgnICcpXG4gICAgICAgICAgLmluZGV4T2YoJ3RyaWNrbGUnKSA+PSAwO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmNhblRyaWNrbGVJY2VDYW5kaWRhdGVzID0gZmFsc2U7XG4gICAgfVxuXG4gICAgc2VjdGlvbnMuZm9yRWFjaChmdW5jdGlvbihtZWRpYVNlY3Rpb24sIHNkcE1MaW5lSW5kZXgpIHtcbiAgICAgIHZhciBsaW5lcyA9IFNEUFV0aWxzLnNwbGl0TGluZXMobWVkaWFTZWN0aW9uKTtcbiAgICAgIHZhciBtbGluZSA9IGxpbmVzWzBdLnN1YnN0cigyKS5zcGxpdCgnICcpO1xuICAgICAgdmFyIGtpbmQgPSBtbGluZVswXTtcbiAgICAgIHZhciByZWplY3RlZCA9IG1saW5lWzFdID09PSAnMCc7XG4gICAgICB2YXIgZGlyZWN0aW9uID0gU0RQVXRpbHMuZ2V0RGlyZWN0aW9uKG1lZGlhU2VjdGlvbiwgc2Vzc2lvbnBhcnQpO1xuICAgICAgdmFyIHJlbW90ZU1zaWQgPSBTRFBVdGlscy5wYXJzZU1zaWQobWVkaWFTZWN0aW9uKTtcblxuICAgICAgdmFyIG1pZCA9IFNEUFV0aWxzLm1hdGNoUHJlZml4KG1lZGlhU2VjdGlvbiwgJ2E9bWlkOicpO1xuICAgICAgaWYgKG1pZC5sZW5ndGgpIHtcbiAgICAgICAgbWlkID0gbWlkWzBdLnN1YnN0cig2KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG1pZCA9IFNEUFV0aWxzLmdlbmVyYXRlSWRlbnRpZmllcigpO1xuICAgICAgfVxuXG4gICAgICAvLyBSZWplY3QgZGF0YWNoYW5uZWxzIHdoaWNoIGFyZSBub3QgaW1wbGVtZW50ZWQgeWV0LlxuICAgICAgaWYgKGtpbmQgPT09ICdhcHBsaWNhdGlvbicgJiYgbWxpbmVbMl0gPT09ICdEVExTL1NDVFAnKSB7XG4gICAgICAgIHNlbGYudHJhbnNjZWl2ZXJzW3NkcE1MaW5lSW5kZXhdID0ge1xuICAgICAgICAgIG1pZDogbWlkLFxuICAgICAgICAgIGlzRGF0YWNoYW5uZWw6IHRydWVcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICB2YXIgdHJhbnNjZWl2ZXI7XG4gICAgICB2YXIgaWNlR2F0aGVyZXI7XG4gICAgICB2YXIgaWNlVHJhbnNwb3J0O1xuICAgICAgdmFyIGR0bHNUcmFuc3BvcnQ7XG4gICAgICB2YXIgcnRwU2VuZGVyO1xuICAgICAgdmFyIHJ0cFJlY2VpdmVyO1xuICAgICAgdmFyIHNlbmRFbmNvZGluZ1BhcmFtZXRlcnM7XG4gICAgICB2YXIgcmVjdkVuY29kaW5nUGFyYW1ldGVycztcbiAgICAgIHZhciBsb2NhbENhcGFiaWxpdGllcztcblxuICAgICAgdmFyIHRyYWNrO1xuICAgICAgLy8gRklYTUU6IGVuc3VyZSB0aGUgbWVkaWFTZWN0aW9uIGhhcyBydGNwLW11eCBzZXQuXG4gICAgICB2YXIgcmVtb3RlQ2FwYWJpbGl0aWVzID0gU0RQVXRpbHMucGFyc2VSdHBQYXJhbWV0ZXJzKG1lZGlhU2VjdGlvbik7XG4gICAgICB2YXIgcmVtb3RlSWNlUGFyYW1ldGVycztcbiAgICAgIHZhciByZW1vdGVEdGxzUGFyYW1ldGVycztcbiAgICAgIGlmICghcmVqZWN0ZWQpIHtcbiAgICAgICAgcmVtb3RlSWNlUGFyYW1ldGVycyA9IFNEUFV0aWxzLmdldEljZVBhcmFtZXRlcnMobWVkaWFTZWN0aW9uLFxuICAgICAgICAgICAgc2Vzc2lvbnBhcnQpO1xuICAgICAgICByZW1vdGVEdGxzUGFyYW1ldGVycyA9IFNEUFV0aWxzLmdldER0bHNQYXJhbWV0ZXJzKG1lZGlhU2VjdGlvbixcbiAgICAgICAgICAgIHNlc3Npb25wYXJ0KTtcbiAgICAgICAgcmVtb3RlRHRsc1BhcmFtZXRlcnMucm9sZSA9ICdjbGllbnQnO1xuICAgICAgfVxuICAgICAgcmVjdkVuY29kaW5nUGFyYW1ldGVycyA9XG4gICAgICAgICAgU0RQVXRpbHMucGFyc2VSdHBFbmNvZGluZ1BhcmFtZXRlcnMobWVkaWFTZWN0aW9uKTtcblxuICAgICAgdmFyIHJ0Y3BQYXJhbWV0ZXJzID0gU0RQVXRpbHMucGFyc2VSdGNwUGFyYW1ldGVycyhtZWRpYVNlY3Rpb24pO1xuXG4gICAgICB2YXIgaXNDb21wbGV0ZSA9IFNEUFV0aWxzLm1hdGNoUHJlZml4KG1lZGlhU2VjdGlvbixcbiAgICAgICAgICAnYT1lbmQtb2YtY2FuZGlkYXRlcycsIHNlc3Npb25wYXJ0KS5sZW5ndGggPiAwO1xuICAgICAgdmFyIGNhbmRzID0gU0RQVXRpbHMubWF0Y2hQcmVmaXgobWVkaWFTZWN0aW9uLCAnYT1jYW5kaWRhdGU6JylcbiAgICAgICAgICAubWFwKGZ1bmN0aW9uKGNhbmQpIHtcbiAgICAgICAgICAgIHJldHVybiBTRFBVdGlscy5wYXJzZUNhbmRpZGF0ZShjYW5kKTtcbiAgICAgICAgICB9KVxuICAgICAgICAgIC5maWx0ZXIoZnVuY3Rpb24oY2FuZCkge1xuICAgICAgICAgICAgcmV0dXJuIGNhbmQuY29tcG9uZW50ID09PSAnMSc7XG4gICAgICAgICAgfSk7XG4gICAgICBpZiAoZGVzY3JpcHRpb24udHlwZSA9PT0gJ29mZmVyJyAmJiAhcmVqZWN0ZWQpIHtcbiAgICAgICAgdmFyIHRyYW5zcG9ydHMgPSB1c2luZ0J1bmRsZSAmJiBzZHBNTGluZUluZGV4ID4gMCA/IHtcbiAgICAgICAgICBpY2VHYXRoZXJlcjogc2VsZi50cmFuc2NlaXZlcnNbMF0uaWNlR2F0aGVyZXIsXG4gICAgICAgICAgaWNlVHJhbnNwb3J0OiBzZWxmLnRyYW5zY2VpdmVyc1swXS5pY2VUcmFuc3BvcnQsXG4gICAgICAgICAgZHRsc1RyYW5zcG9ydDogc2VsZi50cmFuc2NlaXZlcnNbMF0uZHRsc1RyYW5zcG9ydFxuICAgICAgICB9IDogc2VsZi5fY3JlYXRlSWNlQW5kRHRsc1RyYW5zcG9ydHMobWlkLCBzZHBNTGluZUluZGV4KTtcblxuICAgICAgICBpZiAoaXNDb21wbGV0ZSAmJiAoIXVzaW5nQnVuZGxlIHx8IHNkcE1MaW5lSW5kZXggPT09IDApKSB7XG4gICAgICAgICAgdHJhbnNwb3J0cy5pY2VUcmFuc3BvcnQuc2V0UmVtb3RlQ2FuZGlkYXRlcyhjYW5kcyk7XG4gICAgICAgIH1cblxuICAgICAgICBsb2NhbENhcGFiaWxpdGllcyA9IFJUQ1J0cFJlY2VpdmVyLmdldENhcGFiaWxpdGllcyhraW5kKTtcblxuICAgICAgICAvLyBmaWx0ZXIgUlRYIHVudGlsIGFkZGl0aW9uYWwgc3R1ZmYgbmVlZGVkIGZvciBSVFggaXMgaW1wbGVtZW50ZWRcbiAgICAgICAgLy8gaW4gYWRhcHRlci5qc1xuICAgICAgICBpZiAoZWRnZVZlcnNpb24gPCAxNTAxOSkge1xuICAgICAgICAgIGxvY2FsQ2FwYWJpbGl0aWVzLmNvZGVjcyA9IGxvY2FsQ2FwYWJpbGl0aWVzLmNvZGVjcy5maWx0ZXIoXG4gICAgICAgICAgICAgIGZ1bmN0aW9uKGNvZGVjKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNvZGVjLm5hbWUgIT09ICdydHgnO1xuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIHNlbmRFbmNvZGluZ1BhcmFtZXRlcnMgPSBbe1xuICAgICAgICAgIHNzcmM6ICgyICogc2RwTUxpbmVJbmRleCArIDIpICogMTAwMVxuICAgICAgICB9XTtcblxuICAgICAgICBpZiAoZGlyZWN0aW9uID09PSAnc2VuZHJlY3YnIHx8IGRpcmVjdGlvbiA9PT0gJ3NlbmRvbmx5Jykge1xuICAgICAgICAgIHJ0cFJlY2VpdmVyID0gbmV3IFJUQ1J0cFJlY2VpdmVyKHRyYW5zcG9ydHMuZHRsc1RyYW5zcG9ydCxcbiAgICAgICAgICAgICAga2luZCk7XG5cbiAgICAgICAgICB0cmFjayA9IHJ0cFJlY2VpdmVyLnRyYWNrO1xuICAgICAgICAgIC8vIEZJWE1FOiBkb2VzIG5vdCB3b3JrIHdpdGggUGxhbiBCLlxuICAgICAgICAgIGlmIChyZW1vdGVNc2lkKSB7XG4gICAgICAgICAgICBpZiAoIXN0cmVhbXNbcmVtb3RlTXNpZC5zdHJlYW1dKSB7XG4gICAgICAgICAgICAgIHN0cmVhbXNbcmVtb3RlTXNpZC5zdHJlYW1dID0gbmV3IE1lZGlhU3RyZWFtKCk7XG4gICAgICAgICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShzdHJlYW1zW3JlbW90ZU1zaWQuc3RyZWFtXSwgJ2lkJywge1xuICAgICAgICAgICAgICAgIGdldDogZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICAgICAgICByZXR1cm4gcmVtb3RlTXNpZC5zdHJlYW07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0cmFjaywgJ2lkJywge1xuICAgICAgICAgICAgICBnZXQ6IGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiByZW1vdGVNc2lkLnRyYWNrO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHN0cmVhbXNbcmVtb3RlTXNpZC5zdHJlYW1dLmFkZFRyYWNrKHRyYWNrKTtcbiAgICAgICAgICAgIHJlY2VpdmVyTGlzdC5wdXNoKFt0cmFjaywgcnRwUmVjZWl2ZXIsXG4gICAgICAgICAgICAgICAgc3RyZWFtc1tyZW1vdGVNc2lkLnN0cmVhbV1dKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaWYgKCFzdHJlYW1zLmRlZmF1bHQpIHtcbiAgICAgICAgICAgICAgc3RyZWFtcy5kZWZhdWx0ID0gbmV3IE1lZGlhU3RyZWFtKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBzdHJlYW1zLmRlZmF1bHQuYWRkVHJhY2sodHJhY2spO1xuICAgICAgICAgICAgcmVjZWl2ZXJMaXN0LnB1c2goW3RyYWNrLCBydHBSZWNlaXZlciwgc3RyZWFtcy5kZWZhdWx0XSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gRklYTUU6IGxvb2sgYXQgZGlyZWN0aW9uLlxuICAgICAgICBpZiAoc2VsZi5sb2NhbFN0cmVhbXMubGVuZ3RoID4gMCAmJlxuICAgICAgICAgICAgc2VsZi5sb2NhbFN0cmVhbXNbMF0uZ2V0VHJhY2tzKCkubGVuZ3RoID49IHNkcE1MaW5lSW5kZXgpIHtcbiAgICAgICAgICB2YXIgbG9jYWxUcmFjaztcbiAgICAgICAgICBpZiAoa2luZCA9PT0gJ2F1ZGlvJykge1xuICAgICAgICAgICAgbG9jYWxUcmFjayA9IHNlbGYubG9jYWxTdHJlYW1zWzBdLmdldEF1ZGlvVHJhY2tzKClbMF07XG4gICAgICAgICAgfSBlbHNlIGlmIChraW5kID09PSAndmlkZW8nKSB7XG4gICAgICAgICAgICBsb2NhbFRyYWNrID0gc2VsZi5sb2NhbFN0cmVhbXNbMF0uZ2V0VmlkZW9UcmFja3MoKVswXTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKGxvY2FsVHJhY2spIHtcbiAgICAgICAgICAgIC8vIGFkZCBSVFhcbiAgICAgICAgICAgIGlmIChlZGdlVmVyc2lvbiA+PSAxNTAxOSAmJiBraW5kID09PSAndmlkZW8nKSB7XG4gICAgICAgICAgICAgIHNlbmRFbmNvZGluZ1BhcmFtZXRlcnNbMF0ucnR4ID0ge1xuICAgICAgICAgICAgICAgIHNzcmM6ICgyICogc2RwTUxpbmVJbmRleCArIDIpICogMTAwMSArIDFcbiAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJ0cFNlbmRlciA9IG5ldyBSVENSdHBTZW5kZXIobG9jYWxUcmFjayxcbiAgICAgICAgICAgICAgICB0cmFuc3BvcnRzLmR0bHNUcmFuc3BvcnQpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHNlbGYudHJhbnNjZWl2ZXJzW3NkcE1MaW5lSW5kZXhdID0ge1xuICAgICAgICAgIGljZUdhdGhlcmVyOiB0cmFuc3BvcnRzLmljZUdhdGhlcmVyLFxuICAgICAgICAgIGljZVRyYW5zcG9ydDogdHJhbnNwb3J0cy5pY2VUcmFuc3BvcnQsXG4gICAgICAgICAgZHRsc1RyYW5zcG9ydDogdHJhbnNwb3J0cy5kdGxzVHJhbnNwb3J0LFxuICAgICAgICAgIGxvY2FsQ2FwYWJpbGl0aWVzOiBsb2NhbENhcGFiaWxpdGllcyxcbiAgICAgICAgICByZW1vdGVDYXBhYmlsaXRpZXM6IHJlbW90ZUNhcGFiaWxpdGllcyxcbiAgICAgICAgICBydHBTZW5kZXI6IHJ0cFNlbmRlcixcbiAgICAgICAgICBydHBSZWNlaXZlcjogcnRwUmVjZWl2ZXIsXG4gICAgICAgICAga2luZDoga2luZCxcbiAgICAgICAgICBtaWQ6IG1pZCxcbiAgICAgICAgICBydGNwUGFyYW1ldGVyczogcnRjcFBhcmFtZXRlcnMsXG4gICAgICAgICAgc2VuZEVuY29kaW5nUGFyYW1ldGVyczogc2VuZEVuY29kaW5nUGFyYW1ldGVycyxcbiAgICAgICAgICByZWN2RW5jb2RpbmdQYXJhbWV0ZXJzOiByZWN2RW5jb2RpbmdQYXJhbWV0ZXJzXG4gICAgICAgIH07XG4gICAgICAgIC8vIFN0YXJ0IHRoZSBSVENSdHBSZWNlaXZlciBub3cuIFRoZSBSVFBTZW5kZXIgaXMgc3RhcnRlZCBpblxuICAgICAgICAvLyBzZXRMb2NhbERlc2NyaXB0aW9uLlxuICAgICAgICBzZWxmLl90cmFuc2NlaXZlKHNlbGYudHJhbnNjZWl2ZXJzW3NkcE1MaW5lSW5kZXhdLFxuICAgICAgICAgICAgZmFsc2UsXG4gICAgICAgICAgICBkaXJlY3Rpb24gPT09ICdzZW5kcmVjdicgfHwgZGlyZWN0aW9uID09PSAnc2VuZG9ubHknKTtcbiAgICAgIH0gZWxzZSBpZiAoZGVzY3JpcHRpb24udHlwZSA9PT0gJ2Fuc3dlcicgJiYgIXJlamVjdGVkKSB7XG4gICAgICAgIGlmICh1c2luZ0J1bmRsZSAmJiBzZHBNTGluZUluZGV4ID4gMCkge1xuICAgICAgICAgIHNlbGYuX2Rpc3Bvc2VJY2VBbmREdGxzVHJhbnNwb3J0cyhzZHBNTGluZUluZGV4KTtcbiAgICAgICAgICBzZWxmLnRyYW5zY2VpdmVyc1tzZHBNTGluZUluZGV4XS5pY2VHYXRoZXJlciA9XG4gICAgICAgICAgICAgIHNlbGYudHJhbnNjZWl2ZXJzWzBdLmljZUdhdGhlcmVyO1xuICAgICAgICAgIHNlbGYudHJhbnNjZWl2ZXJzW3NkcE1MaW5lSW5kZXhdLmljZVRyYW5zcG9ydCA9XG4gICAgICAgICAgICAgIHNlbGYudHJhbnNjZWl2ZXJzWzBdLmljZVRyYW5zcG9ydDtcbiAgICAgICAgICBzZWxmLnRyYW5zY2VpdmVyc1tzZHBNTGluZUluZGV4XS5kdGxzVHJhbnNwb3J0ID1cbiAgICAgICAgICAgICAgc2VsZi50cmFuc2NlaXZlcnNbMF0uZHRsc1RyYW5zcG9ydDtcbiAgICAgICAgICBpZiAoc2VsZi50cmFuc2NlaXZlcnNbc2RwTUxpbmVJbmRleF0ucnRwU2VuZGVyKSB7XG4gICAgICAgICAgICBzZWxmLnRyYW5zY2VpdmVyc1tzZHBNTGluZUluZGV4XS5ydHBTZW5kZXIuc2V0VHJhbnNwb3J0KFxuICAgICAgICAgICAgICAgIHNlbGYudHJhbnNjZWl2ZXJzWzBdLmR0bHNUcmFuc3BvcnQpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoc2VsZi50cmFuc2NlaXZlcnNbc2RwTUxpbmVJbmRleF0ucnRwUmVjZWl2ZXIpIHtcbiAgICAgICAgICAgIHNlbGYudHJhbnNjZWl2ZXJzW3NkcE1MaW5lSW5kZXhdLnJ0cFJlY2VpdmVyLnNldFRyYW5zcG9ydChcbiAgICAgICAgICAgICAgICBzZWxmLnRyYW5zY2VpdmVyc1swXS5kdGxzVHJhbnNwb3J0KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdHJhbnNjZWl2ZXIgPSBzZWxmLnRyYW5zY2VpdmVyc1tzZHBNTGluZUluZGV4XTtcbiAgICAgICAgaWNlR2F0aGVyZXIgPSB0cmFuc2NlaXZlci5pY2VHYXRoZXJlcjtcbiAgICAgICAgaWNlVHJhbnNwb3J0ID0gdHJhbnNjZWl2ZXIuaWNlVHJhbnNwb3J0O1xuICAgICAgICBkdGxzVHJhbnNwb3J0ID0gdHJhbnNjZWl2ZXIuZHRsc1RyYW5zcG9ydDtcbiAgICAgICAgcnRwU2VuZGVyID0gdHJhbnNjZWl2ZXIucnRwU2VuZGVyO1xuICAgICAgICBydHBSZWNlaXZlciA9IHRyYW5zY2VpdmVyLnJ0cFJlY2VpdmVyO1xuICAgICAgICBzZW5kRW5jb2RpbmdQYXJhbWV0ZXJzID0gdHJhbnNjZWl2ZXIuc2VuZEVuY29kaW5nUGFyYW1ldGVycztcbiAgICAgICAgbG9jYWxDYXBhYmlsaXRpZXMgPSB0cmFuc2NlaXZlci5sb2NhbENhcGFiaWxpdGllcztcblxuICAgICAgICBzZWxmLnRyYW5zY2VpdmVyc1tzZHBNTGluZUluZGV4XS5yZWN2RW5jb2RpbmdQYXJhbWV0ZXJzID1cbiAgICAgICAgICAgIHJlY3ZFbmNvZGluZ1BhcmFtZXRlcnM7XG4gICAgICAgIHNlbGYudHJhbnNjZWl2ZXJzW3NkcE1MaW5lSW5kZXhdLnJlbW90ZUNhcGFiaWxpdGllcyA9XG4gICAgICAgICAgICByZW1vdGVDYXBhYmlsaXRpZXM7XG4gICAgICAgIHNlbGYudHJhbnNjZWl2ZXJzW3NkcE1MaW5lSW5kZXhdLnJ0Y3BQYXJhbWV0ZXJzID0gcnRjcFBhcmFtZXRlcnM7XG5cbiAgICAgICAgaWYgKChpc0ljZUxpdGUgfHwgaXNDb21wbGV0ZSkgJiYgY2FuZHMubGVuZ3RoKSB7XG4gICAgICAgICAgaWNlVHJhbnNwb3J0LnNldFJlbW90ZUNhbmRpZGF0ZXMoY2FuZHMpO1xuICAgICAgICB9XG4gICAgICAgIGlmICghdXNpbmdCdW5kbGUgfHwgc2RwTUxpbmVJbmRleCA9PT0gMCkge1xuICAgICAgICAgIGljZVRyYW5zcG9ydC5zdGFydChpY2VHYXRoZXJlciwgcmVtb3RlSWNlUGFyYW1ldGVycyxcbiAgICAgICAgICAgICAgJ2NvbnRyb2xsaW5nJyk7XG4gICAgICAgICAgZHRsc1RyYW5zcG9ydC5zdGFydChyZW1vdGVEdGxzUGFyYW1ldGVycyk7XG4gICAgICAgIH1cblxuICAgICAgICBzZWxmLl90cmFuc2NlaXZlKHRyYW5zY2VpdmVyLFxuICAgICAgICAgICAgZGlyZWN0aW9uID09PSAnc2VuZHJlY3YnIHx8IGRpcmVjdGlvbiA9PT0gJ3JlY3Zvbmx5JyxcbiAgICAgICAgICAgIGRpcmVjdGlvbiA9PT0gJ3NlbmRyZWN2JyB8fCBkaXJlY3Rpb24gPT09ICdzZW5kb25seScpO1xuXG4gICAgICAgIGlmIChydHBSZWNlaXZlciAmJlxuICAgICAgICAgICAgKGRpcmVjdGlvbiA9PT0gJ3NlbmRyZWN2JyB8fCBkaXJlY3Rpb24gPT09ICdzZW5kb25seScpKSB7XG4gICAgICAgICAgdHJhY2sgPSBydHBSZWNlaXZlci50cmFjaztcbiAgICAgICAgICByZWNlaXZlckxpc3QucHVzaChbdHJhY2ssIHJ0cFJlY2VpdmVyXSk7XG4gICAgICAgICAgaWYgKHJlbW90ZU1zaWQpIHtcbiAgICAgICAgICAgIGlmICghc3RyZWFtc1tyZW1vdGVNc2lkLnN0cmVhbV0pIHtcbiAgICAgICAgICAgICAgc3RyZWFtc1tyZW1vdGVNc2lkLnN0cmVhbV0gPSBuZXcgTWVkaWFTdHJlYW0oKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHN0cmVhbXNbcmVtb3RlTXNpZC5zdHJlYW1dLmFkZFRyYWNrKHRyYWNrKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaWYgKCFzdHJlYW1zLmRlZmF1bHQpIHtcbiAgICAgICAgICAgICAgc3RyZWFtcy5kZWZhdWx0ID0gbmV3IE1lZGlhU3RyZWFtKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBzdHJlYW1zLmRlZmF1bHQuYWRkVHJhY2sodHJhY2spO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyBGSVhNRTogYWN0dWFsbHkgdGhlIHJlY2VpdmVyIHNob3VsZCBiZSBjcmVhdGVkIGxhdGVyLlxuICAgICAgICAgIGRlbGV0ZSB0cmFuc2NlaXZlci5ydHBSZWNlaXZlcjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pO1xuICAgIHRoaXMudXNpbmdCdW5kbGUgPSB1c2luZ0J1bmRsZTtcblxuICAgIHRoaXMucmVtb3RlRGVzY3JpcHRpb24gPSB7XG4gICAgICB0eXBlOiBkZXNjcmlwdGlvbi50eXBlLFxuICAgICAgc2RwOiBkZXNjcmlwdGlvbi5zZHBcbiAgICB9O1xuICAgIHN3aXRjaCAoZGVzY3JpcHRpb24udHlwZSkge1xuICAgICAgY2FzZSAnb2ZmZXInOlxuICAgICAgICB0aGlzLl91cGRhdGVTaWduYWxpbmdTdGF0ZSgnaGF2ZS1yZW1vdGUtb2ZmZXInKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdhbnN3ZXInOlxuICAgICAgICB0aGlzLl91cGRhdGVTaWduYWxpbmdTdGF0ZSgnc3RhYmxlJyk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcigndW5zdXBwb3J0ZWQgdHlwZSBcIicgKyBkZXNjcmlwdGlvbi50eXBlICtcbiAgICAgICAgICAgICdcIicpO1xuICAgIH1cbiAgICBPYmplY3Qua2V5cyhzdHJlYW1zKS5mb3JFYWNoKGZ1bmN0aW9uKHNpZCkge1xuICAgICAgdmFyIHN0cmVhbSA9IHN0cmVhbXNbc2lkXTtcbiAgICAgIGlmIChzdHJlYW0uZ2V0VHJhY2tzKCkubGVuZ3RoKSB7XG4gICAgICAgIHNlbGYucmVtb3RlU3RyZWFtcy5wdXNoKHN0cmVhbSk7XG4gICAgICAgIHZhciBldmVudCA9IG5ldyBFdmVudCgnYWRkc3RyZWFtJyk7XG4gICAgICAgIGV2ZW50LnN0cmVhbSA9IHN0cmVhbTtcbiAgICAgICAgc2VsZi5kaXNwYXRjaEV2ZW50KGV2ZW50KTtcbiAgICAgICAgaWYgKHNlbGYub25hZGRzdHJlYW0gIT09IG51bGwpIHtcbiAgICAgICAgICB3aW5kb3cuc2V0VGltZW91dChmdW5jdGlvbigpIHtcbiAgICAgICAgICAgIHNlbGYub25hZGRzdHJlYW0oZXZlbnQpO1xuICAgICAgICAgIH0sIDApO1xuICAgICAgICB9XG5cbiAgICAgICAgcmVjZWl2ZXJMaXN0LmZvckVhY2goZnVuY3Rpb24oaXRlbSkge1xuICAgICAgICAgIHZhciB0cmFjayA9IGl0ZW1bMF07XG4gICAgICAgICAgdmFyIHJlY2VpdmVyID0gaXRlbVsxXTtcbiAgICAgICAgICBpZiAoc3RyZWFtLmlkICE9PSBpdGVtWzJdLmlkKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuICAgICAgICAgIHZhciB0cmFja0V2ZW50ID0gbmV3IEV2ZW50KCd0cmFjaycpO1xuICAgICAgICAgIHRyYWNrRXZlbnQudHJhY2sgPSB0cmFjaztcbiAgICAgICAgICB0cmFja0V2ZW50LnJlY2VpdmVyID0gcmVjZWl2ZXI7XG4gICAgICAgICAgdHJhY2tFdmVudC5zdHJlYW1zID0gW3N0cmVhbV07XG4gICAgICAgICAgc2VsZi5kaXNwYXRjaEV2ZW50KHRyYWNrRXZlbnQpO1xuICAgICAgICAgIGlmIChzZWxmLm9udHJhY2sgIT09IG51bGwpIHtcbiAgICAgICAgICAgIHdpbmRvdy5zZXRUaW1lb3V0KGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgICBzZWxmLm9udHJhY2sodHJhY2tFdmVudCk7XG4gICAgICAgICAgICB9LCAwKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0pO1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID4gMSAmJiB0eXBlb2YgYXJndW1lbnRzWzFdID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICB3aW5kb3cuc2V0VGltZW91dChhcmd1bWVudHNbMV0sIDApO1xuICAgIH1cbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gIH07XG5cbiAgUlRDUGVlckNvbm5lY3Rpb24ucHJvdG90eXBlLmNsb3NlID0gZnVuY3Rpb24oKSB7XG4gICAgdGhpcy50cmFuc2NlaXZlcnMuZm9yRWFjaChmdW5jdGlvbih0cmFuc2NlaXZlcikge1xuICAgICAgLyogbm90IHlldFxuICAgICAgaWYgKHRyYW5zY2VpdmVyLmljZUdhdGhlcmVyKSB7XG4gICAgICAgIHRyYW5zY2VpdmVyLmljZUdhdGhlcmVyLmNsb3NlKCk7XG4gICAgICB9XG4gICAgICAqL1xuICAgICAgaWYgKHRyYW5zY2VpdmVyLmljZVRyYW5zcG9ydCkge1xuICAgICAgICB0cmFuc2NlaXZlci5pY2VUcmFuc3BvcnQuc3RvcCgpO1xuICAgICAgfVxuICAgICAgaWYgKHRyYW5zY2VpdmVyLmR0bHNUcmFuc3BvcnQpIHtcbiAgICAgICAgdHJhbnNjZWl2ZXIuZHRsc1RyYW5zcG9ydC5zdG9wKCk7XG4gICAgICB9XG4gICAgICBpZiAodHJhbnNjZWl2ZXIucnRwU2VuZGVyKSB7XG4gICAgICAgIHRyYW5zY2VpdmVyLnJ0cFNlbmRlci5zdG9wKCk7XG4gICAgICB9XG4gICAgICBpZiAodHJhbnNjZWl2ZXIucnRwUmVjZWl2ZXIpIHtcbiAgICAgICAgdHJhbnNjZWl2ZXIucnRwUmVjZWl2ZXIuc3RvcCgpO1xuICAgICAgfVxuICAgIH0pO1xuICAgIC8vIEZJWE1FOiBjbGVhbiB1cCB0cmFja3MsIGxvY2FsIHN0cmVhbXMsIHJlbW90ZSBzdHJlYW1zLCBldGNcbiAgICB0aGlzLl91cGRhdGVTaWduYWxpbmdTdGF0ZSgnY2xvc2VkJyk7XG4gIH07XG5cbiAgLy8gVXBkYXRlIHRoZSBzaWduYWxpbmcgc3RhdGUuXG4gIFJUQ1BlZXJDb25uZWN0aW9uLnByb3RvdHlwZS5fdXBkYXRlU2lnbmFsaW5nU3RhdGUgPSBmdW5jdGlvbihuZXdTdGF0ZSkge1xuICAgIHRoaXMuc2lnbmFsaW5nU3RhdGUgPSBuZXdTdGF0ZTtcbiAgICB2YXIgZXZlbnQgPSBuZXcgRXZlbnQoJ3NpZ25hbGluZ3N0YXRlY2hhbmdlJyk7XG4gICAgdGhpcy5kaXNwYXRjaEV2ZW50KGV2ZW50KTtcbiAgICBpZiAodGhpcy5vbnNpZ25hbGluZ3N0YXRlY2hhbmdlICE9PSBudWxsKSB7XG4gICAgICB0aGlzLm9uc2lnbmFsaW5nc3RhdGVjaGFuZ2UoZXZlbnQpO1xuICAgIH1cbiAgfTtcblxuICAvLyBEZXRlcm1pbmUgd2hldGhlciB0byBmaXJlIHRoZSBuZWdvdGlhdGlvbm5lZWRlZCBldmVudC5cbiAgUlRDUGVlckNvbm5lY3Rpb24ucHJvdG90eXBlLl9tYXliZUZpcmVOZWdvdGlhdGlvbk5lZWRlZCA9IGZ1bmN0aW9uKCkge1xuICAgIC8vIEZpcmUgYXdheSAoZm9yIG5vdykuXG4gICAgdmFyIGV2ZW50ID0gbmV3IEV2ZW50KCduZWdvdGlhdGlvbm5lZWRlZCcpO1xuICAgIHRoaXMuZGlzcGF0Y2hFdmVudChldmVudCk7XG4gICAgaWYgKHRoaXMub25uZWdvdGlhdGlvbm5lZWRlZCAhPT0gbnVsbCkge1xuICAgICAgdGhpcy5vbm5lZ290aWF0aW9ubmVlZGVkKGV2ZW50KTtcbiAgICB9XG4gIH07XG5cbiAgLy8gVXBkYXRlIHRoZSBjb25uZWN0aW9uIHN0YXRlLlxuICBSVENQZWVyQ29ubmVjdGlvbi5wcm90b3R5cGUuX3VwZGF0ZUNvbm5lY3Rpb25TdGF0ZSA9IGZ1bmN0aW9uKCkge1xuICAgIHZhciBzZWxmID0gdGhpcztcbiAgICB2YXIgbmV3U3RhdGU7XG4gICAgdmFyIHN0YXRlcyA9IHtcbiAgICAgICduZXcnOiAwLFxuICAgICAgY2xvc2VkOiAwLFxuICAgICAgY29ubmVjdGluZzogMCxcbiAgICAgIGNoZWNraW5nOiAwLFxuICAgICAgY29ubmVjdGVkOiAwLFxuICAgICAgY29tcGxldGVkOiAwLFxuICAgICAgZmFpbGVkOiAwXG4gICAgfTtcbiAgICB0aGlzLnRyYW5zY2VpdmVycy5mb3JFYWNoKGZ1bmN0aW9uKHRyYW5zY2VpdmVyKSB7XG4gICAgICBzdGF0ZXNbdHJhbnNjZWl2ZXIuaWNlVHJhbnNwb3J0LnN0YXRlXSsrO1xuICAgICAgc3RhdGVzW3RyYW5zY2VpdmVyLmR0bHNUcmFuc3BvcnQuc3RhdGVdKys7XG4gICAgfSk7XG4gICAgLy8gSUNFVHJhbnNwb3J0LmNvbXBsZXRlZCBhbmQgY29ubmVjdGVkIGFyZSB0aGUgc2FtZSBmb3IgdGhpcyBwdXJwb3NlLlxuICAgIHN0YXRlcy5jb25uZWN0ZWQgKz0gc3RhdGVzLmNvbXBsZXRlZDtcblxuICAgIG5ld1N0YXRlID0gJ25ldyc7XG4gICAgaWYgKHN0YXRlcy5mYWlsZWQgPiAwKSB7XG4gICAgICBuZXdTdGF0ZSA9ICdmYWlsZWQnO1xuICAgIH0gZWxzZSBpZiAoc3RhdGVzLmNvbm5lY3RpbmcgPiAwIHx8IHN0YXRlcy5jaGVja2luZyA+IDApIHtcbiAgICAgIG5ld1N0YXRlID0gJ2Nvbm5lY3RpbmcnO1xuICAgIH0gZWxzZSBpZiAoc3RhdGVzLmRpc2Nvbm5lY3RlZCA+IDApIHtcbiAgICAgIG5ld1N0YXRlID0gJ2Rpc2Nvbm5lY3RlZCc7XG4gICAgfSBlbHNlIGlmIChzdGF0ZXMubmV3ID4gMCkge1xuICAgICAgbmV3U3RhdGUgPSAnbmV3JztcbiAgICB9IGVsc2UgaWYgKHN0YXRlcy5jb25uZWN0ZWQgPiAwIHx8IHN0YXRlcy5jb21wbGV0ZWQgPiAwKSB7XG4gICAgICBuZXdTdGF0ZSA9ICdjb25uZWN0ZWQnO1xuICAgIH1cblxuICAgIGlmIChuZXdTdGF0ZSAhPT0gc2VsZi5pY2VDb25uZWN0aW9uU3RhdGUpIHtcbiAgICAgIHNlbGYuaWNlQ29ubmVjdGlvblN0YXRlID0gbmV3U3RhdGU7XG4gICAgICB2YXIgZXZlbnQgPSBuZXcgRXZlbnQoJ2ljZWNvbm5lY3Rpb25zdGF0ZWNoYW5nZScpO1xuICAgICAgdGhpcy5kaXNwYXRjaEV2ZW50KGV2ZW50KTtcbiAgICAgIGlmICh0aGlzLm9uaWNlY29ubmVjdGlvbnN0YXRlY2hhbmdlICE9PSBudWxsKSB7XG4gICAgICAgIHRoaXMub25pY2Vjb25uZWN0aW9uc3RhdGVjaGFuZ2UoZXZlbnQpO1xuICAgICAgfVxuICAgIH1cbiAgfTtcblxuICBSVENQZWVyQ29ubmVjdGlvbi5wcm90b3R5cGUuY3JlYXRlT2ZmZXIgPSBmdW5jdGlvbigpIHtcbiAgICB2YXIgc2VsZiA9IHRoaXM7XG4gICAgaWYgKHRoaXMuX3BlbmRpbmdPZmZlcikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdjcmVhdGVPZmZlciBjYWxsZWQgd2hpbGUgdGhlcmUgaXMgYSBwZW5kaW5nIG9mZmVyLicpO1xuICAgIH1cbiAgICB2YXIgb2ZmZXJPcHRpb25zO1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAxICYmIHR5cGVvZiBhcmd1bWVudHNbMF0gIT09ICdmdW5jdGlvbicpIHtcbiAgICAgIG9mZmVyT3B0aW9ucyA9IGFyZ3VtZW50c1swXTtcbiAgICB9IGVsc2UgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDMpIHtcbiAgICAgIG9mZmVyT3B0aW9ucyA9IGFyZ3VtZW50c1syXTtcbiAgICB9XG5cbiAgICB2YXIgdHJhY2tzID0gW107XG4gICAgdmFyIG51bUF1ZGlvVHJhY2tzID0gMDtcbiAgICB2YXIgbnVtVmlkZW9UcmFja3MgPSAwO1xuICAgIC8vIERlZmF1bHQgdG8gc2VuZHJlY3YuXG4gICAgaWYgKHRoaXMubG9jYWxTdHJlYW1zLmxlbmd0aCkge1xuICAgICAgbnVtQXVkaW9UcmFja3MgPSB0aGlzLmxvY2FsU3RyZWFtcy5yZWR1Y2UoZnVuY3Rpb24obnVtVHJhY2tzLCBzdHJlYW0pIHtcbiAgICAgICAgcmV0dXJuIG51bVRyYWNrcyArIHN0cmVhbS5nZXRBdWRpb1RyYWNrcygpLmxlbmd0aDtcbiAgICAgIH0sIDApO1xuICAgICAgbnVtVmlkZW9UcmFja3MgPSB0aGlzLmxvY2FsU3RyZWFtcy5yZWR1Y2UoZnVuY3Rpb24obnVtVHJhY2tzLCBzdHJlYW0pIHtcbiAgICAgICAgcmV0dXJuIG51bVRyYWNrcyArIHN0cmVhbS5nZXRWaWRlb1RyYWNrcygpLmxlbmd0aDtcbiAgICAgIH0sIDApO1xuICAgIH1cbiAgICAvLyBEZXRlcm1pbmUgbnVtYmVyIG9mIGF1ZGlvIGFuZCB2aWRlbyB0cmFja3Mgd2UgbmVlZCB0byBzZW5kL3JlY3YuXG4gICAgaWYgKG9mZmVyT3B0aW9ucykge1xuICAgICAgLy8gUmVqZWN0IENocm9tZSBsZWdhY3kgY29uc3RyYWludHMuXG4gICAgICBpZiAob2ZmZXJPcHRpb25zLm1hbmRhdG9yeSB8fCBvZmZlck9wdGlvbnMub3B0aW9uYWwpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcbiAgICAgICAgICAgICdMZWdhY3kgbWFuZGF0b3J5L29wdGlvbmFsIGNvbnN0cmFpbnRzIG5vdCBzdXBwb3J0ZWQuJyk7XG4gICAgICB9XG4gICAgICBpZiAob2ZmZXJPcHRpb25zLm9mZmVyVG9SZWNlaXZlQXVkaW8gIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBudW1BdWRpb1RyYWNrcyA9IG9mZmVyT3B0aW9ucy5vZmZlclRvUmVjZWl2ZUF1ZGlvO1xuICAgICAgfVxuICAgICAgaWYgKG9mZmVyT3B0aW9ucy5vZmZlclRvUmVjZWl2ZVZpZGVvICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgbnVtVmlkZW9UcmFja3MgPSBvZmZlck9wdGlvbnMub2ZmZXJUb1JlY2VpdmVWaWRlbztcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBQdXNoIGxvY2FsIHN0cmVhbXMuXG4gICAgdGhpcy5sb2NhbFN0cmVhbXMuZm9yRWFjaChmdW5jdGlvbihsb2NhbFN0cmVhbSkge1xuICAgICAgbG9jYWxTdHJlYW0uZ2V0VHJhY2tzKCkuZm9yRWFjaChmdW5jdGlvbih0cmFjaykge1xuICAgICAgICB0cmFja3MucHVzaCh7XG4gICAgICAgICAga2luZDogdHJhY2sua2luZCxcbiAgICAgICAgICB0cmFjazogdHJhY2ssXG4gICAgICAgICAgc3RyZWFtOiBsb2NhbFN0cmVhbSxcbiAgICAgICAgICB3YW50UmVjZWl2ZTogdHJhY2sua2luZCA9PT0gJ2F1ZGlvJyA/XG4gICAgICAgICAgICAgIG51bUF1ZGlvVHJhY2tzID4gMCA6IG51bVZpZGVvVHJhY2tzID4gMFxuICAgICAgICB9KTtcbiAgICAgICAgaWYgKHRyYWNrLmtpbmQgPT09ICdhdWRpbycpIHtcbiAgICAgICAgICBudW1BdWRpb1RyYWNrcy0tO1xuICAgICAgICB9IGVsc2UgaWYgKHRyYWNrLmtpbmQgPT09ICd2aWRlbycpIHtcbiAgICAgICAgICBudW1WaWRlb1RyYWNrcy0tO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIC8vIENyZWF0ZSBNLWxpbmVzIGZvciByZWN2b25seSBzdHJlYW1zLlxuICAgIHdoaWxlIChudW1BdWRpb1RyYWNrcyA+IDAgfHwgbnVtVmlkZW9UcmFja3MgPiAwKSB7XG4gICAgICBpZiAobnVtQXVkaW9UcmFja3MgPiAwKSB7XG4gICAgICAgIHRyYWNrcy5wdXNoKHtcbiAgICAgICAgICBraW5kOiAnYXVkaW8nLFxuICAgICAgICAgIHdhbnRSZWNlaXZlOiB0cnVlXG4gICAgICAgIH0pO1xuICAgICAgICBudW1BdWRpb1RyYWNrcy0tO1xuICAgICAgfVxuICAgICAgaWYgKG51bVZpZGVvVHJhY2tzID4gMCkge1xuICAgICAgICB0cmFja3MucHVzaCh7XG4gICAgICAgICAga2luZDogJ3ZpZGVvJyxcbiAgICAgICAgICB3YW50UmVjZWl2ZTogdHJ1ZVxuICAgICAgICB9KTtcbiAgICAgICAgbnVtVmlkZW9UcmFja3MtLTtcbiAgICAgIH1cbiAgICB9XG4gICAgLy8gcmVvcmRlciB0cmFja3NcbiAgICB0cmFja3MgPSBzb3J0VHJhY2tzKHRyYWNrcyk7XG5cbiAgICB2YXIgc2RwID0gU0RQVXRpbHMud3JpdGVTZXNzaW9uQm9pbGVycGxhdGUoKTtcbiAgICB2YXIgdHJhbnNjZWl2ZXJzID0gW107XG4gICAgdHJhY2tzLmZvckVhY2goZnVuY3Rpb24obWxpbmUsIHNkcE1MaW5lSW5kZXgpIHtcbiAgICAgIC8vIEZvciBlYWNoIHRyYWNrLCBjcmVhdGUgYW4gaWNlIGdhdGhlcmVyLCBpY2UgdHJhbnNwb3J0LFxuICAgICAgLy8gZHRscyB0cmFuc3BvcnQsIHBvdGVudGlhbGx5IHJ0cHNlbmRlciBhbmQgcnRwcmVjZWl2ZXIuXG4gICAgICB2YXIgdHJhY2sgPSBtbGluZS50cmFjaztcbiAgICAgIHZhciBraW5kID0gbWxpbmUua2luZDtcbiAgICAgIHZhciBtaWQgPSBTRFBVdGlscy5nZW5lcmF0ZUlkZW50aWZpZXIoKTtcblxuICAgICAgdmFyIHRyYW5zcG9ydHMgPSBzZWxmLnVzaW5nQnVuZGxlICYmIHNkcE1MaW5lSW5kZXggPiAwID8ge1xuICAgICAgICBpY2VHYXRoZXJlcjogdHJhbnNjZWl2ZXJzWzBdLmljZUdhdGhlcmVyLFxuICAgICAgICBpY2VUcmFuc3BvcnQ6IHRyYW5zY2VpdmVyc1swXS5pY2VUcmFuc3BvcnQsXG4gICAgICAgIGR0bHNUcmFuc3BvcnQ6IHRyYW5zY2VpdmVyc1swXS5kdGxzVHJhbnNwb3J0XG4gICAgICB9IDogc2VsZi5fY3JlYXRlSWNlQW5kRHRsc1RyYW5zcG9ydHMobWlkLCBzZHBNTGluZUluZGV4KTtcblxuICAgICAgdmFyIGxvY2FsQ2FwYWJpbGl0aWVzID0gUlRDUnRwU2VuZGVyLmdldENhcGFiaWxpdGllcyhraW5kKTtcbiAgICAgIC8vIGZpbHRlciBSVFggdW50aWwgYWRkaXRpb25hbCBzdHVmZiBuZWVkZWQgZm9yIFJUWCBpcyBpbXBsZW1lbnRlZFxuICAgICAgLy8gaW4gYWRhcHRlci5qc1xuICAgICAgaWYgKGVkZ2VWZXJzaW9uIDwgMTUwMTkpIHtcbiAgICAgICAgbG9jYWxDYXBhYmlsaXRpZXMuY29kZWNzID0gbG9jYWxDYXBhYmlsaXRpZXMuY29kZWNzLmZpbHRlcihcbiAgICAgICAgICAgIGZ1bmN0aW9uKGNvZGVjKSB7XG4gICAgICAgICAgICAgIHJldHVybiBjb2RlYy5uYW1lICE9PSAncnR4JztcbiAgICAgICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgbG9jYWxDYXBhYmlsaXRpZXMuY29kZWNzLmZvckVhY2goZnVuY3Rpb24oY29kZWMpIHtcbiAgICAgICAgLy8gd29yayBhcm91bmQgaHR0cHM6Ly9idWdzLmNocm9taXVtLm9yZy9wL3dlYnJ0Yy9pc3N1ZXMvZGV0YWlsP2lkPTY1NTJcbiAgICAgICAgLy8gYnkgYWRkaW5nIGxldmVsLWFzeW1tZXRyeS1hbGxvd2VkPTFcbiAgICAgICAgaWYgKGNvZGVjLm5hbWUgPT09ICdIMjY0JyAmJlxuICAgICAgICAgICAgY29kZWMucGFyYW1ldGVyc1snbGV2ZWwtYXN5bW1ldHJ5LWFsbG93ZWQnXSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgY29kZWMucGFyYW1ldGVyc1snbGV2ZWwtYXN5bW1ldHJ5LWFsbG93ZWQnXSA9ICcxJztcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIHZhciBydHBTZW5kZXI7XG4gICAgICB2YXIgcnRwUmVjZWl2ZXI7XG5cbiAgICAgIC8vIGdlbmVyYXRlIGFuIHNzcmMgbm93LCB0byBiZSB1c2VkIGxhdGVyIGluIHJ0cFNlbmRlci5zZW5kXG4gICAgICB2YXIgc2VuZEVuY29kaW5nUGFyYW1ldGVycyA9IFt7XG4gICAgICAgIHNzcmM6ICgyICogc2RwTUxpbmVJbmRleCArIDEpICogMTAwMVxuICAgICAgfV07XG4gICAgICBpZiAodHJhY2spIHtcbiAgICAgICAgLy8gYWRkIFJUWFxuICAgICAgICBpZiAoZWRnZVZlcnNpb24gPj0gMTUwMTkgJiYga2luZCA9PT0gJ3ZpZGVvJykge1xuICAgICAgICAgIHNlbmRFbmNvZGluZ1BhcmFtZXRlcnNbMF0ucnR4ID0ge1xuICAgICAgICAgICAgc3NyYzogKDIgKiBzZHBNTGluZUluZGV4ICsgMSkgKiAxMDAxICsgMVxuICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgcnRwU2VuZGVyID0gbmV3IFJUQ1J0cFNlbmRlcih0cmFjaywgdHJhbnNwb3J0cy5kdGxzVHJhbnNwb3J0KTtcbiAgICAgIH1cblxuICAgICAgaWYgKG1saW5lLndhbnRSZWNlaXZlKSB7XG4gICAgICAgIHJ0cFJlY2VpdmVyID0gbmV3IFJUQ1J0cFJlY2VpdmVyKHRyYW5zcG9ydHMuZHRsc1RyYW5zcG9ydCwga2luZCk7XG4gICAgICB9XG5cbiAgICAgIHRyYW5zY2VpdmVyc1tzZHBNTGluZUluZGV4XSA9IHtcbiAgICAgICAgaWNlR2F0aGVyZXI6IHRyYW5zcG9ydHMuaWNlR2F0aGVyZXIsXG4gICAgICAgIGljZVRyYW5zcG9ydDogdHJhbnNwb3J0cy5pY2VUcmFuc3BvcnQsXG4gICAgICAgIGR0bHNUcmFuc3BvcnQ6IHRyYW5zcG9ydHMuZHRsc1RyYW5zcG9ydCxcbiAgICAgICAgbG9jYWxDYXBhYmlsaXRpZXM6IGxvY2FsQ2FwYWJpbGl0aWVzLFxuICAgICAgICByZW1vdGVDYXBhYmlsaXRpZXM6IG51bGwsXG4gICAgICAgIHJ0cFNlbmRlcjogcnRwU2VuZGVyLFxuICAgICAgICBydHBSZWNlaXZlcjogcnRwUmVjZWl2ZXIsXG4gICAgICAgIGtpbmQ6IGtpbmQsXG4gICAgICAgIG1pZDogbWlkLFxuICAgICAgICBzZW5kRW5jb2RpbmdQYXJhbWV0ZXJzOiBzZW5kRW5jb2RpbmdQYXJhbWV0ZXJzLFxuICAgICAgICByZWN2RW5jb2RpbmdQYXJhbWV0ZXJzOiBudWxsXG4gICAgICB9O1xuICAgIH0pO1xuXG4gICAgLy8gYWx3YXlzIG9mZmVyIEJVTkRMRSBhbmQgZGlzcG9zZSBvbiByZXR1cm4gaWYgbm90IHN1cHBvcnRlZC5cbiAgICBpZiAodGhpcy5fY29uZmlnLmJ1bmRsZVBvbGljeSAhPT0gJ21heC1jb21wYXQnKSB7XG4gICAgICBzZHAgKz0gJ2E9Z3JvdXA6QlVORExFICcgKyB0cmFuc2NlaXZlcnMubWFwKGZ1bmN0aW9uKHQpIHtcbiAgICAgICAgcmV0dXJuIHQubWlkO1xuICAgICAgfSkuam9pbignICcpICsgJ1xcclxcbic7XG4gICAgfVxuICAgIHNkcCArPSAnYT1pY2Utb3B0aW9uczp0cmlja2xlXFxyXFxuJztcblxuICAgIHRyYWNrcy5mb3JFYWNoKGZ1bmN0aW9uKG1saW5lLCBzZHBNTGluZUluZGV4KSB7XG4gICAgICB2YXIgdHJhbnNjZWl2ZXIgPSB0cmFuc2NlaXZlcnNbc2RwTUxpbmVJbmRleF07XG4gICAgICBzZHAgKz0gU0RQVXRpbHMud3JpdGVNZWRpYVNlY3Rpb24odHJhbnNjZWl2ZXIsXG4gICAgICAgICAgdHJhbnNjZWl2ZXIubG9jYWxDYXBhYmlsaXRpZXMsICdvZmZlcicsIG1saW5lLnN0cmVhbSk7XG4gICAgICBzZHAgKz0gJ2E9cnRjcC1yc2l6ZVxcclxcbic7XG4gICAgfSk7XG5cbiAgICB0aGlzLl9wZW5kaW5nT2ZmZXIgPSB0cmFuc2NlaXZlcnM7XG4gICAgdmFyIGRlc2MgPSBuZXcgUlRDU2Vzc2lvbkRlc2NyaXB0aW9uKHtcbiAgICAgIHR5cGU6ICdvZmZlcicsXG4gICAgICBzZHA6IHNkcFxuICAgIH0pO1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoICYmIHR5cGVvZiBhcmd1bWVudHNbMF0gPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHdpbmRvdy5zZXRUaW1lb3V0KGFyZ3VtZW50c1swXSwgMCwgZGVzYyk7XG4gICAgfVxuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoZGVzYyk7XG4gIH07XG5cbiAgUlRDUGVlckNvbm5lY3Rpb24ucHJvdG90eXBlLmNyZWF0ZUFuc3dlciA9IGZ1bmN0aW9uKCkge1xuICAgIHZhciBzZWxmID0gdGhpcztcblxuICAgIHZhciBzZHAgPSBTRFBVdGlscy53cml0ZVNlc3Npb25Cb2lsZXJwbGF0ZSgpO1xuICAgIGlmICh0aGlzLnVzaW5nQnVuZGxlKSB7XG4gICAgICBzZHAgKz0gJ2E9Z3JvdXA6QlVORExFICcgKyB0aGlzLnRyYW5zY2VpdmVycy5tYXAoZnVuY3Rpb24odCkge1xuICAgICAgICByZXR1cm4gdC5taWQ7XG4gICAgICB9KS5qb2luKCcgJykgKyAnXFxyXFxuJztcbiAgICB9XG4gICAgdGhpcy50cmFuc2NlaXZlcnMuZm9yRWFjaChmdW5jdGlvbih0cmFuc2NlaXZlcikge1xuICAgICAgaWYgKHRyYW5zY2VpdmVyLmlzRGF0YWNoYW5uZWwpIHtcbiAgICAgICAgc2RwICs9ICdtPWFwcGxpY2F0aW9uIDAgRFRMUy9TQ1RQIDUwMDBcXHJcXG4nICtcbiAgICAgICAgICAgICdjPUlOIElQNCAwLjAuMC4wXFxyXFxuJyArXG4gICAgICAgICAgICAnYT1taWQ6JyArIHRyYW5zY2VpdmVyLm1pZCArICdcXHJcXG4nO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICAvLyBDYWxjdWxhdGUgaW50ZXJzZWN0aW9uIG9mIGNhcGFiaWxpdGllcy5cbiAgICAgIHZhciBjb21tb25DYXBhYmlsaXRpZXMgPSBzZWxmLl9nZXRDb21tb25DYXBhYmlsaXRpZXMoXG4gICAgICAgICAgdHJhbnNjZWl2ZXIubG9jYWxDYXBhYmlsaXRpZXMsXG4gICAgICAgICAgdHJhbnNjZWl2ZXIucmVtb3RlQ2FwYWJpbGl0aWVzKTtcblxuICAgICAgdmFyIGhhc1J0eCA9IGNvbW1vbkNhcGFiaWxpdGllcy5jb2RlY3MuZmlsdGVyKGZ1bmN0aW9uKGMpIHtcbiAgICAgICAgcmV0dXJuIGMubmFtZS50b0xvd2VyQ2FzZSgpID09PSAncnR4JztcbiAgICAgIH0pLmxlbmd0aDtcbiAgICAgIGlmICghaGFzUnR4ICYmIHRyYW5zY2VpdmVyLnNlbmRFbmNvZGluZ1BhcmFtZXRlcnNbMF0ucnR4KSB7XG4gICAgICAgIGRlbGV0ZSB0cmFuc2NlaXZlci5zZW5kRW5jb2RpbmdQYXJhbWV0ZXJzWzBdLnJ0eDtcbiAgICAgIH1cblxuICAgICAgc2RwICs9IFNEUFV0aWxzLndyaXRlTWVkaWFTZWN0aW9uKHRyYW5zY2VpdmVyLCBjb21tb25DYXBhYmlsaXRpZXMsXG4gICAgICAgICAgJ2Fuc3dlcicsIHNlbGYubG9jYWxTdHJlYW1zWzBdKTtcbiAgICAgIGlmICh0cmFuc2NlaXZlci5ydGNwUGFyYW1ldGVycyAmJlxuICAgICAgICAgIHRyYW5zY2VpdmVyLnJ0Y3BQYXJhbWV0ZXJzLnJlZHVjZWRTaXplKSB7XG4gICAgICAgIHNkcCArPSAnYT1ydGNwLXJzaXplXFxyXFxuJztcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIHZhciBkZXNjID0gbmV3IFJUQ1Nlc3Npb25EZXNjcmlwdGlvbih7XG4gICAgICB0eXBlOiAnYW5zd2VyJyxcbiAgICAgIHNkcDogc2RwXG4gICAgfSk7XG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggJiYgdHlwZW9mIGFyZ3VtZW50c1swXSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgd2luZG93LnNldFRpbWVvdXQoYXJndW1lbnRzWzBdLCAwLCBkZXNjKTtcbiAgICB9XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShkZXNjKTtcbiAgfTtcblxuICBSVENQZWVyQ29ubmVjdGlvbi5wcm90b3R5cGUuYWRkSWNlQ2FuZGlkYXRlID0gZnVuY3Rpb24oY2FuZGlkYXRlKSB7XG4gICAgaWYgKCFjYW5kaWRhdGUpIHtcbiAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgdGhpcy50cmFuc2NlaXZlcnMubGVuZ3RoOyBqKyspIHtcbiAgICAgICAgdGhpcy50cmFuc2NlaXZlcnNbal0uaWNlVHJhbnNwb3J0LmFkZFJlbW90ZUNhbmRpZGF0ZSh7fSk7XG4gICAgICAgIGlmICh0aGlzLnVzaW5nQnVuZGxlKSB7XG4gICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHZhciBtTGluZUluZGV4ID0gY2FuZGlkYXRlLnNkcE1MaW5lSW5kZXg7XG4gICAgICBpZiAoY2FuZGlkYXRlLnNkcE1pZCkge1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMudHJhbnNjZWl2ZXJzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgaWYgKHRoaXMudHJhbnNjZWl2ZXJzW2ldLm1pZCA9PT0gY2FuZGlkYXRlLnNkcE1pZCkge1xuICAgICAgICAgICAgbUxpbmVJbmRleCA9IGk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHZhciB0cmFuc2NlaXZlciA9IHRoaXMudHJhbnNjZWl2ZXJzW21MaW5lSW5kZXhdO1xuICAgICAgaWYgKHRyYW5zY2VpdmVyKSB7XG4gICAgICAgIHZhciBjYW5kID0gT2JqZWN0LmtleXMoY2FuZGlkYXRlLmNhbmRpZGF0ZSkubGVuZ3RoID4gMCA/XG4gICAgICAgICAgICBTRFBVdGlscy5wYXJzZUNhbmRpZGF0ZShjYW5kaWRhdGUuY2FuZGlkYXRlKSA6IHt9O1xuICAgICAgICAvLyBJZ25vcmUgQ2hyb21lJ3MgaW52YWxpZCBjYW5kaWRhdGVzIHNpbmNlIEVkZ2UgZG9lcyBub3QgbGlrZSB0aGVtLlxuICAgICAgICBpZiAoY2FuZC5wcm90b2NvbCA9PT0gJ3RjcCcgJiYgKGNhbmQucG9ydCA9PT0gMCB8fCBjYW5kLnBvcnQgPT09IDkpKSB7XG4gICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICAgICAgICB9XG4gICAgICAgIC8vIElnbm9yZSBSVENQIGNhbmRpZGF0ZXMsIHdlIGFzc3VtZSBSVENQLU1VWC5cbiAgICAgICAgaWYgKGNhbmQuY29tcG9uZW50ICE9PSAnMScpIHtcbiAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgICAgIH1cbiAgICAgICAgdHJhbnNjZWl2ZXIuaWNlVHJhbnNwb3J0LmFkZFJlbW90ZUNhbmRpZGF0ZShjYW5kKTtcblxuICAgICAgICAvLyB1cGRhdGUgdGhlIHJlbW90ZURlc2NyaXB0aW9uLlxuICAgICAgICB2YXIgc2VjdGlvbnMgPSBTRFBVdGlscy5zcGxpdFNlY3Rpb25zKHRoaXMucmVtb3RlRGVzY3JpcHRpb24uc2RwKTtcbiAgICAgICAgc2VjdGlvbnNbbUxpbmVJbmRleCArIDFdICs9IChjYW5kLnR5cGUgPyBjYW5kaWRhdGUuY2FuZGlkYXRlLnRyaW0oKVxuICAgICAgICAgICAgOiAnYT1lbmQtb2YtY2FuZGlkYXRlcycpICsgJ1xcclxcbic7XG4gICAgICAgIHRoaXMucmVtb3RlRGVzY3JpcHRpb24uc2RwID0gc2VjdGlvbnMuam9pbignJyk7XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID4gMSAmJiB0eXBlb2YgYXJndW1lbnRzWzFdID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICB3aW5kb3cuc2V0VGltZW91dChhcmd1bWVudHNbMV0sIDApO1xuICAgIH1cbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gIH07XG5cbiAgUlRDUGVlckNvbm5lY3Rpb24ucHJvdG90eXBlLmdldFN0YXRzID0gZnVuY3Rpb24oKSB7XG4gICAgdmFyIHByb21pc2VzID0gW107XG4gICAgdGhpcy50cmFuc2NlaXZlcnMuZm9yRWFjaChmdW5jdGlvbih0cmFuc2NlaXZlcikge1xuICAgICAgWydydHBTZW5kZXInLCAncnRwUmVjZWl2ZXInLCAnaWNlR2F0aGVyZXInLCAnaWNlVHJhbnNwb3J0JyxcbiAgICAgICAgICAnZHRsc1RyYW5zcG9ydCddLmZvckVhY2goZnVuY3Rpb24obWV0aG9kKSB7XG4gICAgICAgICAgICBpZiAodHJhbnNjZWl2ZXJbbWV0aG9kXSkge1xuICAgICAgICAgICAgICBwcm9taXNlcy5wdXNoKHRyYW5zY2VpdmVyW21ldGhvZF0uZ2V0U3RhdHMoKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSk7XG4gICAgfSk7XG4gICAgdmFyIGNiID0gYXJndW1lbnRzLmxlbmd0aCA+IDEgJiYgdHlwZW9mIGFyZ3VtZW50c1sxXSA9PT0gJ2Z1bmN0aW9uJyAmJlxuICAgICAgICBhcmd1bWVudHNbMV07XG4gICAgdmFyIGZpeFN0YXRzVHlwZSA9IGZ1bmN0aW9uKHN0YXQpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGluYm91bmRydHA6ICdpbmJvdW5kLXJ0cCcsXG4gICAgICAgIG91dGJvdW5kcnRwOiAnb3V0Ym91bmQtcnRwJyxcbiAgICAgICAgY2FuZGlkYXRlcGFpcjogJ2NhbmRpZGF0ZS1wYWlyJyxcbiAgICAgICAgbG9jYWxjYW5kaWRhdGU6ICdsb2NhbC1jYW5kaWRhdGUnLFxuICAgICAgICByZW1vdGVjYW5kaWRhdGU6ICdyZW1vdGUtY2FuZGlkYXRlJ1xuICAgICAgfVtzdGF0LnR5cGVdIHx8IHN0YXQudHlwZTtcbiAgICB9O1xuICAgIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbihyZXNvbHZlKSB7XG4gICAgICAvLyBzaGltIGdldFN0YXRzIHdpdGggbWFwbGlrZSBzdXBwb3J0XG4gICAgICB2YXIgcmVzdWx0cyA9IG5ldyBNYXAoKTtcbiAgICAgIFByb21pc2UuYWxsKHByb21pc2VzKS50aGVuKGZ1bmN0aW9uKHJlcykge1xuICAgICAgICByZXMuZm9yRWFjaChmdW5jdGlvbihyZXN1bHQpIHtcbiAgICAgICAgICBPYmplY3Qua2V5cyhyZXN1bHQpLmZvckVhY2goZnVuY3Rpb24oaWQpIHtcbiAgICAgICAgICAgIHJlc3VsdFtpZF0udHlwZSA9IGZpeFN0YXRzVHlwZShyZXN1bHRbaWRdKTtcbiAgICAgICAgICAgIHJlc3VsdHMuc2V0KGlkLCByZXN1bHRbaWRdKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgICAgIGlmIChjYikge1xuICAgICAgICAgIHdpbmRvdy5zZXRUaW1lb3V0KGNiLCAwLCByZXN1bHRzKTtcbiAgICAgICAgfVxuICAgICAgICByZXNvbHZlKHJlc3VsdHMpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH07XG4gIHJldHVybiBSVENQZWVyQ29ubmVjdGlvbjtcbn07XG4iLCIvKlxuICogIENvcHlyaWdodCAoYykgMjAxNiBUaGUgV2ViUlRDIHByb2plY3QgYXV0aG9ycy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqXG4gKiAgVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZVxuICogIHRoYXQgY2FuIGJlIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgaW4gdGhlIHJvb3Qgb2YgdGhlIHNvdXJjZVxuICogIHRyZWUuXG4gKi9cbiAvKiBlc2xpbnQtZW52IG5vZGUgKi9cbid1c2Ugc3RyaWN0JztcblxudmFyIGJyb3dzZXJEZXRhaWxzID0gcmVxdWlyZSgnLi4vdXRpbHMnKS5icm93c2VyRGV0YWlscztcblxudmFyIGZpcmVmb3hTaGltID0ge1xuICBzaGltT25UcmFjazogZnVuY3Rpb24oKSB7XG4gICAgaWYgKHR5cGVvZiB3aW5kb3cgPT09ICdvYmplY3QnICYmIHdpbmRvdy5SVENQZWVyQ29ubmVjdGlvbiAmJiAhKCdvbnRyYWNrJyBpblxuICAgICAgICB3aW5kb3cuUlRDUGVlckNvbm5lY3Rpb24ucHJvdG90eXBlKSkge1xuICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHdpbmRvdy5SVENQZWVyQ29ubmVjdGlvbi5wcm90b3R5cGUsICdvbnRyYWNrJywge1xuICAgICAgICBnZXQ6IGZ1bmN0aW9uKCkge1xuICAgICAgICAgIHJldHVybiB0aGlzLl9vbnRyYWNrO1xuICAgICAgICB9LFxuICAgICAgICBzZXQ6IGZ1bmN0aW9uKGYpIHtcbiAgICAgICAgICBpZiAodGhpcy5fb250cmFjaykge1xuICAgICAgICAgICAgdGhpcy5yZW1vdmVFdmVudExpc3RlbmVyKCd0cmFjaycsIHRoaXMuX29udHJhY2spO1xuICAgICAgICAgICAgdGhpcy5yZW1vdmVFdmVudExpc3RlbmVyKCdhZGRzdHJlYW0nLCB0aGlzLl9vbnRyYWNrcG9seSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHRoaXMuYWRkRXZlbnRMaXN0ZW5lcigndHJhY2snLCB0aGlzLl9vbnRyYWNrID0gZik7XG4gICAgICAgICAgdGhpcy5hZGRFdmVudExpc3RlbmVyKCdhZGRzdHJlYW0nLCB0aGlzLl9vbnRyYWNrcG9seSA9IGZ1bmN0aW9uKGUpIHtcbiAgICAgICAgICAgIGUuc3RyZWFtLmdldFRyYWNrcygpLmZvckVhY2goZnVuY3Rpb24odHJhY2spIHtcbiAgICAgICAgICAgICAgdmFyIGV2ZW50ID0gbmV3IEV2ZW50KCd0cmFjaycpO1xuICAgICAgICAgICAgICBldmVudC50cmFjayA9IHRyYWNrO1xuICAgICAgICAgICAgICBldmVudC5yZWNlaXZlciA9IHt0cmFjazogdHJhY2t9O1xuICAgICAgICAgICAgICBldmVudC5zdHJlYW1zID0gW2Uuc3RyZWFtXTtcbiAgICAgICAgICAgICAgdGhpcy5kaXNwYXRjaEV2ZW50KGV2ZW50KTtcbiAgICAgICAgICAgIH0uYmluZCh0aGlzKSk7XG4gICAgICAgICAgfS5iaW5kKHRoaXMpKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuICB9LFxuXG4gIHNoaW1Tb3VyY2VPYmplY3Q6IGZ1bmN0aW9uKCkge1xuICAgIC8vIEZpcmVmb3ggaGFzIHN1cHBvcnRlZCBtb3pTcmNPYmplY3Qgc2luY2UgRkYyMiwgdW5wcmVmaXhlZCBpbiA0Mi5cbiAgICBpZiAodHlwZW9mIHdpbmRvdyA9PT0gJ29iamVjdCcpIHtcbiAgICAgIGlmICh3aW5kb3cuSFRNTE1lZGlhRWxlbWVudCAmJlxuICAgICAgICAhKCdzcmNPYmplY3QnIGluIHdpbmRvdy5IVE1MTWVkaWFFbGVtZW50LnByb3RvdHlwZSkpIHtcbiAgICAgICAgLy8gU2hpbSB0aGUgc3JjT2JqZWN0IHByb3BlcnR5LCBvbmNlLCB3aGVuIEhUTUxNZWRpYUVsZW1lbnQgaXMgZm91bmQuXG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh3aW5kb3cuSFRNTE1lZGlhRWxlbWVudC5wcm90b3R5cGUsICdzcmNPYmplY3QnLCB7XG4gICAgICAgICAgZ2V0OiBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLm1velNyY09iamVjdDtcbiAgICAgICAgICB9LFxuICAgICAgICAgIHNldDogZnVuY3Rpb24oc3RyZWFtKSB7XG4gICAgICAgICAgICB0aGlzLm1velNyY09iamVjdCA9IHN0cmVhbTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cbiAgfSxcblxuICBzaGltUGVlckNvbm5lY3Rpb246IGZ1bmN0aW9uKCkge1xuICAgIGlmICh0eXBlb2Ygd2luZG93ICE9PSAnb2JqZWN0JyB8fCAhKHdpbmRvdy5SVENQZWVyQ29ubmVjdGlvbiB8fFxuICAgICAgICB3aW5kb3cubW96UlRDUGVlckNvbm5lY3Rpb24pKSB7XG4gICAgICByZXR1cm47IC8vIHByb2JhYmx5IG1lZGlhLnBlZXJjb25uZWN0aW9uLmVuYWJsZWQ9ZmFsc2UgaW4gYWJvdXQ6Y29uZmlnXG4gICAgfVxuICAgIC8vIFRoZSBSVENQZWVyQ29ubmVjdGlvbiBvYmplY3QuXG4gICAgaWYgKCF3aW5kb3cuUlRDUGVlckNvbm5lY3Rpb24pIHtcbiAgICAgIHdpbmRvdy5SVENQZWVyQ29ubmVjdGlvbiA9IGZ1bmN0aW9uKHBjQ29uZmlnLCBwY0NvbnN0cmFpbnRzKSB7XG4gICAgICAgIGlmIChicm93c2VyRGV0YWlscy52ZXJzaW9uIDwgMzgpIHtcbiAgICAgICAgICAvLyAudXJscyBpcyBub3Qgc3VwcG9ydGVkIGluIEZGIDwgMzguXG4gICAgICAgICAgLy8gY3JlYXRlIFJUQ0ljZVNlcnZlcnMgd2l0aCBhIHNpbmdsZSB1cmwuXG4gICAgICAgICAgaWYgKHBjQ29uZmlnICYmIHBjQ29uZmlnLmljZVNlcnZlcnMpIHtcbiAgICAgICAgICAgIHZhciBuZXdJY2VTZXJ2ZXJzID0gW107XG4gICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHBjQ29uZmlnLmljZVNlcnZlcnMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgdmFyIHNlcnZlciA9IHBjQ29uZmlnLmljZVNlcnZlcnNbaV07XG4gICAgICAgICAgICAgIGlmIChzZXJ2ZXIuaGFzT3duUHJvcGVydHkoJ3VybHMnKSkge1xuICAgICAgICAgICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgc2VydmVyLnVybHMubGVuZ3RoOyBqKyspIHtcbiAgICAgICAgICAgICAgICAgIHZhciBuZXdTZXJ2ZXIgPSB7XG4gICAgICAgICAgICAgICAgICAgIHVybDogc2VydmVyLnVybHNbal1cbiAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICBpZiAoc2VydmVyLnVybHNbal0uaW5kZXhPZigndHVybicpID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgIG5ld1NlcnZlci51c2VybmFtZSA9IHNlcnZlci51c2VybmFtZTtcbiAgICAgICAgICAgICAgICAgICAgbmV3U2VydmVyLmNyZWRlbnRpYWwgPSBzZXJ2ZXIuY3JlZGVudGlhbDtcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIG5ld0ljZVNlcnZlcnMucHVzaChuZXdTZXJ2ZXIpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBuZXdJY2VTZXJ2ZXJzLnB1c2gocGNDb25maWcuaWNlU2VydmVyc1tpXSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHBjQ29uZmlnLmljZVNlcnZlcnMgPSBuZXdJY2VTZXJ2ZXJzO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbmV3IG1velJUQ1BlZXJDb25uZWN0aW9uKHBjQ29uZmlnLCBwY0NvbnN0cmFpbnRzKTtcbiAgICAgIH07XG4gICAgICB3aW5kb3cuUlRDUGVlckNvbm5lY3Rpb24ucHJvdG90eXBlID0gbW96UlRDUGVlckNvbm5lY3Rpb24ucHJvdG90eXBlO1xuXG4gICAgICAvLyB3cmFwIHN0YXRpYyBtZXRob2RzLiBDdXJyZW50bHkganVzdCBnZW5lcmF0ZUNlcnRpZmljYXRlLlxuICAgICAgaWYgKG1velJUQ1BlZXJDb25uZWN0aW9uLmdlbmVyYXRlQ2VydGlmaWNhdGUpIHtcbiAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHdpbmRvdy5SVENQZWVyQ29ubmVjdGlvbiwgJ2dlbmVyYXRlQ2VydGlmaWNhdGUnLCB7XG4gICAgICAgICAgZ2V0OiBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgIHJldHVybiBtb3pSVENQZWVyQ29ubmVjdGlvbi5nZW5lcmF0ZUNlcnRpZmljYXRlO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIHdpbmRvdy5SVENTZXNzaW9uRGVzY3JpcHRpb24gPSBtb3pSVENTZXNzaW9uRGVzY3JpcHRpb247XG4gICAgICB3aW5kb3cuUlRDSWNlQ2FuZGlkYXRlID0gbW96UlRDSWNlQ2FuZGlkYXRlO1xuICAgIH1cblxuICAgIC8vIHNoaW0gYXdheSBuZWVkIGZvciBvYnNvbGV0ZSBSVENJY2VDYW5kaWRhdGUvUlRDU2Vzc2lvbkRlc2NyaXB0aW9uLlxuICAgIFsnc2V0TG9jYWxEZXNjcmlwdGlvbicsICdzZXRSZW1vdGVEZXNjcmlwdGlvbicsICdhZGRJY2VDYW5kaWRhdGUnXVxuICAgICAgICAuZm9yRWFjaChmdW5jdGlvbihtZXRob2QpIHtcbiAgICAgICAgICB2YXIgbmF0aXZlTWV0aG9kID0gUlRDUGVlckNvbm5lY3Rpb24ucHJvdG90eXBlW21ldGhvZF07XG4gICAgICAgICAgUlRDUGVlckNvbm5lY3Rpb24ucHJvdG90eXBlW21ldGhvZF0gPSBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgIGFyZ3VtZW50c1swXSA9IG5ldyAoKG1ldGhvZCA9PT0gJ2FkZEljZUNhbmRpZGF0ZScpID9cbiAgICAgICAgICAgICAgICBSVENJY2VDYW5kaWRhdGUgOiBSVENTZXNzaW9uRGVzY3JpcHRpb24pKGFyZ3VtZW50c1swXSk7XG4gICAgICAgICAgICByZXR1cm4gbmF0aXZlTWV0aG9kLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICAgICAgfTtcbiAgICAgICAgfSk7XG5cbiAgICAvLyBzdXBwb3J0IGZvciBhZGRJY2VDYW5kaWRhdGUobnVsbCBvciB1bmRlZmluZWQpXG4gICAgdmFyIG5hdGl2ZUFkZEljZUNhbmRpZGF0ZSA9XG4gICAgICAgIFJUQ1BlZXJDb25uZWN0aW9uLnByb3RvdHlwZS5hZGRJY2VDYW5kaWRhdGU7XG4gICAgUlRDUGVlckNvbm5lY3Rpb24ucHJvdG90eXBlLmFkZEljZUNhbmRpZGF0ZSA9IGZ1bmN0aW9uKCkge1xuICAgICAgaWYgKCFhcmd1bWVudHNbMF0pIHtcbiAgICAgICAgaWYgKGFyZ3VtZW50c1sxXSkge1xuICAgICAgICAgIGFyZ3VtZW50c1sxXS5hcHBseShudWxsKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgICB9XG4gICAgICByZXR1cm4gbmF0aXZlQWRkSWNlQ2FuZGlkYXRlLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgfTtcblxuICAgIC8vIHNoaW0gZ2V0U3RhdHMgd2l0aCBtYXBsaWtlIHN1cHBvcnRcbiAgICB2YXIgbWFrZU1hcFN0YXRzID0gZnVuY3Rpb24oc3RhdHMpIHtcbiAgICAgIHZhciBtYXAgPSBuZXcgTWFwKCk7XG4gICAgICBPYmplY3Qua2V5cyhzdGF0cykuZm9yRWFjaChmdW5jdGlvbihrZXkpIHtcbiAgICAgICAgbWFwLnNldChrZXksIHN0YXRzW2tleV0pO1xuICAgICAgICBtYXBba2V5XSA9IHN0YXRzW2tleV07XG4gICAgICB9KTtcbiAgICAgIHJldHVybiBtYXA7XG4gICAgfTtcblxuICAgIHZhciBtb2Rlcm5TdGF0c1R5cGVzID0ge1xuICAgICAgaW5ib3VuZHJ0cDogJ2luYm91bmQtcnRwJyxcbiAgICAgIG91dGJvdW5kcnRwOiAnb3V0Ym91bmQtcnRwJyxcbiAgICAgIGNhbmRpZGF0ZXBhaXI6ICdjYW5kaWRhdGUtcGFpcicsXG4gICAgICBsb2NhbGNhbmRpZGF0ZTogJ2xvY2FsLWNhbmRpZGF0ZScsXG4gICAgICByZW1vdGVjYW5kaWRhdGU6ICdyZW1vdGUtY2FuZGlkYXRlJ1xuICAgIH07XG5cbiAgICB2YXIgbmF0aXZlR2V0U3RhdHMgPSBSVENQZWVyQ29ubmVjdGlvbi5wcm90b3R5cGUuZ2V0U3RhdHM7XG4gICAgUlRDUGVlckNvbm5lY3Rpb24ucHJvdG90eXBlLmdldFN0YXRzID0gZnVuY3Rpb24oc2VsZWN0b3IsIG9uU3VjYywgb25FcnIpIHtcbiAgICAgIHJldHVybiBuYXRpdmVHZXRTdGF0cy5hcHBseSh0aGlzLCBbc2VsZWN0b3IgfHwgbnVsbF0pXG4gICAgICAgIC50aGVuKGZ1bmN0aW9uKHN0YXRzKSB7XG4gICAgICAgICAgaWYgKGJyb3dzZXJEZXRhaWxzLnZlcnNpb24gPCA0OCkge1xuICAgICAgICAgICAgc3RhdHMgPSBtYWtlTWFwU3RhdHMoc3RhdHMpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoYnJvd3NlckRldGFpbHMudmVyc2lvbiA8IDUzICYmICFvblN1Y2MpIHtcbiAgICAgICAgICAgIC8vIFNoaW0gb25seSBwcm9taXNlIGdldFN0YXRzIHdpdGggc3BlYy1oeXBoZW5zIGluIHR5cGUgbmFtZXNcbiAgICAgICAgICAgIC8vIExlYXZlIGNhbGxiYWNrIHZlcnNpb24gYWxvbmU7IG1pc2Mgb2xkIHVzZXMgb2YgZm9yRWFjaCBiZWZvcmUgTWFwXG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICBzdGF0cy5mb3JFYWNoKGZ1bmN0aW9uKHN0YXQpIHtcbiAgICAgICAgICAgICAgICBzdGF0LnR5cGUgPSBtb2Rlcm5TdGF0c1R5cGVzW3N0YXQudHlwZV0gfHwgc3RhdC50eXBlO1xuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgaWYgKGUubmFtZSAhPT0gJ1R5cGVFcnJvcicpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBlO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIC8vIEF2b2lkIFR5cGVFcnJvcjogXCJ0eXBlXCIgaXMgcmVhZC1vbmx5LCBpbiBvbGQgdmVyc2lvbnMuIDM0LTQzaXNoXG4gICAgICAgICAgICAgIHN0YXRzLmZvckVhY2goZnVuY3Rpb24oc3RhdCwgaSkge1xuICAgICAgICAgICAgICAgIHN0YXRzLnNldChpLCBPYmplY3QuYXNzaWduKHt9LCBzdGF0LCB7XG4gICAgICAgICAgICAgICAgICB0eXBlOiBtb2Rlcm5TdGF0c1R5cGVzW3N0YXQudHlwZV0gfHwgc3RhdC50eXBlXG4gICAgICAgICAgICAgICAgfSkpO1xuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIHN0YXRzO1xuICAgICAgICB9KVxuICAgICAgICAudGhlbihvblN1Y2MsIG9uRXJyKTtcbiAgICB9O1xuICB9XG59O1xuXG4vLyBFeHBvc2UgcHVibGljIG1ldGhvZHMuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgc2hpbU9uVHJhY2s6IGZpcmVmb3hTaGltLnNoaW1PblRyYWNrLFxuICBzaGltU291cmNlT2JqZWN0OiBmaXJlZm94U2hpbS5zaGltU291cmNlT2JqZWN0LFxuICBzaGltUGVlckNvbm5lY3Rpb246IGZpcmVmb3hTaGltLnNoaW1QZWVyQ29ubmVjdGlvbixcbiAgc2hpbUdldFVzZXJNZWRpYTogcmVxdWlyZSgnLi9nZXR1c2VybWVkaWEnKVxufTtcbiIsIi8qXG4gKiAgQ29weXJpZ2h0IChjKSAyMDE2IFRoZSBXZWJSVEMgcHJvamVjdCBhdXRob3JzLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICpcbiAqICBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlXG4gKiAgdGhhdCBjYW4gYmUgZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZSBpbiB0aGUgcm9vdCBvZiB0aGUgc291cmNlXG4gKiAgdHJlZS5cbiAqL1xuIC8qIGVzbGludC1lbnYgbm9kZSAqL1xuJ3VzZSBzdHJpY3QnO1xuXG52YXIgbG9nZ2luZyA9IHJlcXVpcmUoJy4uL3V0aWxzJykubG9nO1xudmFyIGJyb3dzZXJEZXRhaWxzID0gcmVxdWlyZSgnLi4vdXRpbHMnKS5icm93c2VyRGV0YWlscztcblxuLy8gRXhwb3NlIHB1YmxpYyBtZXRob2RzLlxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbigpIHtcbiAgdmFyIHNoaW1FcnJvcl8gPSBmdW5jdGlvbihlKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIG5hbWU6IHtcbiAgICAgICAgTm90U3VwcG9ydGVkRXJyb3I6ICdUeXBlRXJyb3InLFxuICAgICAgICBTZWN1cml0eUVycm9yOiAnTm90QWxsb3dlZEVycm9yJyxcbiAgICAgICAgUGVybWlzc2lvbkRlbmllZEVycm9yOiAnTm90QWxsb3dlZEVycm9yJ1xuICAgICAgfVtlLm5hbWVdIHx8IGUubmFtZSxcbiAgICAgIG1lc3NhZ2U6IHtcbiAgICAgICAgJ1RoZSBvcGVyYXRpb24gaXMgaW5zZWN1cmUuJzogJ1RoZSByZXF1ZXN0IGlzIG5vdCBhbGxvd2VkIGJ5IHRoZSAnICtcbiAgICAgICAgJ3VzZXIgYWdlbnQgb3IgdGhlIHBsYXRmb3JtIGluIHRoZSBjdXJyZW50IGNvbnRleHQuJ1xuICAgICAgfVtlLm1lc3NhZ2VdIHx8IGUubWVzc2FnZSxcbiAgICAgIGNvbnN0cmFpbnQ6IGUuY29uc3RyYWludCxcbiAgICAgIHRvU3RyaW5nOiBmdW5jdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubmFtZSArICh0aGlzLm1lc3NhZ2UgJiYgJzogJykgKyB0aGlzLm1lc3NhZ2U7XG4gICAgICB9XG4gICAgfTtcbiAgfTtcblxuICAvLyBnZXRVc2VyTWVkaWEgY29uc3RyYWludHMgc2hpbS5cbiAgdmFyIGdldFVzZXJNZWRpYV8gPSBmdW5jdGlvbihjb25zdHJhaW50cywgb25TdWNjZXNzLCBvbkVycm9yKSB7XG4gICAgdmFyIGNvbnN0cmFpbnRzVG9GRjM3XyA9IGZ1bmN0aW9uKGMpIHtcbiAgICAgIGlmICh0eXBlb2YgYyAhPT0gJ29iamVjdCcgfHwgYy5yZXF1aXJlKSB7XG4gICAgICAgIHJldHVybiBjO1xuICAgICAgfVxuICAgICAgdmFyIHJlcXVpcmUgPSBbXTtcbiAgICAgIE9iamVjdC5rZXlzKGMpLmZvckVhY2goZnVuY3Rpb24oa2V5KSB7XG4gICAgICAgIGlmIChrZXkgPT09ICdyZXF1aXJlJyB8fCBrZXkgPT09ICdhZHZhbmNlZCcgfHwga2V5ID09PSAnbWVkaWFTb3VyY2UnKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHZhciByID0gY1trZXldID0gKHR5cGVvZiBjW2tleV0gPT09ICdvYmplY3QnKSA/XG4gICAgICAgICAgICBjW2tleV0gOiB7aWRlYWw6IGNba2V5XX07XG4gICAgICAgIGlmIChyLm1pbiAhPT0gdW5kZWZpbmVkIHx8XG4gICAgICAgICAgICByLm1heCAhPT0gdW5kZWZpbmVkIHx8IHIuZXhhY3QgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIHJlcXVpcmUucHVzaChrZXkpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChyLmV4YWN0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICBpZiAodHlwZW9mIHIuZXhhY3QgPT09ICdudW1iZXInKSB7XG4gICAgICAgICAgICByLiBtaW4gPSByLm1heCA9IHIuZXhhY3Q7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNba2V5XSA9IHIuZXhhY3Q7XG4gICAgICAgICAgfVxuICAgICAgICAgIGRlbGV0ZSByLmV4YWN0O1xuICAgICAgICB9XG4gICAgICAgIGlmIChyLmlkZWFsICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICBjLmFkdmFuY2VkID0gYy5hZHZhbmNlZCB8fCBbXTtcbiAgICAgICAgICB2YXIgb2MgPSB7fTtcbiAgICAgICAgICBpZiAodHlwZW9mIHIuaWRlYWwgPT09ICdudW1iZXInKSB7XG4gICAgICAgICAgICBvY1trZXldID0ge21pbjogci5pZGVhbCwgbWF4OiByLmlkZWFsfTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgb2Nba2V5XSA9IHIuaWRlYWw7XG4gICAgICAgICAgfVxuICAgICAgICAgIGMuYWR2YW5jZWQucHVzaChvYyk7XG4gICAgICAgICAgZGVsZXRlIHIuaWRlYWw7XG4gICAgICAgICAgaWYgKCFPYmplY3Qua2V5cyhyKS5sZW5ndGgpIHtcbiAgICAgICAgICAgIGRlbGV0ZSBjW2tleV07XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIGlmIChyZXF1aXJlLmxlbmd0aCkge1xuICAgICAgICBjLnJlcXVpcmUgPSByZXF1aXJlO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGM7XG4gICAgfTtcbiAgICBjb25zdHJhaW50cyA9IEpTT04ucGFyc2UoSlNPTi5zdHJpbmdpZnkoY29uc3RyYWludHMpKTtcbiAgICBpZiAoYnJvd3NlckRldGFpbHMudmVyc2lvbiA8IDM4KSB7XG4gICAgICBsb2dnaW5nKCdzcGVjOiAnICsgSlNPTi5zdHJpbmdpZnkoY29uc3RyYWludHMpKTtcbiAgICAgIGlmIChjb25zdHJhaW50cy5hdWRpbykge1xuICAgICAgICBjb25zdHJhaW50cy5hdWRpbyA9IGNvbnN0cmFpbnRzVG9GRjM3Xyhjb25zdHJhaW50cy5hdWRpbyk7XG4gICAgICB9XG4gICAgICBpZiAoY29uc3RyYWludHMudmlkZW8pIHtcbiAgICAgICAgY29uc3RyYWludHMudmlkZW8gPSBjb25zdHJhaW50c1RvRkYzN18oY29uc3RyYWludHMudmlkZW8pO1xuICAgICAgfVxuICAgICAgbG9nZ2luZygnZmYzNzogJyArIEpTT04uc3RyaW5naWZ5KGNvbnN0cmFpbnRzKSk7XG4gICAgfVxuICAgIHJldHVybiBuYXZpZ2F0b3IubW96R2V0VXNlck1lZGlhKGNvbnN0cmFpbnRzLCBvblN1Y2Nlc3MsIGZ1bmN0aW9uKGUpIHtcbiAgICAgIG9uRXJyb3Ioc2hpbUVycm9yXyhlKSk7XG4gICAgfSk7XG4gIH07XG5cbiAgLy8gUmV0dXJucyB0aGUgcmVzdWx0IG9mIGdldFVzZXJNZWRpYSBhcyBhIFByb21pc2UuXG4gIHZhciBnZXRVc2VyTWVkaWFQcm9taXNlXyA9IGZ1bmN0aW9uKGNvbnN0cmFpbnRzKSB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uKHJlc29sdmUsIHJlamVjdCkge1xuICAgICAgZ2V0VXNlck1lZGlhXyhjb25zdHJhaW50cywgcmVzb2x2ZSwgcmVqZWN0KTtcbiAgICB9KTtcbiAgfTtcblxuICAvLyBTaGltIGZvciBtZWRpYURldmljZXMgb24gb2xkZXIgdmVyc2lvbnMuXG4gIGlmICghbmF2aWdhdG9yLm1lZGlhRGV2aWNlcykge1xuICAgIG5hdmlnYXRvci5tZWRpYURldmljZXMgPSB7Z2V0VXNlck1lZGlhOiBnZXRVc2VyTWVkaWFQcm9taXNlXyxcbiAgICAgIGFkZEV2ZW50TGlzdGVuZXI6IGZ1bmN0aW9uKCkgeyB9LFxuICAgICAgcmVtb3ZlRXZlbnRMaXN0ZW5lcjogZnVuY3Rpb24oKSB7IH1cbiAgICB9O1xuICB9XG4gIG5hdmlnYXRvci5tZWRpYURldmljZXMuZW51bWVyYXRlRGV2aWNlcyA9XG4gICAgICBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmVudW1lcmF0ZURldmljZXMgfHwgZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbihyZXNvbHZlKSB7XG4gICAgICAgICAgdmFyIGluZm9zID0gW1xuICAgICAgICAgICAge2tpbmQ6ICdhdWRpb2lucHV0JywgZGV2aWNlSWQ6ICdkZWZhdWx0JywgbGFiZWw6ICcnLCBncm91cElkOiAnJ30sXG4gICAgICAgICAgICB7a2luZDogJ3ZpZGVvaW5wdXQnLCBkZXZpY2VJZDogJ2RlZmF1bHQnLCBsYWJlbDogJycsIGdyb3VwSWQ6ICcnfVxuICAgICAgICAgIF07XG4gICAgICAgICAgcmVzb2x2ZShpbmZvcyk7XG4gICAgICAgIH0pO1xuICAgICAgfTtcblxuICBpZiAoYnJvd3NlckRldGFpbHMudmVyc2lvbiA8IDQxKSB7XG4gICAgLy8gV29yayBhcm91bmQgaHR0cDovL2J1Z3ppbC5sYS8xMTY5NjY1XG4gICAgdmFyIG9yZ0VudW1lcmF0ZURldmljZXMgPVxuICAgICAgICBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmVudW1lcmF0ZURldmljZXMuYmluZChuYXZpZ2F0b3IubWVkaWFEZXZpY2VzKTtcbiAgICBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmVudW1lcmF0ZURldmljZXMgPSBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiBvcmdFbnVtZXJhdGVEZXZpY2VzKCkudGhlbih1bmRlZmluZWQsIGZ1bmN0aW9uKGUpIHtcbiAgICAgICAgaWYgKGUubmFtZSA9PT0gJ05vdEZvdW5kRXJyb3InKSB7XG4gICAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgICB9XG4gICAgICAgIHRocm93IGU7XG4gICAgICB9KTtcbiAgICB9O1xuICB9XG4gIGlmIChicm93c2VyRGV0YWlscy52ZXJzaW9uIDwgNDkpIHtcbiAgICB2YXIgb3JpZ0dldFVzZXJNZWRpYSA9IG5hdmlnYXRvci5tZWRpYURldmljZXMuZ2V0VXNlck1lZGlhLlxuICAgICAgICBiaW5kKG5hdmlnYXRvci5tZWRpYURldmljZXMpO1xuICAgIG5hdmlnYXRvci5tZWRpYURldmljZXMuZ2V0VXNlck1lZGlhID0gZnVuY3Rpb24oYykge1xuICAgICAgcmV0dXJuIG9yaWdHZXRVc2VyTWVkaWEoYykudGhlbihmdW5jdGlvbihzdHJlYW0pIHtcbiAgICAgICAgLy8gV29yayBhcm91bmQgaHR0cHM6Ly9idWd6aWwubGEvODAyMzI2XG4gICAgICAgIGlmIChjLmF1ZGlvICYmICFzdHJlYW0uZ2V0QXVkaW9UcmFja3MoKS5sZW5ndGggfHxcbiAgICAgICAgICAgIGMudmlkZW8gJiYgIXN0cmVhbS5nZXRWaWRlb1RyYWNrcygpLmxlbmd0aCkge1xuICAgICAgICAgIHN0cmVhbS5nZXRUcmFja3MoKS5mb3JFYWNoKGZ1bmN0aW9uKHRyYWNrKSB7XG4gICAgICAgICAgICB0cmFjay5zdG9wKCk7XG4gICAgICAgICAgfSk7XG4gICAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbignVGhlIG9iamVjdCBjYW4gbm90IGJlIGZvdW5kIGhlcmUuJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdOb3RGb3VuZEVycm9yJyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHN0cmVhbTtcbiAgICAgIH0sIGZ1bmN0aW9uKGUpIHtcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KHNoaW1FcnJvcl8oZSkpO1xuICAgICAgfSk7XG4gICAgfTtcbiAgfVxuICBuYXZpZ2F0b3IuZ2V0VXNlck1lZGlhID0gZnVuY3Rpb24oY29uc3RyYWludHMsIG9uU3VjY2Vzcywgb25FcnJvcikge1xuICAgIGlmIChicm93c2VyRGV0YWlscy52ZXJzaW9uIDwgNDQpIHtcbiAgICAgIHJldHVybiBnZXRVc2VyTWVkaWFfKGNvbnN0cmFpbnRzLCBvblN1Y2Nlc3MsIG9uRXJyb3IpO1xuICAgIH1cbiAgICAvLyBSZXBsYWNlIEZpcmVmb3ggNDQrJ3MgZGVwcmVjYXRpb24gd2FybmluZyB3aXRoIHVucHJlZml4ZWQgdmVyc2lvbi5cbiAgICBjb25zb2xlLndhcm4oJ25hdmlnYXRvci5nZXRVc2VyTWVkaWEgaGFzIGJlZW4gcmVwbGFjZWQgYnkgJyArXG4gICAgICAgICAgICAgICAgICduYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmdldFVzZXJNZWRpYScpO1xuICAgIG5hdmlnYXRvci5tZWRpYURldmljZXMuZ2V0VXNlck1lZGlhKGNvbnN0cmFpbnRzKS50aGVuKG9uU3VjY2Vzcywgb25FcnJvcik7XG4gIH07XG59O1xuIiwiLypcbiAqICBDb3B5cmlnaHQgKGMpIDIwMTYgVGhlIFdlYlJUQyBwcm9qZWN0IGF1dGhvcnMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKlxuICogIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2VcbiAqICB0aGF0IGNhbiBiZSBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlIGluIHRoZSByb290IG9mIHRoZSBzb3VyY2VcbiAqICB0cmVlLlxuICovXG4ndXNlIHN0cmljdCc7XG52YXIgc2FmYXJpU2hpbSA9IHtcbiAgLy8gVE9ETzogRHJBbGV4LCBzaG91bGQgYmUgaGVyZSwgZG91YmxlIGNoZWNrIGFnYWluc3QgTGF5b3V0VGVzdHNcblxuICAvLyBUT0RPOiBvbmNlIHRoZSBiYWNrLWVuZCBmb3IgdGhlIG1hYyBwb3J0IGlzIGRvbmUsIGFkZC5cbiAgLy8gVE9ETzogY2hlY2sgZm9yIHdlYmtpdEdUSytcbiAgLy8gc2hpbVBlZXJDb25uZWN0aW9uOiBmdW5jdGlvbigpIHsgfSxcblxuICBzaGltT25BZGRTdHJlYW06IGZ1bmN0aW9uKCkge1xuICAgIGlmICh0eXBlb2Ygd2luZG93ID09PSAnb2JqZWN0JyAmJiB3aW5kb3cuUlRDUGVlckNvbm5lY3Rpb24gJiZcbiAgICAgICAgISgnb25hZGRzdHJlYW0nIGluIHdpbmRvdy5SVENQZWVyQ29ubmVjdGlvbi5wcm90b3R5cGUpKSB7XG4gICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkod2luZG93LlJUQ1BlZXJDb25uZWN0aW9uLnByb3RvdHlwZSwgJ29uYWRkc3RyZWFtJywge1xuICAgICAgICBnZXQ6IGZ1bmN0aW9uKCkge1xuICAgICAgICAgIHJldHVybiB0aGlzLl9vbmFkZHN0cmVhbTtcbiAgICAgICAgfSxcbiAgICAgICAgc2V0OiBmdW5jdGlvbihmKSB7XG4gICAgICAgICAgaWYgKHRoaXMuX29uYWRkc3RyZWFtKSB7XG4gICAgICAgICAgICB0aGlzLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2FkZHN0cmVhbScsIHRoaXMuX29uYWRkc3RyZWFtKTtcbiAgICAgICAgICAgIHRoaXMucmVtb3ZlRXZlbnRMaXN0ZW5lcigndHJhY2snLCB0aGlzLl9vbmFkZHN0cmVhbXBvbHkpO1xuICAgICAgICAgIH1cbiAgICAgICAgICB0aGlzLmFkZEV2ZW50TGlzdGVuZXIoJ2FkZHN0cmVhbScsIHRoaXMuX29uYWRkc3RyZWFtID0gZik7XG4gICAgICAgICAgdGhpcy5hZGRFdmVudExpc3RlbmVyKCd0cmFjaycsIHRoaXMuX29uYWRkc3RyZWFtcG9seSA9IGZ1bmN0aW9uKGUpIHtcbiAgICAgICAgICAgIHZhciBzdHJlYW0gPSBlLnN0cmVhbXNbMF07XG4gICAgICAgICAgICBpZiAoIXRoaXMuX3N0cmVhbXMpIHtcbiAgICAgICAgICAgICAgdGhpcy5fc3RyZWFtcyA9IFtdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHRoaXMuX3N0cmVhbXMuaW5kZXhPZihzdHJlYW0pID49IDApIHtcbiAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5fc3RyZWFtcy5wdXNoKHN0cmVhbSk7XG4gICAgICAgICAgICB2YXIgZXZlbnQgPSBuZXcgRXZlbnQoJ2FkZHN0cmVhbScpO1xuICAgICAgICAgICAgZXZlbnQuc3RyZWFtID0gZS5zdHJlYW1zWzBdO1xuICAgICAgICAgICAgdGhpcy5kaXNwYXRjaEV2ZW50KGV2ZW50KTtcbiAgICAgICAgICB9LmJpbmQodGhpcykpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG4gIH0sXG5cbiAgc2hpbUdldFVzZXJNZWRpYTogZnVuY3Rpb24oKSB7XG4gICAgaWYgKCFuYXZpZ2F0b3IuZ2V0VXNlck1lZGlhKSB7XG4gICAgICBpZiAobmF2aWdhdG9yLndlYmtpdEdldFVzZXJNZWRpYSkge1xuICAgICAgICBuYXZpZ2F0b3IuZ2V0VXNlck1lZGlhID0gbmF2aWdhdG9yLndlYmtpdEdldFVzZXJNZWRpYS5iaW5kKG5hdmlnYXRvcik7XG4gICAgICB9IGVsc2UgaWYgKG5hdmlnYXRvci5tZWRpYURldmljZXMgJiZcbiAgICAgICAgICBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmdldFVzZXJNZWRpYSkge1xuICAgICAgICBuYXZpZ2F0b3IuZ2V0VXNlck1lZGlhID0gZnVuY3Rpb24oY29uc3RyYWludHMsIGNiLCBlcnJjYikge1xuICAgICAgICAgIG5hdmlnYXRvci5tZWRpYURldmljZXMuZ2V0VXNlck1lZGlhKGNvbnN0cmFpbnRzKVxuICAgICAgICAgIC50aGVuKGNiLCBlcnJjYik7XG4gICAgICAgIH0uYmluZChuYXZpZ2F0b3IpO1xuICAgICAgfVxuICAgIH1cbiAgfVxufTtcblxuLy8gRXhwb3NlIHB1YmxpYyBtZXRob2RzLlxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIHNoaW1PbkFkZFN0cmVhbTogc2FmYXJpU2hpbS5zaGltT25BZGRTdHJlYW0sXG4gIHNoaW1HZXRVc2VyTWVkaWE6IHNhZmFyaVNoaW0uc2hpbUdldFVzZXJNZWRpYVxuICAvLyBUT0RPXG4gIC8vIHNoaW1QZWVyQ29ubmVjdGlvbjogc2FmYXJpU2hpbS5zaGltUGVlckNvbm5lY3Rpb25cbn07XG4iLCIvKlxuICogIENvcHlyaWdodCAoYykgMjAxNiBUaGUgV2ViUlRDIHByb2plY3QgYXV0aG9ycy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqXG4gKiAgVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZVxuICogIHRoYXQgY2FuIGJlIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgaW4gdGhlIHJvb3Qgb2YgdGhlIHNvdXJjZVxuICogIHRyZWUuXG4gKi9cbiAvKiBlc2xpbnQtZW52IG5vZGUgKi9cbid1c2Ugc3RyaWN0JztcblxudmFyIGxvZ0Rpc2FibGVkXyA9IHRydWU7XG5cbi8vIFV0aWxpdHkgbWV0aG9kcy5cbnZhciB1dGlscyA9IHtcbiAgZGlzYWJsZUxvZzogZnVuY3Rpb24oYm9vbCkge1xuICAgIGlmICh0eXBlb2YgYm9vbCAhPT0gJ2Jvb2xlYW4nKSB7XG4gICAgICByZXR1cm4gbmV3IEVycm9yKCdBcmd1bWVudCB0eXBlOiAnICsgdHlwZW9mIGJvb2wgK1xuICAgICAgICAgICcuIFBsZWFzZSB1c2UgYSBib29sZWFuLicpO1xuICAgIH1cbiAgICBsb2dEaXNhYmxlZF8gPSBib29sO1xuICAgIHJldHVybiAoYm9vbCkgPyAnYWRhcHRlci5qcyBsb2dnaW5nIGRpc2FibGVkJyA6XG4gICAgICAgICdhZGFwdGVyLmpzIGxvZ2dpbmcgZW5hYmxlZCc7XG4gIH0sXG5cbiAgbG9nOiBmdW5jdGlvbigpIHtcbiAgICBpZiAodHlwZW9mIHdpbmRvdyA9PT0gJ29iamVjdCcpIHtcbiAgICAgIGlmIChsb2dEaXNhYmxlZF8pIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgaWYgKHR5cGVvZiBjb25zb2xlICE9PSAndW5kZWZpbmVkJyAmJiB0eXBlb2YgY29uc29sZS5sb2cgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgY29uc29sZS5sb2cuYXBwbHkoY29uc29sZSwgYXJndW1lbnRzKTtcbiAgICAgIH1cbiAgICB9XG4gIH0sXG5cbiAgLyoqXG4gICAqIEV4dHJhY3QgYnJvd3NlciB2ZXJzaW9uIG91dCBvZiB0aGUgcHJvdmlkZWQgdXNlciBhZ2VudCBzdHJpbmcuXG4gICAqXG4gICAqIEBwYXJhbSB7IXN0cmluZ30gdWFzdHJpbmcgdXNlckFnZW50IHN0cmluZy5cbiAgICogQHBhcmFtIHshc3RyaW5nfSBleHByIFJlZ3VsYXIgZXhwcmVzc2lvbiB1c2VkIGFzIG1hdGNoIGNyaXRlcmlhLlxuICAgKiBAcGFyYW0geyFudW1iZXJ9IHBvcyBwb3NpdGlvbiBpbiB0aGUgdmVyc2lvbiBzdHJpbmcgdG8gYmUgcmV0dXJuZWQuXG4gICAqIEByZXR1cm4geyFudW1iZXJ9IGJyb3dzZXIgdmVyc2lvbi5cbiAgICovXG4gIGV4dHJhY3RWZXJzaW9uOiBmdW5jdGlvbih1YXN0cmluZywgZXhwciwgcG9zKSB7XG4gICAgdmFyIG1hdGNoID0gdWFzdHJpbmcubWF0Y2goZXhwcik7XG4gICAgcmV0dXJuIG1hdGNoICYmIG1hdGNoLmxlbmd0aCA+PSBwb3MgJiYgcGFyc2VJbnQobWF0Y2hbcG9zXSwgMTApO1xuICB9LFxuXG4gIC8qKlxuICAgKiBCcm93c2VyIGRldGVjdG9yLlxuICAgKlxuICAgKiBAcmV0dXJuIHtvYmplY3R9IHJlc3VsdCBjb250YWluaW5nIGJyb3dzZXIgYW5kIHZlcnNpb25cbiAgICogICAgIHByb3BlcnRpZXMuXG4gICAqL1xuICBkZXRlY3RCcm93c2VyOiBmdW5jdGlvbigpIHtcbiAgICAvLyBSZXR1cm5lZCByZXN1bHQgb2JqZWN0LlxuICAgIHZhciByZXN1bHQgPSB7fTtcbiAgICByZXN1bHQuYnJvd3NlciA9IG51bGw7XG4gICAgcmVzdWx0LnZlcnNpb24gPSBudWxsO1xuXG4gICAgLy8gRmFpbCBlYXJseSBpZiBpdCdzIG5vdCBhIGJyb3dzZXJcbiAgICBpZiAodHlwZW9mIHdpbmRvdyA9PT0gJ3VuZGVmaW5lZCcgfHwgIXdpbmRvdy5uYXZpZ2F0b3IpIHtcbiAgICAgIHJlc3VsdC5icm93c2VyID0gJ05vdCBhIGJyb3dzZXIuJztcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLy8gRmlyZWZveC5cbiAgICBpZiAobmF2aWdhdG9yLm1vekdldFVzZXJNZWRpYSkge1xuICAgICAgcmVzdWx0LmJyb3dzZXIgPSAnZmlyZWZveCc7XG4gICAgICByZXN1bHQudmVyc2lvbiA9IHRoaXMuZXh0cmFjdFZlcnNpb24obmF2aWdhdG9yLnVzZXJBZ2VudCxcbiAgICAgICAgICAvRmlyZWZveFxcLyhcXGQrKVxcLi8sIDEpO1xuICAgIH0gZWxzZSBpZiAobmF2aWdhdG9yLndlYmtpdEdldFVzZXJNZWRpYSkge1xuICAgICAgLy8gQ2hyb21lLCBDaHJvbWl1bSwgV2VidmlldywgT3BlcmEsIGFsbCB1c2UgdGhlIGNocm9tZSBzaGltIGZvciBub3dcbiAgICAgIGlmICh3aW5kb3cud2Via2l0UlRDUGVlckNvbm5lY3Rpb24pIHtcbiAgICAgICAgcmVzdWx0LmJyb3dzZXIgPSAnY2hyb21lJztcbiAgICAgICAgcmVzdWx0LnZlcnNpb24gPSB0aGlzLmV4dHJhY3RWZXJzaW9uKG5hdmlnYXRvci51c2VyQWdlbnQsXG4gICAgICAgICAgL0Nocm9tKGV8aXVtKVxcLyhcXGQrKVxcLi8sIDIpO1xuICAgICAgfSBlbHNlIHsgLy8gU2FmYXJpIChpbiBhbiB1bnB1Ymxpc2hlZCB2ZXJzaW9uKSBvciB1bmtub3duIHdlYmtpdC1iYXNlZC5cbiAgICAgICAgaWYgKG5hdmlnYXRvci51c2VyQWdlbnQubWF0Y2goL1ZlcnNpb25cXC8oXFxkKykuKFxcZCspLykpIHtcbiAgICAgICAgICByZXN1bHQuYnJvd3NlciA9ICdzYWZhcmknO1xuICAgICAgICAgIHJlc3VsdC52ZXJzaW9uID0gdGhpcy5leHRyYWN0VmVyc2lvbihuYXZpZ2F0b3IudXNlckFnZW50LFxuICAgICAgICAgICAgL0FwcGxlV2ViS2l0XFwvKFxcZCspXFwuLywgMSk7XG4gICAgICAgIH0gZWxzZSB7IC8vIHVua25vd24gd2Via2l0LWJhc2VkIGJyb3dzZXIuXG4gICAgICAgICAgcmVzdWx0LmJyb3dzZXIgPSAnVW5zdXBwb3J0ZWQgd2Via2l0LWJhc2VkIGJyb3dzZXIgJyArXG4gICAgICAgICAgICAgICd3aXRoIEdVTSBzdXBwb3J0IGJ1dCBubyBXZWJSVEMgc3VwcG9ydC4nO1xuICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKG5hdmlnYXRvci5tZWRpYURldmljZXMgJiZcbiAgICAgICAgbmF2aWdhdG9yLnVzZXJBZ2VudC5tYXRjaCgvRWRnZVxcLyhcXGQrKS4oXFxkKykkLykpIHsgLy8gRWRnZS5cbiAgICAgIHJlc3VsdC5icm93c2VyID0gJ2VkZ2UnO1xuICAgICAgcmVzdWx0LnZlcnNpb24gPSB0aGlzLmV4dHJhY3RWZXJzaW9uKG5hdmlnYXRvci51c2VyQWdlbnQsXG4gICAgICAgICAgL0VkZ2VcXC8oXFxkKykuKFxcZCspJC8sIDIpO1xuICAgIH0gZWxzZSBpZiAobmF2aWdhdG9yLm1lZGlhRGV2aWNlcyAmJlxuICAgICAgICBuYXZpZ2F0b3IudXNlckFnZW50Lm1hdGNoKC9BcHBsZVdlYktpdFxcLyhcXGQrKVxcLi8pKSB7XG4gICAgICAgIC8vIFNhZmFyaSwgd2l0aCB3ZWJraXRHZXRVc2VyTWVkaWEgcmVtb3ZlZC5cbiAgICAgIHJlc3VsdC5icm93c2VyID0gJ3NhZmFyaSc7XG4gICAgICByZXN1bHQudmVyc2lvbiA9IHRoaXMuZXh0cmFjdFZlcnNpb24obmF2aWdhdG9yLnVzZXJBZ2VudCxcbiAgICAgICAgICAvQXBwbGVXZWJLaXRcXC8oXFxkKylcXC4vLCAxKTtcbiAgICB9IGVsc2UgeyAvLyBEZWZhdWx0IGZhbGx0aHJvdWdoOiBub3Qgc3VwcG9ydGVkLlxuICAgICAgcmVzdWx0LmJyb3dzZXIgPSAnTm90IGEgc3VwcG9ydGVkIGJyb3dzZXIuJztcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfSxcblxuICAvLyBzaGltQ3JlYXRlT2JqZWN0VVJMIG11c3QgYmUgY2FsbGVkIGJlZm9yZSBzaGltU291cmNlT2JqZWN0IHRvIGF2b2lkIGxvb3AuXG5cbiAgc2hpbUNyZWF0ZU9iamVjdFVSTDogZnVuY3Rpb24oKSB7XG4gICAgaWYgKCEodHlwZW9mIHdpbmRvdyA9PT0gJ29iamVjdCcgJiYgd2luZG93LkhUTUxNZWRpYUVsZW1lbnQgJiZcbiAgICAgICAgICAnc3JjT2JqZWN0JyBpbiB3aW5kb3cuSFRNTE1lZGlhRWxlbWVudC5wcm90b3R5cGUpKSB7XG4gICAgICAvLyBPbmx5IHNoaW0gQ3JlYXRlT2JqZWN0VVJMIHVzaW5nIHNyY09iamVjdCBpZiBzcmNPYmplY3QgZXhpc3RzLlxuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICB2YXIgbmF0aXZlQ3JlYXRlT2JqZWN0VVJMID0gVVJMLmNyZWF0ZU9iamVjdFVSTC5iaW5kKFVSTCk7XG4gICAgdmFyIG5hdGl2ZVJldm9rZU9iamVjdFVSTCA9IFVSTC5yZXZva2VPYmplY3RVUkwuYmluZChVUkwpO1xuICAgIHZhciBzdHJlYW1zID0gbmV3IE1hcCgpLCBuZXdJZCA9IDA7XG5cbiAgICBVUkwuY3JlYXRlT2JqZWN0VVJMID0gZnVuY3Rpb24oc3RyZWFtKSB7XG4gICAgICBpZiAoJ2dldFRyYWNrcycgaW4gc3RyZWFtKSB7XG4gICAgICAgIHZhciB1cmwgPSAncG9seWJsb2I6JyArICgrK25ld0lkKTtcbiAgICAgICAgc3RyZWFtcy5zZXQodXJsLCBzdHJlYW0pO1xuICAgICAgICBjb25zb2xlLmxvZygnVVJMLmNyZWF0ZU9iamVjdFVSTChzdHJlYW0pIGlzIGRlcHJlY2F0ZWQhICcgK1xuICAgICAgICAgICAgICAgICAgICAnVXNlIGVsZW0uc3JjT2JqZWN0ID0gc3RyZWFtIGluc3RlYWQhJyk7XG4gICAgICAgIHJldHVybiB1cmw7XG4gICAgICB9XG4gICAgICByZXR1cm4gbmF0aXZlQ3JlYXRlT2JqZWN0VVJMKHN0cmVhbSk7XG4gICAgfTtcbiAgICBVUkwucmV2b2tlT2JqZWN0VVJMID0gZnVuY3Rpb24odXJsKSB7XG4gICAgICBuYXRpdmVSZXZva2VPYmplY3RVUkwodXJsKTtcbiAgICAgIHN0cmVhbXMuZGVsZXRlKHVybCk7XG4gICAgfTtcblxuICAgIHZhciBkc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKHdpbmRvdy5IVE1MTWVkaWFFbGVtZW50LnByb3RvdHlwZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnc3JjJyk7XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHdpbmRvdy5IVE1MTWVkaWFFbGVtZW50LnByb3RvdHlwZSwgJ3NyYycsIHtcbiAgICAgIGdldDogZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiBkc2MuZ2V0LmFwcGx5KHRoaXMpO1xuICAgICAgfSxcbiAgICAgIHNldDogZnVuY3Rpb24odXJsKSB7XG4gICAgICAgIHRoaXMuc3JjT2JqZWN0ID0gc3RyZWFtcy5nZXQodXJsKSB8fCBudWxsO1xuICAgICAgICByZXR1cm4gZHNjLnNldC5hcHBseSh0aGlzLCBbdXJsXSk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICB2YXIgbmF0aXZlU2V0QXR0cmlidXRlID0gSFRNTE1lZGlhRWxlbWVudC5wcm90b3R5cGUuc2V0QXR0cmlidXRlO1xuICAgIEhUTUxNZWRpYUVsZW1lbnQucHJvdG90eXBlLnNldEF0dHJpYnV0ZSA9IGZ1bmN0aW9uKCkge1xuICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDIgJiZcbiAgICAgICAgICAoJycgKyBhcmd1bWVudHNbMF0pLnRvTG93ZXJDYXNlKCkgPT09ICdzcmMnKSB7XG4gICAgICAgIHRoaXMuc3JjT2JqZWN0ID0gc3RyZWFtcy5nZXQoYXJndW1lbnRzWzFdKSB8fCBudWxsO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG5hdGl2ZVNldEF0dHJpYnV0ZS5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIH07XG4gIH1cbn07XG5cbi8vIEV4cG9ydC5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBsb2c6IHV0aWxzLmxvZyxcbiAgZGlzYWJsZUxvZzogdXRpbHMuZGlzYWJsZUxvZyxcbiAgYnJvd3NlckRldGFpbHM6IHV0aWxzLmRldGVjdEJyb3dzZXIoKSxcbiAgZXh0cmFjdFZlcnNpb246IHV0aWxzLmV4dHJhY3RWZXJzaW9uLFxuICBzaGltQ3JlYXRlT2JqZWN0VVJMOiB1dGlscy5zaGltQ3JlYXRlT2JqZWN0VVJMLFxuICBkZXRlY3RCcm93c2VyOiB1dGlscy5kZXRlY3RCcm93c2VyLmJpbmQodXRpbHMpXG59O1xuIiwiLypcclxuV2lsZEVtaXR0ZXIuanMgaXMgYSBzbGltIGxpdHRsZSBldmVudCBlbWl0dGVyIGJ5IEBoZW5yaWtqb3JldGVnIGxhcmdlbHkgYmFzZWRcclxub24gQHZpc2lvbm1lZGlhJ3MgRW1pdHRlciBmcm9tIFVJIEtpdC5cclxuXHJcbldoeT8gSSB3YW50ZWQgaXQgc3RhbmRhbG9uZS5cclxuXHJcbkkgYWxzbyB3YW50ZWQgc3VwcG9ydCBmb3Igd2lsZGNhcmQgZW1pdHRlcnMgbGlrZSB0aGlzOlxyXG5cclxuZW1pdHRlci5vbignKicsIGZ1bmN0aW9uIChldmVudE5hbWUsIG90aGVyLCBldmVudCwgcGF5bG9hZHMpIHtcclxuXHJcbn0pO1xyXG5cclxuZW1pdHRlci5vbignc29tZW5hbWVzcGFjZSonLCBmdW5jdGlvbiAoZXZlbnROYW1lLCBwYXlsb2Fkcykge1xyXG5cclxufSk7XHJcblxyXG5QbGVhc2Ugbm90ZSB0aGF0IGNhbGxiYWNrcyB0cmlnZ2VyZWQgYnkgd2lsZGNhcmQgcmVnaXN0ZXJlZCBldmVudHMgYWxzbyBnZXRcclxudGhlIGV2ZW50IG5hbWUgYXMgdGhlIGZpcnN0IGFyZ3VtZW50LlxyXG4qL1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBXaWxkRW1pdHRlcjtcclxuXHJcbmZ1bmN0aW9uIFdpbGRFbWl0dGVyKCkgeyB9XHJcblxyXG5XaWxkRW1pdHRlci5taXhpbiA9IGZ1bmN0aW9uIChjb25zdHJ1Y3Rvcikge1xyXG4gICAgdmFyIHByb3RvdHlwZSA9IGNvbnN0cnVjdG9yLnByb3RvdHlwZSB8fCBjb25zdHJ1Y3RvcjtcclxuXHJcbiAgICBwcm90b3R5cGUuaXNXaWxkRW1pdHRlcj0gdHJ1ZTtcclxuXHJcbiAgICAvLyBMaXN0ZW4gb24gdGhlIGdpdmVuIGBldmVudGAgd2l0aCBgZm5gLiBTdG9yZSBhIGdyb3VwIG5hbWUgaWYgcHJlc2VudC5cclxuICAgIHByb3RvdHlwZS5vbiA9IGZ1bmN0aW9uIChldmVudCwgZ3JvdXBOYW1lLCBmbikge1xyXG4gICAgICAgIHRoaXMuY2FsbGJhY2tzID0gdGhpcy5jYWxsYmFja3MgfHwge307XHJcbiAgICAgICAgdmFyIGhhc0dyb3VwID0gKGFyZ3VtZW50cy5sZW5ndGggPT09IDMpLFxyXG4gICAgICAgICAgICBncm91cCA9IGhhc0dyb3VwID8gYXJndW1lbnRzWzFdIDogdW5kZWZpbmVkLFxyXG4gICAgICAgICAgICBmdW5jID0gaGFzR3JvdXAgPyBhcmd1bWVudHNbMl0gOiBhcmd1bWVudHNbMV07XHJcbiAgICAgICAgZnVuYy5fZ3JvdXBOYW1lID0gZ3JvdXA7XHJcbiAgICAgICAgKHRoaXMuY2FsbGJhY2tzW2V2ZW50XSA9IHRoaXMuY2FsbGJhY2tzW2V2ZW50XSB8fCBbXSkucHVzaChmdW5jKTtcclxuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH07XHJcblxyXG4gICAgLy8gQWRkcyBhbiBgZXZlbnRgIGxpc3RlbmVyIHRoYXQgd2lsbCBiZSBpbnZva2VkIGEgc2luZ2xlXHJcbiAgICAvLyB0aW1lIHRoZW4gYXV0b21hdGljYWxseSByZW1vdmVkLlxyXG4gICAgcHJvdG90eXBlLm9uY2UgPSBmdW5jdGlvbiAoZXZlbnQsIGdyb3VwTmFtZSwgZm4pIHtcclxuICAgICAgICB2YXIgc2VsZiA9IHRoaXMsXHJcbiAgICAgICAgICAgIGhhc0dyb3VwID0gKGFyZ3VtZW50cy5sZW5ndGggPT09IDMpLFxyXG4gICAgICAgICAgICBncm91cCA9IGhhc0dyb3VwID8gYXJndW1lbnRzWzFdIDogdW5kZWZpbmVkLFxyXG4gICAgICAgICAgICBmdW5jID0gaGFzR3JvdXAgPyBhcmd1bWVudHNbMl0gOiBhcmd1bWVudHNbMV07XHJcbiAgICAgICAgZnVuY3Rpb24gb24oKSB7XHJcbiAgICAgICAgICAgIHNlbGYub2ZmKGV2ZW50LCBvbik7XHJcbiAgICAgICAgICAgIGZ1bmMuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy5vbihldmVudCwgZ3JvdXAsIG9uKTtcclxuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH07XHJcblxyXG4gICAgLy8gVW5iaW5kcyBhbiBlbnRpcmUgZ3JvdXBcclxuICAgIHByb3RvdHlwZS5yZWxlYXNlR3JvdXAgPSBmdW5jdGlvbiAoZ3JvdXBOYW1lKSB7XHJcbiAgICAgICAgdGhpcy5jYWxsYmFja3MgPSB0aGlzLmNhbGxiYWNrcyB8fCB7fTtcclxuICAgICAgICB2YXIgaXRlbSwgaSwgbGVuLCBoYW5kbGVycztcclxuICAgICAgICBmb3IgKGl0ZW0gaW4gdGhpcy5jYWxsYmFja3MpIHtcclxuICAgICAgICAgICAgaGFuZGxlcnMgPSB0aGlzLmNhbGxiYWNrc1tpdGVtXTtcclxuICAgICAgICAgICAgZm9yIChpID0gMCwgbGVuID0gaGFuZGxlcnMubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcclxuICAgICAgICAgICAgICAgIGlmIChoYW5kbGVyc1tpXS5fZ3JvdXBOYW1lID09PSBncm91cE5hbWUpIHtcclxuICAgICAgICAgICAgICAgICAgICAvL2NvbnNvbGUubG9nKCdyZW1vdmluZycpO1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIHJlbW92ZSBpdCBhbmQgc2hvcnRlbiB0aGUgYXJyYXkgd2UncmUgbG9vcGluZyB0aHJvdWdoXHJcbiAgICAgICAgICAgICAgICAgICAgaGFuZGxlcnMuc3BsaWNlKGksIDEpO1xyXG4gICAgICAgICAgICAgICAgICAgIGktLTtcclxuICAgICAgICAgICAgICAgICAgICBsZW4tLTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH07XHJcblxyXG4gICAgLy8gUmVtb3ZlIHRoZSBnaXZlbiBjYWxsYmFjayBmb3IgYGV2ZW50YCBvciBhbGxcclxuICAgIC8vIHJlZ2lzdGVyZWQgY2FsbGJhY2tzLlxyXG4gICAgcHJvdG90eXBlLm9mZiA9IGZ1bmN0aW9uIChldmVudCwgZm4pIHtcclxuICAgICAgICB0aGlzLmNhbGxiYWNrcyA9IHRoaXMuY2FsbGJhY2tzIHx8IHt9O1xyXG4gICAgICAgIHZhciBjYWxsYmFja3MgPSB0aGlzLmNhbGxiYWNrc1tldmVudF0sXHJcbiAgICAgICAgICAgIGk7XHJcblxyXG4gICAgICAgIGlmICghY2FsbGJhY2tzKSByZXR1cm4gdGhpcztcclxuXHJcbiAgICAgICAgLy8gcmVtb3ZlIGFsbCBoYW5kbGVyc1xyXG4gICAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAxKSB7XHJcbiAgICAgICAgICAgIGRlbGV0ZSB0aGlzLmNhbGxiYWNrc1tldmVudF07XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gcmVtb3ZlIHNwZWNpZmljIGhhbmRsZXJcclxuICAgICAgICBpID0gY2FsbGJhY2tzLmluZGV4T2YoZm4pO1xyXG4gICAgICAgIGNhbGxiYWNrcy5zcGxpY2UoaSwgMSk7XHJcbiAgICAgICAgaWYgKGNhbGxiYWNrcy5sZW5ndGggPT09IDApIHtcclxuICAgICAgICAgICAgZGVsZXRlIHRoaXMuY2FsbGJhY2tzW2V2ZW50XTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICB9O1xyXG5cclxuICAgIC8vLyBFbWl0IGBldmVudGAgd2l0aCB0aGUgZ2l2ZW4gYXJncy5cclxuICAgIC8vIGFsc28gY2FsbHMgYW55IGAqYCBoYW5kbGVyc1xyXG4gICAgcHJvdG90eXBlLmVtaXQgPSBmdW5jdGlvbiAoZXZlbnQpIHtcclxuICAgICAgICB0aGlzLmNhbGxiYWNrcyA9IHRoaXMuY2FsbGJhY2tzIHx8IHt9O1xyXG4gICAgICAgIHZhciBhcmdzID0gW10uc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpLFxyXG4gICAgICAgICAgICBjYWxsYmFja3MgPSB0aGlzLmNhbGxiYWNrc1tldmVudF0sXHJcbiAgICAgICAgICAgIHNwZWNpYWxDYWxsYmFja3MgPSB0aGlzLmdldFdpbGRjYXJkQ2FsbGJhY2tzKGV2ZW50KSxcclxuICAgICAgICAgICAgaSxcclxuICAgICAgICAgICAgbGVuLFxyXG4gICAgICAgICAgICBpdGVtLFxyXG4gICAgICAgICAgICBsaXN0ZW5lcnM7XHJcblxyXG4gICAgICAgIGlmIChjYWxsYmFja3MpIHtcclxuICAgICAgICAgICAgbGlzdGVuZXJzID0gY2FsbGJhY2tzLnNsaWNlKCk7XHJcbiAgICAgICAgICAgIGZvciAoaSA9IDAsIGxlbiA9IGxpc3RlbmVycy5sZW5ndGg7IGkgPCBsZW47ICsraSkge1xyXG4gICAgICAgICAgICAgICAgaWYgKCFsaXN0ZW5lcnNbaV0pIHtcclxuICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGxpc3RlbmVyc1tpXS5hcHBseSh0aGlzLCBhcmdzKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKHNwZWNpYWxDYWxsYmFja3MpIHtcclxuICAgICAgICAgICAgbGVuID0gc3BlY2lhbENhbGxiYWNrcy5sZW5ndGg7XHJcbiAgICAgICAgICAgIGxpc3RlbmVycyA9IHNwZWNpYWxDYWxsYmFja3Muc2xpY2UoKTtcclxuICAgICAgICAgICAgZm9yIChpID0gMCwgbGVuID0gbGlzdGVuZXJzLmxlbmd0aDsgaSA8IGxlbjsgKytpKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoIWxpc3RlbmVyc1tpXSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgbGlzdGVuZXJzW2ldLmFwcGx5KHRoaXMsIFtldmVudF0uY29uY2F0KGFyZ3MpKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICB9O1xyXG5cclxuICAgIC8vIEhlbHBlciBmb3IgZm9yIGZpbmRpbmcgc3BlY2lhbCB3aWxkY2FyZCBldmVudCBoYW5kbGVycyB0aGF0IG1hdGNoIHRoZSBldmVudFxyXG4gICAgcHJvdG90eXBlLmdldFdpbGRjYXJkQ2FsbGJhY2tzID0gZnVuY3Rpb24gKGV2ZW50TmFtZSkge1xyXG4gICAgICAgIHRoaXMuY2FsbGJhY2tzID0gdGhpcy5jYWxsYmFja3MgfHwge307XHJcbiAgICAgICAgdmFyIGl0ZW0sXHJcbiAgICAgICAgICAgIHNwbGl0LFxyXG4gICAgICAgICAgICByZXN1bHQgPSBbXTtcclxuXHJcbiAgICAgICAgZm9yIChpdGVtIGluIHRoaXMuY2FsbGJhY2tzKSB7XHJcbiAgICAgICAgICAgIHNwbGl0ID0gaXRlbS5zcGxpdCgnKicpO1xyXG4gICAgICAgICAgICBpZiAoaXRlbSA9PT0gJyonIHx8IChzcGxpdC5sZW5ndGggPT09IDIgJiYgZXZlbnROYW1lLnNsaWNlKDAsIHNwbGl0WzBdLmxlbmd0aCkgPT09IHNwbGl0WzBdKSkge1xyXG4gICAgICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0LmNvbmNhdCh0aGlzLmNhbGxiYWNrc1tpdGVtXSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcclxuICAgIH07XHJcblxyXG59O1xyXG5cclxuV2lsZEVtaXR0ZXIubWl4aW4oV2lsZEVtaXR0ZXIpO1xyXG4iLCIvKiFcbiAqIEV2ZW50RW1pdHRlciB2NC4yLjkgLSBnaXQuaW8vZWVcbiAqIE9saXZlciBDYWxkd2VsbFxuICogTUlUIGxpY2Vuc2VcbiAqIEBwcmVzZXJ2ZVxuICovXG5cbihmdW5jdGlvbiAoKSB7XG4gICAgJ3VzZSBzdHJpY3QnO1xuXG4gICAgLyoqXG4gICAgICogQ2xhc3MgZm9yIG1hbmFnaW5nIGV2ZW50cy5cbiAgICAgKiBDYW4gYmUgZXh0ZW5kZWQgdG8gcHJvdmlkZSBldmVudCBmdW5jdGlvbmFsaXR5IGluIG90aGVyIGNsYXNzZXMuXG4gICAgICpcbiAgICAgKiBAY2xhc3MgRXZlbnRFbWl0dGVyIE1hbmFnZXMgZXZlbnQgcmVnaXN0ZXJpbmcgYW5kIGVtaXR0aW5nLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIEV2ZW50RW1pdHRlcigpIHt9XG5cbiAgICAvLyBTaG9ydGN1dHMgdG8gaW1wcm92ZSBzcGVlZCBhbmQgc2l6ZVxuICAgIHZhciBwcm90byA9IEV2ZW50RW1pdHRlci5wcm90b3R5cGU7XG4gICAgdmFyIGV4cG9ydHMgPSB0aGlzO1xuICAgIHZhciBvcmlnaW5hbEdsb2JhbFZhbHVlID0gZXhwb3J0cy5FdmVudEVtaXR0ZXI7XG5cbiAgICAvKipcbiAgICAgKiBGaW5kcyB0aGUgaW5kZXggb2YgdGhlIGxpc3RlbmVyIGZvciB0aGUgZXZlbnQgaW4gaXRzIHN0b3JhZ2UgYXJyYXkuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9uW119IGxpc3RlbmVycyBBcnJheSBvZiBsaXN0ZW5lcnMgdG8gc2VhcmNoIHRocm91Z2guXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gbGlzdGVuZXIgTWV0aG9kIHRvIGxvb2sgZm9yLlxuICAgICAqIEByZXR1cm4ge051bWJlcn0gSW5kZXggb2YgdGhlIHNwZWNpZmllZCBsaXN0ZW5lciwgLTEgaWYgbm90IGZvdW5kXG4gICAgICogQGFwaSBwcml2YXRlXG4gICAgICovXG4gICAgZnVuY3Rpb24gaW5kZXhPZkxpc3RlbmVyKGxpc3RlbmVycywgbGlzdGVuZXIpIHtcbiAgICAgICAgdmFyIGkgPSBsaXN0ZW5lcnMubGVuZ3RoO1xuICAgICAgICB3aGlsZSAoaS0tKSB7XG4gICAgICAgICAgICBpZiAobGlzdGVuZXJzW2ldLmxpc3RlbmVyID09PSBsaXN0ZW5lcikge1xuICAgICAgICAgICAgICAgIHJldHVybiBpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIC0xO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEFsaWFzIGEgbWV0aG9kIHdoaWxlIGtlZXBpbmcgdGhlIGNvbnRleHQgY29ycmVjdCwgdG8gYWxsb3cgZm9yIG92ZXJ3cml0aW5nIG9mIHRhcmdldCBtZXRob2QuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gbmFtZSBUaGUgbmFtZSBvZiB0aGUgdGFyZ2V0IG1ldGhvZC5cbiAgICAgKiBAcmV0dXJuIHtGdW5jdGlvbn0gVGhlIGFsaWFzZWQgbWV0aG9kXG4gICAgICogQGFwaSBwcml2YXRlXG4gICAgICovXG4gICAgZnVuY3Rpb24gYWxpYXMobmFtZSkge1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24gYWxpYXNDbG9zdXJlKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXNbbmFtZV0uYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBsaXN0ZW5lciBhcnJheSBmb3IgdGhlIHNwZWNpZmllZCBldmVudC5cbiAgICAgKiBXaWxsIGluaXRpYWxpc2UgdGhlIGV2ZW50IG9iamVjdCBhbmQgbGlzdGVuZXIgYXJyYXlzIGlmIHJlcXVpcmVkLlxuICAgICAqIFdpbGwgcmV0dXJuIGFuIG9iamVjdCBpZiB5b3UgdXNlIGEgcmVnZXggc2VhcmNoLiBUaGUgb2JqZWN0IGNvbnRhaW5zIGtleXMgZm9yIGVhY2ggbWF0Y2hlZCBldmVudC4gU28gL2JhW3J6XS8gbWlnaHQgcmV0dXJuIGFuIG9iamVjdCBjb250YWluaW5nIGJhciBhbmQgYmF6LiBCdXQgb25seSBpZiB5b3UgaGF2ZSBlaXRoZXIgZGVmaW5lZCB0aGVtIHdpdGggZGVmaW5lRXZlbnQgb3IgYWRkZWQgc29tZSBsaXN0ZW5lcnMgdG8gdGhlbS5cbiAgICAgKiBFYWNoIHByb3BlcnR5IGluIHRoZSBvYmplY3QgcmVzcG9uc2UgaXMgYW4gYXJyYXkgb2YgbGlzdGVuZXIgZnVuY3Rpb25zLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtTdHJpbmd8UmVnRXhwfSBldnQgTmFtZSBvZiB0aGUgZXZlbnQgdG8gcmV0dXJuIHRoZSBsaXN0ZW5lcnMgZnJvbS5cbiAgICAgKiBAcmV0dXJuIHtGdW5jdGlvbltdfE9iamVjdH0gQWxsIGxpc3RlbmVyIGZ1bmN0aW9ucyBmb3IgdGhlIGV2ZW50LlxuICAgICAqL1xuICAgIHByb3RvLmdldExpc3RlbmVycyA9IGZ1bmN0aW9uIGdldExpc3RlbmVycyhldnQpIHtcbiAgICAgICAgdmFyIGV2ZW50cyA9IHRoaXMuX2dldEV2ZW50cygpO1xuICAgICAgICB2YXIgcmVzcG9uc2U7XG4gICAgICAgIHZhciBrZXk7XG5cbiAgICAgICAgLy8gUmV0dXJuIGEgY29uY2F0ZW5hdGVkIGFycmF5IG9mIGFsbCBtYXRjaGluZyBldmVudHMgaWZcbiAgICAgICAgLy8gdGhlIHNlbGVjdG9yIGlzIGEgcmVndWxhciBleHByZXNzaW9uLlxuICAgICAgICBpZiAoZXZ0IGluc3RhbmNlb2YgUmVnRXhwKSB7XG4gICAgICAgICAgICByZXNwb25zZSA9IHt9O1xuICAgICAgICAgICAgZm9yIChrZXkgaW4gZXZlbnRzKSB7XG4gICAgICAgICAgICAgICAgaWYgKGV2ZW50cy5oYXNPd25Qcm9wZXJ0eShrZXkpICYmIGV2dC50ZXN0KGtleSkpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVzcG9uc2Vba2V5XSA9IGV2ZW50c1trZXldO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJlc3BvbnNlID0gZXZlbnRzW2V2dF0gfHwgKGV2ZW50c1tldnRdID0gW10pO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHJlc3BvbnNlO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBUYWtlcyBhIGxpc3Qgb2YgbGlzdGVuZXIgb2JqZWN0cyBhbmQgZmxhdHRlbnMgaXQgaW50byBhIGxpc3Qgb2YgbGlzdGVuZXIgZnVuY3Rpb25zLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtPYmplY3RbXX0gbGlzdGVuZXJzIFJhdyBsaXN0ZW5lciBvYmplY3RzLlxuICAgICAqIEByZXR1cm4ge0Z1bmN0aW9uW119IEp1c3QgdGhlIGxpc3RlbmVyIGZ1bmN0aW9ucy5cbiAgICAgKi9cbiAgICBwcm90by5mbGF0dGVuTGlzdGVuZXJzID0gZnVuY3Rpb24gZmxhdHRlbkxpc3RlbmVycyhsaXN0ZW5lcnMpIHtcbiAgICAgICAgdmFyIGZsYXRMaXN0ZW5lcnMgPSBbXTtcbiAgICAgICAgdmFyIGk7XG5cbiAgICAgICAgZm9yIChpID0gMDsgaSA8IGxpc3RlbmVycy5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICAgICAgZmxhdExpc3RlbmVycy5wdXNoKGxpc3RlbmVyc1tpXS5saXN0ZW5lcik7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gZmxhdExpc3RlbmVycztcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogRmV0Y2hlcyB0aGUgcmVxdWVzdGVkIGxpc3RlbmVycyB2aWEgZ2V0TGlzdGVuZXJzIGJ1dCB3aWxsIGFsd2F5cyByZXR1cm4gdGhlIHJlc3VsdHMgaW5zaWRlIGFuIG9iamVjdC4gVGhpcyBpcyBtYWlubHkgZm9yIGludGVybmFsIHVzZSBidXQgb3RoZXJzIG1heSBmaW5kIGl0IHVzZWZ1bC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfFJlZ0V4cH0gZXZ0IE5hbWUgb2YgdGhlIGV2ZW50IHRvIHJldHVybiB0aGUgbGlzdGVuZXJzIGZyb20uXG4gICAgICogQHJldHVybiB7T2JqZWN0fSBBbGwgbGlzdGVuZXIgZnVuY3Rpb25zIGZvciBhbiBldmVudCBpbiBhbiBvYmplY3QuXG4gICAgICovXG4gICAgcHJvdG8uZ2V0TGlzdGVuZXJzQXNPYmplY3QgPSBmdW5jdGlvbiBnZXRMaXN0ZW5lcnNBc09iamVjdChldnQpIHtcbiAgICAgICAgdmFyIGxpc3RlbmVycyA9IHRoaXMuZ2V0TGlzdGVuZXJzKGV2dCk7XG4gICAgICAgIHZhciByZXNwb25zZTtcblxuICAgICAgICBpZiAobGlzdGVuZXJzIGluc3RhbmNlb2YgQXJyYXkpIHtcbiAgICAgICAgICAgIHJlc3BvbnNlID0ge307XG4gICAgICAgICAgICByZXNwb25zZVtldnRdID0gbGlzdGVuZXJzO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHJlc3BvbnNlIHx8IGxpc3RlbmVycztcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQWRkcyBhIGxpc3RlbmVyIGZ1bmN0aW9uIHRvIHRoZSBzcGVjaWZpZWQgZXZlbnQuXG4gICAgICogVGhlIGxpc3RlbmVyIHdpbGwgbm90IGJlIGFkZGVkIGlmIGl0IGlzIGEgZHVwbGljYXRlLlxuICAgICAqIElmIHRoZSBsaXN0ZW5lciByZXR1cm5zIHRydWUgdGhlbiBpdCB3aWxsIGJlIHJlbW92ZWQgYWZ0ZXIgaXQgaXMgY2FsbGVkLlxuICAgICAqIElmIHlvdSBwYXNzIGEgcmVndWxhciBleHByZXNzaW9uIGFzIHRoZSBldmVudCBuYW1lIHRoZW4gdGhlIGxpc3RlbmVyIHdpbGwgYmUgYWRkZWQgdG8gYWxsIGV2ZW50cyB0aGF0IG1hdGNoIGl0LlxuICAgICAqXG4gICAgICogQHBhcmFtIHtTdHJpbmd8UmVnRXhwfSBldnQgTmFtZSBvZiB0aGUgZXZlbnQgdG8gYXR0YWNoIHRoZSBsaXN0ZW5lciB0by5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBsaXN0ZW5lciBNZXRob2QgdG8gYmUgY2FsbGVkIHdoZW4gdGhlIGV2ZW50IGlzIGVtaXR0ZWQuIElmIHRoZSBmdW5jdGlvbiByZXR1cm5zIHRydWUgdGhlbiBpdCB3aWxsIGJlIHJlbW92ZWQgYWZ0ZXIgY2FsbGluZy5cbiAgICAgKiBAcmV0dXJuIHtPYmplY3R9IEN1cnJlbnQgaW5zdGFuY2Ugb2YgRXZlbnRFbWl0dGVyIGZvciBjaGFpbmluZy5cbiAgICAgKi9cbiAgICBwcm90by5hZGRMaXN0ZW5lciA9IGZ1bmN0aW9uIGFkZExpc3RlbmVyKGV2dCwgbGlzdGVuZXIpIHtcbiAgICAgICAgdmFyIGxpc3RlbmVycyA9IHRoaXMuZ2V0TGlzdGVuZXJzQXNPYmplY3QoZXZ0KTtcbiAgICAgICAgdmFyIGxpc3RlbmVySXNXcmFwcGVkID0gdHlwZW9mIGxpc3RlbmVyID09PSAnb2JqZWN0JztcbiAgICAgICAgdmFyIGtleTtcblxuICAgICAgICBmb3IgKGtleSBpbiBsaXN0ZW5lcnMpIHtcbiAgICAgICAgICAgIGlmIChsaXN0ZW5lcnMuaGFzT3duUHJvcGVydHkoa2V5KSAmJiBpbmRleE9mTGlzdGVuZXIobGlzdGVuZXJzW2tleV0sIGxpc3RlbmVyKSA9PT0gLTEpIHtcbiAgICAgICAgICAgICAgICBsaXN0ZW5lcnNba2V5XS5wdXNoKGxpc3RlbmVySXNXcmFwcGVkID8gbGlzdGVuZXIgOiB7XG4gICAgICAgICAgICAgICAgICAgIGxpc3RlbmVyOiBsaXN0ZW5lcixcbiAgICAgICAgICAgICAgICAgICAgb25jZTogZmFsc2VcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBBbGlhcyBvZiBhZGRMaXN0ZW5lclxuICAgICAqL1xuICAgIHByb3RvLm9uID0gYWxpYXMoJ2FkZExpc3RlbmVyJyk7XG5cbiAgICAvKipcbiAgICAgKiBTZW1pLWFsaWFzIG9mIGFkZExpc3RlbmVyLiBJdCB3aWxsIGFkZCBhIGxpc3RlbmVyIHRoYXQgd2lsbCBiZVxuICAgICAqIGF1dG9tYXRpY2FsbHkgcmVtb3ZlZCBhZnRlciBpdHMgZmlyc3QgZXhlY3V0aW9uLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtTdHJpbmd8UmVnRXhwfSBldnQgTmFtZSBvZiB0aGUgZXZlbnQgdG8gYXR0YWNoIHRoZSBsaXN0ZW5lciB0by5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBsaXN0ZW5lciBNZXRob2QgdG8gYmUgY2FsbGVkIHdoZW4gdGhlIGV2ZW50IGlzIGVtaXR0ZWQuIElmIHRoZSBmdW5jdGlvbiByZXR1cm5zIHRydWUgdGhlbiBpdCB3aWxsIGJlIHJlbW92ZWQgYWZ0ZXIgY2FsbGluZy5cbiAgICAgKiBAcmV0dXJuIHtPYmplY3R9IEN1cnJlbnQgaW5zdGFuY2Ugb2YgRXZlbnRFbWl0dGVyIGZvciBjaGFpbmluZy5cbiAgICAgKi9cbiAgICBwcm90by5hZGRPbmNlTGlzdGVuZXIgPSBmdW5jdGlvbiBhZGRPbmNlTGlzdGVuZXIoZXZ0LCBsaXN0ZW5lcikge1xuICAgICAgICByZXR1cm4gdGhpcy5hZGRMaXN0ZW5lcihldnQsIHtcbiAgICAgICAgICAgIGxpc3RlbmVyOiBsaXN0ZW5lcixcbiAgICAgICAgICAgIG9uY2U6IHRydWVcbiAgICAgICAgfSk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEFsaWFzIG9mIGFkZE9uY2VMaXN0ZW5lci5cbiAgICAgKi9cbiAgICBwcm90by5vbmNlID0gYWxpYXMoJ2FkZE9uY2VMaXN0ZW5lcicpO1xuXG4gICAgLyoqXG4gICAgICogRGVmaW5lcyBhbiBldmVudCBuYW1lLiBUaGlzIGlzIHJlcXVpcmVkIGlmIHlvdSB3YW50IHRvIHVzZSBhIHJlZ2V4IHRvIGFkZCBhIGxpc3RlbmVyIHRvIG11bHRpcGxlIGV2ZW50cyBhdCBvbmNlLiBJZiB5b3UgZG9uJ3QgZG8gdGhpcyB0aGVuIGhvdyBkbyB5b3UgZXhwZWN0IGl0IHRvIGtub3cgd2hhdCBldmVudCB0byBhZGQgdG8/IFNob3VsZCBpdCBqdXN0IGFkZCB0byBldmVyeSBwb3NzaWJsZSBtYXRjaCBmb3IgYSByZWdleD8gTm8uIFRoYXQgaXMgc2NhcnkgYW5kIGJhZC5cbiAgICAgKiBZb3UgbmVlZCB0byB0ZWxsIGl0IHdoYXQgZXZlbnQgbmFtZXMgc2hvdWxkIGJlIG1hdGNoZWQgYnkgYSByZWdleC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBldnQgTmFtZSBvZiB0aGUgZXZlbnQgdG8gY3JlYXRlLlxuICAgICAqIEByZXR1cm4ge09iamVjdH0gQ3VycmVudCBpbnN0YW5jZSBvZiBFdmVudEVtaXR0ZXIgZm9yIGNoYWluaW5nLlxuICAgICAqL1xuICAgIHByb3RvLmRlZmluZUV2ZW50ID0gZnVuY3Rpb24gZGVmaW5lRXZlbnQoZXZ0KSB7XG4gICAgICAgIHRoaXMuZ2V0TGlzdGVuZXJzKGV2dCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBVc2VzIGRlZmluZUV2ZW50IHRvIGRlZmluZSBtdWx0aXBsZSBldmVudHMuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge1N0cmluZ1tdfSBldnRzIEFuIGFycmF5IG9mIGV2ZW50IG5hbWVzIHRvIGRlZmluZS5cbiAgICAgKiBAcmV0dXJuIHtPYmplY3R9IEN1cnJlbnQgaW5zdGFuY2Ugb2YgRXZlbnRFbWl0dGVyIGZvciBjaGFpbmluZy5cbiAgICAgKi9cbiAgICBwcm90by5kZWZpbmVFdmVudHMgPSBmdW5jdGlvbiBkZWZpbmVFdmVudHMoZXZ0cykge1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGV2dHMubGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgICAgICAgIHRoaXMuZGVmaW5lRXZlbnQoZXZ0c1tpXSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIFJlbW92ZXMgYSBsaXN0ZW5lciBmdW5jdGlvbiBmcm9tIHRoZSBzcGVjaWZpZWQgZXZlbnQuXG4gICAgICogV2hlbiBwYXNzZWQgYSByZWd1bGFyIGV4cHJlc3Npb24gYXMgdGhlIGV2ZW50IG5hbWUsIGl0IHdpbGwgcmVtb3ZlIHRoZSBsaXN0ZW5lciBmcm9tIGFsbCBldmVudHMgdGhhdCBtYXRjaCBpdC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfFJlZ0V4cH0gZXZ0IE5hbWUgb2YgdGhlIGV2ZW50IHRvIHJlbW92ZSB0aGUgbGlzdGVuZXIgZnJvbS5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBsaXN0ZW5lciBNZXRob2QgdG8gcmVtb3ZlIGZyb20gdGhlIGV2ZW50LlxuICAgICAqIEByZXR1cm4ge09iamVjdH0gQ3VycmVudCBpbnN0YW5jZSBvZiBFdmVudEVtaXR0ZXIgZm9yIGNoYWluaW5nLlxuICAgICAqL1xuICAgIHByb3RvLnJlbW92ZUxpc3RlbmVyID0gZnVuY3Rpb24gcmVtb3ZlTGlzdGVuZXIoZXZ0LCBsaXN0ZW5lcikge1xuICAgICAgICB2YXIgbGlzdGVuZXJzID0gdGhpcy5nZXRMaXN0ZW5lcnNBc09iamVjdChldnQpO1xuICAgICAgICB2YXIgaW5kZXg7XG4gICAgICAgIHZhciBrZXk7XG5cbiAgICAgICAgZm9yIChrZXkgaW4gbGlzdGVuZXJzKSB7XG4gICAgICAgICAgICBpZiAobGlzdGVuZXJzLmhhc093blByb3BlcnR5KGtleSkpIHtcbiAgICAgICAgICAgICAgICBpbmRleCA9IGluZGV4T2ZMaXN0ZW5lcihsaXN0ZW5lcnNba2V5XSwgbGlzdGVuZXIpO1xuXG4gICAgICAgICAgICAgICAgaWYgKGluZGV4ICE9PSAtMSkge1xuICAgICAgICAgICAgICAgICAgICBsaXN0ZW5lcnNba2V5XS5zcGxpY2UoaW5kZXgsIDEpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBBbGlhcyBvZiByZW1vdmVMaXN0ZW5lclxuICAgICAqL1xuICAgIHByb3RvLm9mZiA9IGFsaWFzKCdyZW1vdmVMaXN0ZW5lcicpO1xuXG4gICAgLyoqXG4gICAgICogQWRkcyBsaXN0ZW5lcnMgaW4gYnVsayB1c2luZyB0aGUgbWFuaXB1bGF0ZUxpc3RlbmVycyBtZXRob2QuXG4gICAgICogSWYgeW91IHBhc3MgYW4gb2JqZWN0IGFzIHRoZSBzZWNvbmQgYXJndW1lbnQgeW91IGNhbiBhZGQgdG8gbXVsdGlwbGUgZXZlbnRzIGF0IG9uY2UuIFRoZSBvYmplY3Qgc2hvdWxkIGNvbnRhaW4ga2V5IHZhbHVlIHBhaXJzIG9mIGV2ZW50cyBhbmQgbGlzdGVuZXJzIG9yIGxpc3RlbmVyIGFycmF5cy4gWW91IGNhbiBhbHNvIHBhc3MgaXQgYW4gZXZlbnQgbmFtZSBhbmQgYW4gYXJyYXkgb2YgbGlzdGVuZXJzIHRvIGJlIGFkZGVkLlxuICAgICAqIFlvdSBjYW4gYWxzbyBwYXNzIGl0IGEgcmVndWxhciBleHByZXNzaW9uIHRvIGFkZCB0aGUgYXJyYXkgb2YgbGlzdGVuZXJzIHRvIGFsbCBldmVudHMgdGhhdCBtYXRjaCBpdC5cbiAgICAgKiBZZWFoLCB0aGlzIGZ1bmN0aW9uIGRvZXMgcXVpdGUgYSBiaXQuIFRoYXQncyBwcm9iYWJseSBhIGJhZCB0aGluZy5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfE9iamVjdHxSZWdFeHB9IGV2dCBBbiBldmVudCBuYW1lIGlmIHlvdSB3aWxsIHBhc3MgYW4gYXJyYXkgb2YgbGlzdGVuZXJzIG5leHQuIEFuIG9iamVjdCBpZiB5b3Ugd2lzaCB0byBhZGQgdG8gbXVsdGlwbGUgZXZlbnRzIGF0IG9uY2UuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbltdfSBbbGlzdGVuZXJzXSBBbiBvcHRpb25hbCBhcnJheSBvZiBsaXN0ZW5lciBmdW5jdGlvbnMgdG8gYWRkLlxuICAgICAqIEByZXR1cm4ge09iamVjdH0gQ3VycmVudCBpbnN0YW5jZSBvZiBFdmVudEVtaXR0ZXIgZm9yIGNoYWluaW5nLlxuICAgICAqL1xuICAgIHByb3RvLmFkZExpc3RlbmVycyA9IGZ1bmN0aW9uIGFkZExpc3RlbmVycyhldnQsIGxpc3RlbmVycykge1xuICAgICAgICAvLyBQYXNzIHRocm91Z2ggdG8gbWFuaXB1bGF0ZUxpc3RlbmVyc1xuICAgICAgICByZXR1cm4gdGhpcy5tYW5pcHVsYXRlTGlzdGVuZXJzKGZhbHNlLCBldnQsIGxpc3RlbmVycyk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIFJlbW92ZXMgbGlzdGVuZXJzIGluIGJ1bGsgdXNpbmcgdGhlIG1hbmlwdWxhdGVMaXN0ZW5lcnMgbWV0aG9kLlxuICAgICAqIElmIHlvdSBwYXNzIGFuIG9iamVjdCBhcyB0aGUgc2Vjb25kIGFyZ3VtZW50IHlvdSBjYW4gcmVtb3ZlIGZyb20gbXVsdGlwbGUgZXZlbnRzIGF0IG9uY2UuIFRoZSBvYmplY3Qgc2hvdWxkIGNvbnRhaW4ga2V5IHZhbHVlIHBhaXJzIG9mIGV2ZW50cyBhbmQgbGlzdGVuZXJzIG9yIGxpc3RlbmVyIGFycmF5cy5cbiAgICAgKiBZb3UgY2FuIGFsc28gcGFzcyBpdCBhbiBldmVudCBuYW1lIGFuZCBhbiBhcnJheSBvZiBsaXN0ZW5lcnMgdG8gYmUgcmVtb3ZlZC5cbiAgICAgKiBZb3UgY2FuIGFsc28gcGFzcyBpdCBhIHJlZ3VsYXIgZXhwcmVzc2lvbiB0byByZW1vdmUgdGhlIGxpc3RlbmVycyBmcm9tIGFsbCBldmVudHMgdGhhdCBtYXRjaCBpdC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfE9iamVjdHxSZWdFeHB9IGV2dCBBbiBldmVudCBuYW1lIGlmIHlvdSB3aWxsIHBhc3MgYW4gYXJyYXkgb2YgbGlzdGVuZXJzIG5leHQuIEFuIG9iamVjdCBpZiB5b3Ugd2lzaCB0byByZW1vdmUgZnJvbSBtdWx0aXBsZSBldmVudHMgYXQgb25jZS5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9uW119IFtsaXN0ZW5lcnNdIEFuIG9wdGlvbmFsIGFycmF5IG9mIGxpc3RlbmVyIGZ1bmN0aW9ucyB0byByZW1vdmUuXG4gICAgICogQHJldHVybiB7T2JqZWN0fSBDdXJyZW50IGluc3RhbmNlIG9mIEV2ZW50RW1pdHRlciBmb3IgY2hhaW5pbmcuXG4gICAgICovXG4gICAgcHJvdG8ucmVtb3ZlTGlzdGVuZXJzID0gZnVuY3Rpb24gcmVtb3ZlTGlzdGVuZXJzKGV2dCwgbGlzdGVuZXJzKSB7XG4gICAgICAgIC8vIFBhc3MgdGhyb3VnaCB0byBtYW5pcHVsYXRlTGlzdGVuZXJzXG4gICAgICAgIHJldHVybiB0aGlzLm1hbmlwdWxhdGVMaXN0ZW5lcnModHJ1ZSwgZXZ0LCBsaXN0ZW5lcnMpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBFZGl0cyBsaXN0ZW5lcnMgaW4gYnVsay4gVGhlIGFkZExpc3RlbmVycyBhbmQgcmVtb3ZlTGlzdGVuZXJzIG1ldGhvZHMgYm90aCB1c2UgdGhpcyB0byBkbyB0aGVpciBqb2IuIFlvdSBzaG91bGQgcmVhbGx5IHVzZSB0aG9zZSBpbnN0ZWFkLCB0aGlzIGlzIGEgbGl0dGxlIGxvd2VyIGxldmVsLlxuICAgICAqIFRoZSBmaXJzdCBhcmd1bWVudCB3aWxsIGRldGVybWluZSBpZiB0aGUgbGlzdGVuZXJzIGFyZSByZW1vdmVkICh0cnVlKSBvciBhZGRlZCAoZmFsc2UpLlxuICAgICAqIElmIHlvdSBwYXNzIGFuIG9iamVjdCBhcyB0aGUgc2Vjb25kIGFyZ3VtZW50IHlvdSBjYW4gYWRkL3JlbW92ZSBmcm9tIG11bHRpcGxlIGV2ZW50cyBhdCBvbmNlLiBUaGUgb2JqZWN0IHNob3VsZCBjb250YWluIGtleSB2YWx1ZSBwYWlycyBvZiBldmVudHMgYW5kIGxpc3RlbmVycyBvciBsaXN0ZW5lciBhcnJheXMuXG4gICAgICogWW91IGNhbiBhbHNvIHBhc3MgaXQgYW4gZXZlbnQgbmFtZSBhbmQgYW4gYXJyYXkgb2YgbGlzdGVuZXJzIHRvIGJlIGFkZGVkL3JlbW92ZWQuXG4gICAgICogWW91IGNhbiBhbHNvIHBhc3MgaXQgYSByZWd1bGFyIGV4cHJlc3Npb24gdG8gbWFuaXB1bGF0ZSB0aGUgbGlzdGVuZXJzIG9mIGFsbCBldmVudHMgdGhhdCBtYXRjaCBpdC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gcmVtb3ZlIFRydWUgaWYgeW91IHdhbnQgdG8gcmVtb3ZlIGxpc3RlbmVycywgZmFsc2UgaWYgeW91IHdhbnQgdG8gYWRkLlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfE9iamVjdHxSZWdFeHB9IGV2dCBBbiBldmVudCBuYW1lIGlmIHlvdSB3aWxsIHBhc3MgYW4gYXJyYXkgb2YgbGlzdGVuZXJzIG5leHQuIEFuIG9iamVjdCBpZiB5b3Ugd2lzaCB0byBhZGQvcmVtb3ZlIGZyb20gbXVsdGlwbGUgZXZlbnRzIGF0IG9uY2UuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbltdfSBbbGlzdGVuZXJzXSBBbiBvcHRpb25hbCBhcnJheSBvZiBsaXN0ZW5lciBmdW5jdGlvbnMgdG8gYWRkL3JlbW92ZS5cbiAgICAgKiBAcmV0dXJuIHtPYmplY3R9IEN1cnJlbnQgaW5zdGFuY2Ugb2YgRXZlbnRFbWl0dGVyIGZvciBjaGFpbmluZy5cbiAgICAgKi9cbiAgICBwcm90by5tYW5pcHVsYXRlTGlzdGVuZXJzID0gZnVuY3Rpb24gbWFuaXB1bGF0ZUxpc3RlbmVycyhyZW1vdmUsIGV2dCwgbGlzdGVuZXJzKSB7XG4gICAgICAgIHZhciBpO1xuICAgICAgICB2YXIgdmFsdWU7XG4gICAgICAgIHZhciBzaW5nbGUgPSByZW1vdmUgPyB0aGlzLnJlbW92ZUxpc3RlbmVyIDogdGhpcy5hZGRMaXN0ZW5lcjtcbiAgICAgICAgdmFyIG11bHRpcGxlID0gcmVtb3ZlID8gdGhpcy5yZW1vdmVMaXN0ZW5lcnMgOiB0aGlzLmFkZExpc3RlbmVycztcblxuICAgICAgICAvLyBJZiBldnQgaXMgYW4gb2JqZWN0IHRoZW4gcGFzcyBlYWNoIG9mIGl0cyBwcm9wZXJ0aWVzIHRvIHRoaXMgbWV0aG9kXG4gICAgICAgIGlmICh0eXBlb2YgZXZ0ID09PSAnb2JqZWN0JyAmJiAhKGV2dCBpbnN0YW5jZW9mIFJlZ0V4cCkpIHtcbiAgICAgICAgICAgIGZvciAoaSBpbiBldnQpIHtcbiAgICAgICAgICAgICAgICBpZiAoZXZ0Lmhhc093blByb3BlcnR5KGkpICYmICh2YWx1ZSA9IGV2dFtpXSkpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gUGFzcyB0aGUgc2luZ2xlIGxpc3RlbmVyIHN0cmFpZ2h0IHRocm91Z2ggdG8gdGhlIHNpbmd1bGFyIG1ldGhvZFxuICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzaW5nbGUuY2FsbCh0aGlzLCBpLCB2YWx1ZSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBPdGhlcndpc2UgcGFzcyBiYWNrIHRvIHRoZSBtdWx0aXBsZSBmdW5jdGlvblxuICAgICAgICAgICAgICAgICAgICAgICAgbXVsdGlwbGUuY2FsbCh0aGlzLCBpLCB2YWx1ZSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAvLyBTbyBldnQgbXVzdCBiZSBhIHN0cmluZ1xuICAgICAgICAgICAgLy8gQW5kIGxpc3RlbmVycyBtdXN0IGJlIGFuIGFycmF5IG9mIGxpc3RlbmVyc1xuICAgICAgICAgICAgLy8gTG9vcCBvdmVyIGl0IGFuZCBwYXNzIGVhY2ggb25lIHRvIHRoZSBtdWx0aXBsZSBtZXRob2RcbiAgICAgICAgICAgIGkgPSBsaXN0ZW5lcnMubGVuZ3RoO1xuICAgICAgICAgICAgd2hpbGUgKGktLSkge1xuICAgICAgICAgICAgICAgIHNpbmdsZS5jYWxsKHRoaXMsIGV2dCwgbGlzdGVuZXJzW2ldKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBSZW1vdmVzIGFsbCBsaXN0ZW5lcnMgZnJvbSBhIHNwZWNpZmllZCBldmVudC5cbiAgICAgKiBJZiB5b3UgZG8gbm90IHNwZWNpZnkgYW4gZXZlbnQgdGhlbiBhbGwgbGlzdGVuZXJzIHdpbGwgYmUgcmVtb3ZlZC5cbiAgICAgKiBUaGF0IG1lYW5zIGV2ZXJ5IGV2ZW50IHdpbGwgYmUgZW1wdGllZC5cbiAgICAgKiBZb3UgY2FuIGFsc28gcGFzcyBhIHJlZ2V4IHRvIHJlbW92ZSBhbGwgZXZlbnRzIHRoYXQgbWF0Y2ggaXQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge1N0cmluZ3xSZWdFeHB9IFtldnRdIE9wdGlvbmFsIG5hbWUgb2YgdGhlIGV2ZW50IHRvIHJlbW92ZSBhbGwgbGlzdGVuZXJzIGZvci4gV2lsbCByZW1vdmUgZnJvbSBldmVyeSBldmVudCBpZiBub3QgcGFzc2VkLlxuICAgICAqIEByZXR1cm4ge09iamVjdH0gQ3VycmVudCBpbnN0YW5jZSBvZiBFdmVudEVtaXR0ZXIgZm9yIGNoYWluaW5nLlxuICAgICAqL1xuICAgIHByb3RvLnJlbW92ZUV2ZW50ID0gZnVuY3Rpb24gcmVtb3ZlRXZlbnQoZXZ0KSB7XG4gICAgICAgIHZhciB0eXBlID0gdHlwZW9mIGV2dDtcbiAgICAgICAgdmFyIGV2ZW50cyA9IHRoaXMuX2dldEV2ZW50cygpO1xuICAgICAgICB2YXIga2V5O1xuXG4gICAgICAgIC8vIFJlbW92ZSBkaWZmZXJlbnQgdGhpbmdzIGRlcGVuZGluZyBvbiB0aGUgc3RhdGUgb2YgZXZ0XG4gICAgICAgIGlmICh0eXBlID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgLy8gUmVtb3ZlIGFsbCBsaXN0ZW5lcnMgZm9yIHRoZSBzcGVjaWZpZWQgZXZlbnRcbiAgICAgICAgICAgIGRlbGV0ZSBldmVudHNbZXZ0XTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChldnQgaW5zdGFuY2VvZiBSZWdFeHApIHtcbiAgICAgICAgICAgIC8vIFJlbW92ZSBhbGwgZXZlbnRzIG1hdGNoaW5nIHRoZSByZWdleC5cbiAgICAgICAgICAgIGZvciAoa2V5IGluIGV2ZW50cykge1xuICAgICAgICAgICAgICAgIGlmIChldmVudHMuaGFzT3duUHJvcGVydHkoa2V5KSAmJiBldnQudGVzdChrZXkpKSB7XG4gICAgICAgICAgICAgICAgICAgIGRlbGV0ZSBldmVudHNba2V5XTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAvLyBSZW1vdmUgYWxsIGxpc3RlbmVycyBpbiBhbGwgZXZlbnRzXG4gICAgICAgICAgICBkZWxldGUgdGhpcy5fZXZlbnRzO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEFsaWFzIG9mIHJlbW92ZUV2ZW50LlxuICAgICAqXG4gICAgICogQWRkZWQgdG8gbWlycm9yIHRoZSBub2RlIEFQSS5cbiAgICAgKi9cbiAgICBwcm90by5yZW1vdmVBbGxMaXN0ZW5lcnMgPSBhbGlhcygncmVtb3ZlRXZlbnQnKTtcblxuICAgIC8qKlxuICAgICAqIEVtaXRzIGFuIGV2ZW50IG9mIHlvdXIgY2hvaWNlLlxuICAgICAqIFdoZW4gZW1pdHRlZCwgZXZlcnkgbGlzdGVuZXIgYXR0YWNoZWQgdG8gdGhhdCBldmVudCB3aWxsIGJlIGV4ZWN1dGVkLlxuICAgICAqIElmIHlvdSBwYXNzIHRoZSBvcHRpb25hbCBhcmd1bWVudCBhcnJheSB0aGVuIHRob3NlIGFyZ3VtZW50cyB3aWxsIGJlIHBhc3NlZCB0byBldmVyeSBsaXN0ZW5lciB1cG9uIGV4ZWN1dGlvbi5cbiAgICAgKiBCZWNhdXNlIGl0IHVzZXMgYGFwcGx5YCwgeW91ciBhcnJheSBvZiBhcmd1bWVudHMgd2lsbCBiZSBwYXNzZWQgYXMgaWYgeW91IHdyb3RlIHRoZW0gb3V0IHNlcGFyYXRlbHkuXG4gICAgICogU28gdGhleSB3aWxsIG5vdCBhcnJpdmUgd2l0aGluIHRoZSBhcnJheSBvbiB0aGUgb3RoZXIgc2lkZSwgdGhleSB3aWxsIGJlIHNlcGFyYXRlLlxuICAgICAqIFlvdSBjYW4gYWxzbyBwYXNzIGEgcmVndWxhciBleHByZXNzaW9uIHRvIGVtaXQgdG8gYWxsIGV2ZW50cyB0aGF0IG1hdGNoIGl0LlxuICAgICAqXG4gICAgICogQHBhcmFtIHtTdHJpbmd8UmVnRXhwfSBldnQgTmFtZSBvZiB0aGUgZXZlbnQgdG8gZW1pdCBhbmQgZXhlY3V0ZSBsaXN0ZW5lcnMgZm9yLlxuICAgICAqIEBwYXJhbSB7QXJyYXl9IFthcmdzXSBPcHRpb25hbCBhcnJheSBvZiBhcmd1bWVudHMgdG8gYmUgcGFzc2VkIHRvIGVhY2ggbGlzdGVuZXIuXG4gICAgICogQHJldHVybiB7T2JqZWN0fSBDdXJyZW50IGluc3RhbmNlIG9mIEV2ZW50RW1pdHRlciBmb3IgY2hhaW5pbmcuXG4gICAgICovXG4gICAgcHJvdG8uZW1pdEV2ZW50ID0gZnVuY3Rpb24gZW1pdEV2ZW50KGV2dCwgYXJncykge1xuICAgICAgICB2YXIgbGlzdGVuZXJzID0gdGhpcy5nZXRMaXN0ZW5lcnNBc09iamVjdChldnQpO1xuICAgICAgICB2YXIgbGlzdGVuZXI7XG4gICAgICAgIHZhciBpO1xuICAgICAgICB2YXIga2V5O1xuICAgICAgICB2YXIgcmVzcG9uc2U7XG5cbiAgICAgICAgZm9yIChrZXkgaW4gbGlzdGVuZXJzKSB7XG4gICAgICAgICAgICBpZiAobGlzdGVuZXJzLmhhc093blByb3BlcnR5KGtleSkpIHtcbiAgICAgICAgICAgICAgICBpID0gbGlzdGVuZXJzW2tleV0ubGVuZ3RoO1xuXG4gICAgICAgICAgICAgICAgd2hpbGUgKGktLSkge1xuICAgICAgICAgICAgICAgICAgICAvLyBJZiB0aGUgbGlzdGVuZXIgcmV0dXJucyB0cnVlIHRoZW4gaXQgc2hhbGwgYmUgcmVtb3ZlZCBmcm9tIHRoZSBldmVudFxuICAgICAgICAgICAgICAgICAgICAvLyBUaGUgZnVuY3Rpb24gaXMgZXhlY3V0ZWQgZWl0aGVyIHdpdGggYSBiYXNpYyBjYWxsIG9yIGFuIGFwcGx5IGlmIHRoZXJlIGlzIGFuIGFyZ3MgYXJyYXlcbiAgICAgICAgICAgICAgICAgICAgbGlzdGVuZXIgPSBsaXN0ZW5lcnNba2V5XVtpXTtcblxuICAgICAgICAgICAgICAgICAgICBpZiAobGlzdGVuZXIub25jZSA9PT0gdHJ1ZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5yZW1vdmVMaXN0ZW5lcihldnQsIGxpc3RlbmVyLmxpc3RlbmVyKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIHJlc3BvbnNlID0gbGlzdGVuZXIubGlzdGVuZXIuYXBwbHkodGhpcywgYXJncyB8fCBbXSk7XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKHJlc3BvbnNlID09PSB0aGlzLl9nZXRPbmNlUmV0dXJuVmFsdWUoKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5yZW1vdmVMaXN0ZW5lcihldnQsIGxpc3RlbmVyLmxpc3RlbmVyKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBBbGlhcyBvZiBlbWl0RXZlbnRcbiAgICAgKi9cbiAgICBwcm90by50cmlnZ2VyID0gYWxpYXMoJ2VtaXRFdmVudCcpO1xuXG4gICAgLyoqXG4gICAgICogU3VidGx5IGRpZmZlcmVudCBmcm9tIGVtaXRFdmVudCBpbiB0aGF0IGl0IHdpbGwgcGFzcyBpdHMgYXJndW1lbnRzIG9uIHRvIHRoZSBsaXN0ZW5lcnMsIGFzIG9wcG9zZWQgdG8gdGFraW5nIGEgc2luZ2xlIGFycmF5IG9mIGFyZ3VtZW50cyB0byBwYXNzIG9uLlxuICAgICAqIEFzIHdpdGggZW1pdEV2ZW50LCB5b3UgY2FuIHBhc3MgYSByZWdleCBpbiBwbGFjZSBvZiB0aGUgZXZlbnQgbmFtZSB0byBlbWl0IHRvIGFsbCBldmVudHMgdGhhdCBtYXRjaCBpdC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfFJlZ0V4cH0gZXZ0IE5hbWUgb2YgdGhlIGV2ZW50IHRvIGVtaXQgYW5kIGV4ZWN1dGUgbGlzdGVuZXJzIGZvci5cbiAgICAgKiBAcGFyYW0gey4uLip9IE9wdGlvbmFsIGFkZGl0aW9uYWwgYXJndW1lbnRzIHRvIGJlIHBhc3NlZCB0byBlYWNoIGxpc3RlbmVyLlxuICAgICAqIEByZXR1cm4ge09iamVjdH0gQ3VycmVudCBpbnN0YW5jZSBvZiBFdmVudEVtaXR0ZXIgZm9yIGNoYWluaW5nLlxuICAgICAqL1xuICAgIHByb3RvLmVtaXQgPSBmdW5jdGlvbiBlbWl0KGV2dCkge1xuICAgICAgICB2YXIgYXJncyA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMSk7XG4gICAgICAgIHJldHVybiB0aGlzLmVtaXRFdmVudChldnQsIGFyZ3MpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBTZXRzIHRoZSBjdXJyZW50IHZhbHVlIHRvIGNoZWNrIGFnYWluc3Qgd2hlbiBleGVjdXRpbmcgbGlzdGVuZXJzLiBJZiBhXG4gICAgICogbGlzdGVuZXJzIHJldHVybiB2YWx1ZSBtYXRjaGVzIHRoZSBvbmUgc2V0IGhlcmUgdGhlbiBpdCB3aWxsIGJlIHJlbW92ZWRcbiAgICAgKiBhZnRlciBleGVjdXRpb24uIFRoaXMgdmFsdWUgZGVmYXVsdHMgdG8gdHJ1ZS5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIG5ldyB2YWx1ZSB0byBjaGVjayBmb3Igd2hlbiBleGVjdXRpbmcgbGlzdGVuZXJzLlxuICAgICAqIEByZXR1cm4ge09iamVjdH0gQ3VycmVudCBpbnN0YW5jZSBvZiBFdmVudEVtaXR0ZXIgZm9yIGNoYWluaW5nLlxuICAgICAqL1xuICAgIHByb3RvLnNldE9uY2VSZXR1cm5WYWx1ZSA9IGZ1bmN0aW9uIHNldE9uY2VSZXR1cm5WYWx1ZSh2YWx1ZSkge1xuICAgICAgICB0aGlzLl9vbmNlUmV0dXJuVmFsdWUgPSB2YWx1ZTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEZldGNoZXMgdGhlIGN1cnJlbnQgdmFsdWUgdG8gY2hlY2sgYWdhaW5zdCB3aGVuIGV4ZWN1dGluZyBsaXN0ZW5lcnMuIElmXG4gICAgICogdGhlIGxpc3RlbmVycyByZXR1cm4gdmFsdWUgbWF0Y2hlcyB0aGlzIG9uZSB0aGVuIGl0IHNob3VsZCBiZSByZW1vdmVkXG4gICAgICogYXV0b21hdGljYWxseS4gSXQgd2lsbCByZXR1cm4gdHJ1ZSBieSBkZWZhdWx0LlxuICAgICAqXG4gICAgICogQHJldHVybiB7KnxCb29sZWFufSBUaGUgY3VycmVudCB2YWx1ZSB0byBjaGVjayBmb3Igb3IgdGhlIGRlZmF1bHQsIHRydWUuXG4gICAgICogQGFwaSBwcml2YXRlXG4gICAgICovXG4gICAgcHJvdG8uX2dldE9uY2VSZXR1cm5WYWx1ZSA9IGZ1bmN0aW9uIF9nZXRPbmNlUmV0dXJuVmFsdWUoKSB7XG4gICAgICAgIGlmICh0aGlzLmhhc093blByb3BlcnR5KCdfb25jZVJldHVyblZhbHVlJykpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9vbmNlUmV0dXJuVmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBGZXRjaGVzIHRoZSBldmVudHMgb2JqZWN0IGFuZCBjcmVhdGVzIG9uZSBpZiByZXF1aXJlZC5cbiAgICAgKlxuICAgICAqIEByZXR1cm4ge09iamVjdH0gVGhlIGV2ZW50cyBzdG9yYWdlIG9iamVjdC5cbiAgICAgKiBAYXBpIHByaXZhdGVcbiAgICAgKi9cbiAgICBwcm90by5fZ2V0RXZlbnRzID0gZnVuY3Rpb24gX2dldEV2ZW50cygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2V2ZW50cyB8fCAodGhpcy5fZXZlbnRzID0ge30pO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBSZXZlcnRzIHRoZSBnbG9iYWwge0BsaW5rIEV2ZW50RW1pdHRlcn0gdG8gaXRzIHByZXZpb3VzIHZhbHVlIGFuZCByZXR1cm5zIGEgcmVmZXJlbmNlIHRvIHRoaXMgdmVyc2lvbi5cbiAgICAgKlxuICAgICAqIEByZXR1cm4ge0Z1bmN0aW9ufSBOb24gY29uZmxpY3RpbmcgRXZlbnRFbWl0dGVyIGNsYXNzLlxuICAgICAqL1xuICAgIEV2ZW50RW1pdHRlci5ub0NvbmZsaWN0ID0gZnVuY3Rpb24gbm9Db25mbGljdCgpIHtcbiAgICAgICAgZXhwb3J0cy5FdmVudEVtaXR0ZXIgPSBvcmlnaW5hbEdsb2JhbFZhbHVlO1xuICAgICAgICByZXR1cm4gRXZlbnRFbWl0dGVyO1xuICAgIH07XG5cbiAgICAvLyBFeHBvc2UgdGhlIGNsYXNzIGVpdGhlciB2aWEgQU1ELCBDb21tb25KUyBvciB0aGUgZ2xvYmFsIG9iamVjdFxuICAgIGlmICh0eXBlb2YgZGVmaW5lID09PSAnZnVuY3Rpb24nICYmIGRlZmluZS5hbWQpIHtcbiAgICAgICAgZGVmaW5lKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHJldHVybiBFdmVudEVtaXR0ZXI7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBlbHNlIGlmICh0eXBlb2YgbW9kdWxlID09PSAnb2JqZWN0JyAmJiBtb2R1bGUuZXhwb3J0cyl7XG4gICAgICAgIG1vZHVsZS5leHBvcnRzID0gRXZlbnRFbWl0dGVyO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgZXhwb3J0cy5FdmVudEVtaXR0ZXIgPSBFdmVudEVtaXR0ZXI7XG4gICAgfVxufS5jYWxsKHRoaXMpKTtcbiIsImZ1bmN0aW9uIE1hcHBlcigpXG57XG4gIHZhciBzb3VyY2VzID0ge307XG5cblxuICB0aGlzLmZvckVhY2ggPSBmdW5jdGlvbihjYWxsYmFjaylcbiAge1xuICAgIGZvcih2YXIga2V5IGluIHNvdXJjZXMpXG4gICAge1xuICAgICAgdmFyIHNvdXJjZSA9IHNvdXJjZXNba2V5XTtcblxuICAgICAgZm9yKHZhciBrZXkyIGluIHNvdXJjZSlcbiAgICAgICAgY2FsbGJhY2soc291cmNlW2tleTJdKTtcbiAgICB9O1xuICB9O1xuXG4gIHRoaXMuZ2V0ID0gZnVuY3Rpb24oaWQsIHNvdXJjZSlcbiAge1xuICAgIHZhciBpZHMgPSBzb3VyY2VzW3NvdXJjZV07XG4gICAgaWYoaWRzID09IHVuZGVmaW5lZClcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG5cbiAgICByZXR1cm4gaWRzW2lkXTtcbiAgfTtcblxuICB0aGlzLnJlbW92ZSA9IGZ1bmN0aW9uKGlkLCBzb3VyY2UpXG4gIHtcbiAgICB2YXIgaWRzID0gc291cmNlc1tzb3VyY2VdO1xuICAgIGlmKGlkcyA9PSB1bmRlZmluZWQpXG4gICAgICByZXR1cm47XG5cbiAgICBkZWxldGUgaWRzW2lkXTtcblxuICAgIC8vIENoZWNrIGl0J3MgZW1wdHlcbiAgICBmb3IodmFyIGkgaW4gaWRzKXtyZXR1cm4gZmFsc2V9XG5cbiAgICBkZWxldGUgc291cmNlc1tzb3VyY2VdO1xuICB9O1xuXG4gIHRoaXMuc2V0ID0gZnVuY3Rpb24odmFsdWUsIGlkLCBzb3VyY2UpXG4gIHtcbiAgICBpZih2YWx1ZSA9PSB1bmRlZmluZWQpXG4gICAgICByZXR1cm4gdGhpcy5yZW1vdmUoaWQsIHNvdXJjZSk7XG5cbiAgICB2YXIgaWRzID0gc291cmNlc1tzb3VyY2VdO1xuICAgIGlmKGlkcyA9PSB1bmRlZmluZWQpXG4gICAgICBzb3VyY2VzW3NvdXJjZV0gPSBpZHMgPSB7fTtcblxuICAgIGlkc1tpZF0gPSB2YWx1ZTtcbiAgfTtcbn07XG5cblxuTWFwcGVyLnByb3RvdHlwZS5wb3AgPSBmdW5jdGlvbihpZCwgc291cmNlKVxue1xuICB2YXIgdmFsdWUgPSB0aGlzLmdldChpZCwgc291cmNlKTtcbiAgaWYodmFsdWUgPT0gdW5kZWZpbmVkKVxuICAgIHJldHVybiB1bmRlZmluZWQ7XG5cbiAgdGhpcy5yZW1vdmUoaWQsIHNvdXJjZSk7XG5cbiAgcmV0dXJuIHZhbHVlO1xufTtcblxuXG5tb2R1bGUuZXhwb3J0cyA9IE1hcHBlcjtcbiIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTQgS3VyZW50byAoaHR0cDovL2t1cmVudG8ub3JnLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG52YXIgSnNvblJwY0NsaWVudCAgPSByZXF1aXJlKCcuL2pzb25ycGNjbGllbnQnKTtcblxuXG5leHBvcnRzLkpzb25ScGNDbGllbnQgID0gSnNvblJwY0NsaWVudDsiLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE0IEt1cmVudG8gKGh0dHA6Ly9rdXJlbnRvLm9yZy8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxudmFyIFJwY0J1aWxkZXIgPSByZXF1aXJlKCcuLi8nKTtcbnZhciBXZWJTb2NrZXRXaXRoUmVjb25uZWN0aW9uID0gcmVxdWlyZSgnLi90cmFuc3BvcnRzL3dlYlNvY2tldFdpdGhSZWNvbm5lY3Rpb24nKTtcblxuRGF0ZS5ub3cgPSBEYXRlLm5vdyB8fCBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gK25ldyBEYXRlO1xufTtcblxudmFyIFBJTkdfSU5URVJWQUwgPSA1MDAwO1xuXG52YXIgUkVDT05ORUNUSU5HID0gJ1JFQ09OTkVDVElORyc7XG52YXIgQ09OTkVDVEVEID0gJ0NPTk5FQ1RFRCc7XG52YXIgRElTQ09OTkVDVEVEID0gJ0RJU0NPTk5FQ1RFRCc7XG5cbnZhciBMb2dnZXIgPSBjb25zb2xlO1xuXG4vKipcbiAqXG4gKiBoZWFydGJlYXQ6IGludGVydmFsIGluIG1zIGZvciBlYWNoIGhlYXJ0YmVhdCBtZXNzYWdlLFxuICogc2VuZENsb3NlTWVzc2FnZSA6IHRydWUgLyBmYWxzZSwgYmVmb3JlIGNsb3NpbmcgdGhlIGNvbm5lY3Rpb24sIGl0IHNlbmRzIGEgY2xvc2VTZXNzaW9uIG1lc3NhZ2VcbiAqIDxwcmU+XG4gKiB3cyA6IHtcbiAqIFx0dXJpIDogVVJJIHRvIGNvbm50ZWN0IHRvLFxuICogIHVzZVNvY2tKUyA6IHRydWUgKHVzZSBTb2NrSlMpIC8gZmFsc2UgKHVzZSBXZWJTb2NrZXQpIGJ5IGRlZmF1bHQsXG4gKiBcdG9uY29ubmVjdGVkIDogY2FsbGJhY2sgbWV0aG9kIHRvIGludm9rZSB3aGVuIGNvbm5lY3Rpb24gaXMgc3VjY2Vzc2Z1bCxcbiAqIFx0b25kaXNjb25uZWN0IDogY2FsbGJhY2sgbWV0aG9kIHRvIGludm9rZSB3aGVuIHRoZSBjb25uZWN0aW9uIGlzIGxvc3QsXG4gKiBcdG9ucmVjb25uZWN0aW5nIDogY2FsbGJhY2sgbWV0aG9kIHRvIGludm9rZSB3aGVuIHRoZSBjbGllbnQgaXMgcmVjb25uZWN0aW5nLFxuICogXHRvbnJlY29ubmVjdGVkIDogY2FsbGJhY2sgbWV0aG9kIHRvIGludm9rZSB3aGVuIHRoZSBjbGllbnQgc3VjY2VzZnVsbHkgcmVjb25uZWN0cyxcbiAqIFx0b25lcnJvciA6IGNhbGxiYWNrIG1ldGhvZCB0byBpbnZva2Ugd2hlbiB0aGVyZSBpcyBhbiBlcnJvclxuICogfSxcbiAqIHJwYyA6IHtcbiAqIFx0cmVxdWVzdFRpbWVvdXQgOiB0aW1lb3V0IGZvciBhIHJlcXVlc3QsXG4gKiBcdHNlc3Npb25TdGF0dXNDaGFuZ2VkOiBjYWxsYmFjayBtZXRob2QgZm9yIGNoYW5nZXMgaW4gc2Vzc2lvbiBzdGF0dXMsXG4gKiBcdG1lZGlhUmVuZWdvdGlhdGlvbjogbWVkaWFSZW5lZ290aWF0aW9uXG4gKiB9XG4gKiA8L3ByZT5cbiAqL1xuZnVuY3Rpb24gSnNvblJwY0NsaWVudChjb25maWd1cmF0aW9uKSB7XG5cbiAgICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgICB2YXIgd3NDb25maWcgPSBjb25maWd1cmF0aW9uLndzO1xuXG4gICAgdmFyIG5vdFJlY29ubmVjdElmTnVtTGVzc1RoYW4gPSAtMTtcblxuICAgIHZhciBwaW5nTmV4dE51bSA9IDA7XG4gICAgdmFyIGVuYWJsZWRQaW5ncyA9IHRydWU7XG4gICAgdmFyIHBpbmdQb25nU3RhcnRlZCA9IGZhbHNlO1xuICAgIHZhciBwaW5nSW50ZXJ2YWw7XG5cbiAgICB2YXIgc3RhdHVzID0gRElTQ09OTkVDVEVEO1xuXG4gICAgdmFyIG9ucmVjb25uZWN0aW5nID0gd3NDb25maWcub25yZWNvbm5lY3Rpbmc7XG4gICAgdmFyIG9ucmVjb25uZWN0ZWQgPSB3c0NvbmZpZy5vbnJlY29ubmVjdGVkO1xuICAgIHZhciBvbmNvbm5lY3RlZCA9IHdzQ29uZmlnLm9uY29ubmVjdGVkO1xuICAgIHZhciBvbmVycm9yID0gd3NDb25maWcub25lcnJvcjtcblxuICAgIGNvbmZpZ3VyYXRpb24ucnBjLnB1bGwgPSBmdW5jdGlvbihwYXJhbXMsIHJlcXVlc3QpIHtcbiAgICAgICAgcmVxdWVzdC5yZXBseShudWxsLCBcInB1c2hcIik7XG4gICAgfVxuXG4gICAgd3NDb25maWcub25yZWNvbm5lY3RpbmcgPSBmdW5jdGlvbigpIHtcbiAgICAgICAgTG9nZ2VyLmRlYnVnKFwiLS0tLS0tLS0tIE9OUkVDT05ORUNUSU5HIC0tLS0tLS0tLS0tXCIpO1xuICAgICAgICBpZiAoc3RhdHVzID09PSBSRUNPTk5FQ1RJTkcpIHtcbiAgICAgICAgICAgIExvZ2dlci5lcnJvcihcIldlYnNvY2tldCBhbHJlYWR5IGluIFJFQ09OTkVDVElORyBzdGF0ZSB3aGVuIHJlY2VpdmluZyBhIG5ldyBPTlJFQ09OTkVDVElORyBtZXNzYWdlLiBJZ25vcmluZyBpdFwiKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHN0YXR1cyA9IFJFQ09OTkVDVElORztcbiAgICAgICAgaWYgKG9ucmVjb25uZWN0aW5nKSB7XG4gICAgICAgICAgICBvbnJlY29ubmVjdGluZygpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgd3NDb25maWcub25yZWNvbm5lY3RlZCA9IGZ1bmN0aW9uKCkge1xuICAgICAgICBMb2dnZXIuZGVidWcoXCItLS0tLS0tLS0gT05SRUNPTk5FQ1RFRCAtLS0tLS0tLS0tLVwiKTtcbiAgICAgICAgaWYgKHN0YXR1cyA9PT0gQ09OTkVDVEVEKSB7XG4gICAgICAgICAgICBMb2dnZXIuZXJyb3IoXCJXZWJzb2NrZXQgYWxyZWFkeSBpbiBDT05ORUNURUQgc3RhdGUgd2hlbiByZWNlaXZpbmcgYSBuZXcgT05SRUNPTk5FQ1RFRCBtZXNzYWdlLiBJZ25vcmluZyBpdFwiKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBzdGF0dXMgPSBDT05ORUNURUQ7XG5cbiAgICAgICAgZW5hYmxlZFBpbmdzID0gdHJ1ZTtcbiAgICAgICAgdXBkYXRlTm90UmVjb25uZWN0SWZMZXNzVGhhbigpO1xuICAgICAgICB1c2VQaW5nKCk7XG5cbiAgICAgICAgaWYgKG9ucmVjb25uZWN0ZWQpIHtcbiAgICAgICAgICAgIG9ucmVjb25uZWN0ZWQoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHdzQ29uZmlnLm9uY29ubmVjdGVkID0gZnVuY3Rpb24oKSB7XG4gICAgICAgIExvZ2dlci5kZWJ1ZyhcIi0tLS0tLS0tLSBPTkNPTk5FQ1RFRCAtLS0tLS0tLS0tLVwiKTtcbiAgICAgICAgaWYgKHN0YXR1cyA9PT0gQ09OTkVDVEVEKSB7XG4gICAgICAgICAgICBMb2dnZXIuZXJyb3IoXCJXZWJzb2NrZXQgYWxyZWFkeSBpbiBDT05ORUNURUQgc3RhdGUgd2hlbiByZWNlaXZpbmcgYSBuZXcgT05DT05ORUNURUQgbWVzc2FnZS4gSWdub3JpbmcgaXRcIik7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgc3RhdHVzID0gQ09OTkVDVEVEO1xuXG4gICAgICAgIGVuYWJsZWRQaW5ncyA9IHRydWU7XG4gICAgICAgIHVzZVBpbmcoKTtcblxuICAgICAgICBpZiAob25jb25uZWN0ZWQpIHtcbiAgICAgICAgICAgIG9uY29ubmVjdGVkKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICB3c0NvbmZpZy5vbmVycm9yID0gZnVuY3Rpb24oZXJyb3IpIHtcbiAgICAgICAgTG9nZ2VyLmRlYnVnKFwiLS0tLS0tLS0tIE9ORVJST1IgLS0tLS0tLS0tLS1cIik7XG5cbiAgICAgICAgc3RhdHVzID0gRElTQ09OTkVDVEVEO1xuXG4gICAgICAgIGlmIChvbmVycm9yKSB7XG4gICAgICAgICAgICBvbmVycm9yKGVycm9yKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHZhciB3cyA9IG5ldyBXZWJTb2NrZXRXaXRoUmVjb25uZWN0aW9uKHdzQ29uZmlnKTtcblxuICAgIExvZ2dlci5kZWJ1ZygnQ29ubmVjdGluZyB3ZWJzb2NrZXQgdG8gVVJJOiAnICsgd3NDb25maWcudXJpKTtcblxuICAgIHZhciBycGNCdWlsZGVyT3B0aW9ucyA9IHtcbiAgICAgICAgcmVxdWVzdF90aW1lb3V0OiBjb25maWd1cmF0aW9uLnJwYy5yZXF1ZXN0VGltZW91dCxcbiAgICAgICAgcGluZ19yZXF1ZXN0X3RpbWVvdXQ6IGNvbmZpZ3VyYXRpb24ucnBjLmhlYXJ0YmVhdFJlcXVlc3RUaW1lb3V0XG4gICAgfTtcblxuICAgIHZhciBycGMgPSBuZXcgUnBjQnVpbGRlcihScGNCdWlsZGVyLnBhY2tlcnMuSnNvblJQQywgcnBjQnVpbGRlck9wdGlvbnMsIHdzLFxuICAgICAgICBmdW5jdGlvbihyZXF1ZXN0KSB7XG5cbiAgICAgICAgICAgIExvZ2dlci5kZWJ1ZygnUmVjZWl2ZWQgcmVxdWVzdDogJyArIEpTT04uc3RyaW5naWZ5KHJlcXVlc3QpKTtcblxuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICB2YXIgZnVuYyA9IGNvbmZpZ3VyYXRpb24ucnBjW3JlcXVlc3QubWV0aG9kXTtcblxuICAgICAgICAgICAgICAgIGlmIChmdW5jID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgTG9nZ2VyLmVycm9yKFwiTWV0aG9kIFwiICsgcmVxdWVzdC5tZXRob2QgKyBcIiBub3QgcmVnaXN0ZXJlZCBpbiBjbGllbnRcIik7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgZnVuYyhyZXF1ZXN0LnBhcmFtcywgcmVxdWVzdCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICAgICAgTG9nZ2VyLmVycm9yKCdFeGNlcHRpb24gcHJvY2Vzc2luZyByZXF1ZXN0OiAnICsgSlNPTi5zdHJpbmdpZnkocmVxdWVzdCkpO1xuICAgICAgICAgICAgICAgIExvZ2dlci5lcnJvcihlcnIpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgIHRoaXMuc2VuZCA9IGZ1bmN0aW9uKG1ldGhvZCwgcGFyYW1zLCBjYWxsYmFjaykge1xuICAgICAgICBpZiAobWV0aG9kICE9PSAncGluZycpIHtcbiAgICAgICAgICAgIExvZ2dlci5kZWJ1ZygnUmVxdWVzdDogbWV0aG9kOicgKyBtZXRob2QgKyBcIiBwYXJhbXM6XCIgKyBKU09OLnN0cmluZ2lmeShwYXJhbXMpKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciByZXF1ZXN0VGltZSA9IERhdGUubm93KCk7XG5cbiAgICAgICAgcnBjLmVuY29kZShtZXRob2QsIHBhcmFtcywgZnVuY3Rpb24oZXJyb3IsIHJlc3VsdCkge1xuICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgTG9nZ2VyLmVycm9yKFwiRVJST1I6XCIgKyBlcnJvci5tZXNzYWdlICsgXCIgaW4gUmVxdWVzdDogbWV0aG9kOlwiICtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1ldGhvZCArIFwiIHBhcmFtczpcIiArIEpTT04uc3RyaW5naWZ5KHBhcmFtcykgKyBcIiByZXF1ZXN0OlwiICtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yLnJlcXVlc3QpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IuZGF0YSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgTG9nZ2VyLmVycm9yKFwiRVJST1IgREFUQTpcIiArIEpTT04uc3RyaW5naWZ5KGVycm9yLmRhdGEpKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHt9XG4gICAgICAgICAgICAgICAgZXJyb3IucmVxdWVzdFRpbWUgPSByZXF1ZXN0VGltZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChjYWxsYmFjaykge1xuICAgICAgICAgICAgICAgIGlmIChyZXN1bHQgIT0gdW5kZWZpbmVkICYmIHJlc3VsdC52YWx1ZSAhPT0gJ3BvbmcnKSB7XG4gICAgICAgICAgICAgICAgICAgIExvZ2dlci5kZWJ1ZygnUmVzcG9uc2U6ICcgKyBKU09OLnN0cmluZ2lmeShyZXN1bHQpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY2FsbGJhY2soZXJyb3IsIHJlc3VsdCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHVwZGF0ZU5vdFJlY29ubmVjdElmTGVzc1RoYW4oKSB7XG4gICAgICAgIExvZ2dlci5kZWJ1ZyhcIm5vdFJlY29ubmVjdElmTnVtTGVzc1RoYW4gPSBcIiArIHBpbmdOZXh0TnVtICsgJyAob2xkPScgK1xuICAgICAgICAgICAgbm90UmVjb25uZWN0SWZOdW1MZXNzVGhhbiArICcpJyk7XG4gICAgICAgIG5vdFJlY29ubmVjdElmTnVtTGVzc1RoYW4gPSBwaW5nTmV4dE51bTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBzZW5kUGluZygpIHtcbiAgICAgICAgaWYgKGVuYWJsZWRQaW5ncykge1xuICAgICAgICAgICAgdmFyIHBhcmFtcyA9IG51bGw7XG4gICAgICAgICAgICBpZiAocGluZ05leHROdW0gPT0gMCB8fCBwaW5nTmV4dE51bSA9PSBub3RSZWNvbm5lY3RJZk51bUxlc3NUaGFuKSB7XG4gICAgICAgICAgICAgICAgcGFyYW1zID0ge1xuICAgICAgICAgICAgICAgICAgICBpbnRlcnZhbDogY29uZmlndXJhdGlvbi5oZWFydGJlYXQgfHwgUElOR19JTlRFUlZBTFxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBwaW5nTmV4dE51bSsrO1xuXG4gICAgICAgICAgICBzZWxmLnNlbmQoJ3BpbmcnLCBwYXJhbXMsIChmdW5jdGlvbihwaW5nTnVtKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKGVycm9yLCByZXN1bHQpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBMb2dnZXIuZGVidWcoXCJFcnJvciBpbiBwaW5nIHJlcXVlc3QgI1wiICsgcGluZ051bSArIFwiIChcIiArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3IubWVzc2FnZSArIFwiKVwiKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwaW5nTnVtID4gbm90UmVjb25uZWN0SWZOdW1MZXNzVGhhbikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVuYWJsZWRQaW5ncyA9IGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVwZGF0ZU5vdFJlY29ubmVjdElmTGVzc1RoYW4oKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBMb2dnZXIuZGVidWcoXCJTZXJ2ZXIgZGlkIG5vdCByZXNwb25kIHRvIHBpbmcgbWVzc2FnZSAjXCIgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwaW5nTnVtICsgXCIuIFJlY29ubmVjdGluZy4uLiBcIik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgd3MucmVjb25uZWN0V3MoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pKHBpbmdOZXh0TnVtKSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBMb2dnZXIuZGVidWcoXCJUcnlpbmcgdG8gc2VuZCBwaW5nLCBidXQgcGluZyBpcyBub3QgZW5hYmxlZFwiKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qXG4gICAgKiBJZiBjb25maWd1cmF0aW9uLmhlYXJiZWF0IGhhcyBhbnkgdmFsdWUsIHRoZSBwaW5nLXBvbmcgd2lsbCB3b3JrIHdpdGggdGhlIGludGVydmFsXG4gICAgKiBvZiBjb25maWd1cmF0aW9uLmhlYXJiZWF0XG4gICAgKi9cbiAgICBmdW5jdGlvbiB1c2VQaW5nKCkge1xuICAgICAgICBpZiAoIXBpbmdQb25nU3RhcnRlZCkge1xuICAgICAgICAgICAgTG9nZ2VyLmRlYnVnKFwiU3RhcnRpbmcgcGluZyAoaWYgY29uZmlndXJlZClcIilcbiAgICAgICAgICAgIHBpbmdQb25nU3RhcnRlZCA9IHRydWU7XG5cbiAgICAgICAgICAgIGlmIChjb25maWd1cmF0aW9uLmhlYXJ0YmVhdCAhPSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICBwaW5nSW50ZXJ2YWwgPSBzZXRJbnRlcnZhbChzZW5kUGluZywgY29uZmlndXJhdGlvbi5oZWFydGJlYXQpO1xuICAgICAgICAgICAgICAgIHNlbmRQaW5nKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICB0aGlzLmNsb3NlID0gZnVuY3Rpb24oKSB7XG4gICAgICAgIExvZ2dlci5kZWJ1ZyhcIkNsb3NpbmcganNvblJwY0NsaWVudCBleHBsaWNpdGx5IGJ5IGNsaWVudFwiKTtcblxuICAgICAgICBpZiAocGluZ0ludGVydmFsICE9IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgTG9nZ2VyLmRlYnVnKFwiQ2xlYXJpbmcgcGluZyBpbnRlcnZhbFwiKTtcbiAgICAgICAgICAgIGNsZWFySW50ZXJ2YWwocGluZ0ludGVydmFsKTtcbiAgICAgICAgfVxuICAgICAgICBwaW5nUG9uZ1N0YXJ0ZWQgPSBmYWxzZTtcbiAgICAgICAgZW5hYmxlZFBpbmdzID0gZmFsc2U7XG5cbiAgICAgICAgaWYgKGNvbmZpZ3VyYXRpb24uc2VuZENsb3NlTWVzc2FnZSkge1xuICAgICAgICAgICAgTG9nZ2VyLmRlYnVnKFwiU2VuZGluZyBjbG9zZSBtZXNzYWdlXCIpXG4gICAgICAgICAgICB0aGlzLnNlbmQoJ2Nsb3NlU2Vzc2lvbicsIG51bGwsIGZ1bmN0aW9uKGVycm9yLCByZXN1bHQpIHtcbiAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgTG9nZ2VyLmVycm9yKFwiRXJyb3Igc2VuZGluZyBjbG9zZSBtZXNzYWdlOiBcIiArIEpTT04uc3RyaW5naWZ5KGVycm9yKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHdzLmNsb3NlKCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIHtcblx0XHRcdHdzLmNsb3NlKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBUaGlzIG1ldGhvZCBpcyBvbmx5IGZvciB0ZXN0aW5nXG4gICAgdGhpcy5mb3JjZUNsb3NlID0gZnVuY3Rpb24obWlsbGlzKSB7XG4gICAgICAgIHdzLmZvcmNlQ2xvc2UobWlsbGlzKTtcbiAgICB9XG5cbiAgICB0aGlzLnJlY29ubmVjdCA9IGZ1bmN0aW9uKCkge1xuICAgICAgICB3cy5yZWNvbm5lY3RXcygpO1xuICAgIH1cbn1cblxuXG5tb2R1bGUuZXhwb3J0cyA9IEpzb25ScGNDbGllbnQ7XG4iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE0IEt1cmVudG8gKGh0dHA6Ly9rdXJlbnRvLm9yZy8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxudmFyIFdlYlNvY2tldFdpdGhSZWNvbm5lY3Rpb24gID0gcmVxdWlyZSgnLi93ZWJTb2NrZXRXaXRoUmVjb25uZWN0aW9uJyk7XG5cblxuZXhwb3J0cy5XZWJTb2NrZXRXaXRoUmVjb25uZWN0aW9uICA9IFdlYlNvY2tldFdpdGhSZWNvbm5lY3Rpb247IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxMy0yMDE1IEt1cmVudG8gKGh0dHA6Ly9rdXJlbnRvLm9yZy8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqL1xuXG5cInVzZSBzdHJpY3RcIjtcblxudmFyIEJyb3dzZXJXZWJTb2NrZXQgPSBnbG9iYWwuV2ViU29ja2V0IHx8IGdsb2JhbC5Nb3pXZWJTb2NrZXQ7XG5cbnZhciBMb2dnZXIgPSBjb25zb2xlO1xuXG4vKipcbiAqIEdldCBlaXRoZXIgdGhlIGBXZWJTb2NrZXRgIG9yIGBNb3pXZWJTb2NrZXRgIGdsb2JhbHNcbiAqIGluIHRoZSBicm93c2VyIG9yIHRyeSB0byByZXNvbHZlIFdlYlNvY2tldC1jb21wYXRpYmxlXG4gKiBpbnRlcmZhY2UgZXhwb3NlZCBieSBgd3NgIGZvciBOb2RlLWxpa2UgZW52aXJvbm1lbnQuXG4gKi9cblxuLyp2YXIgV2ViU29ja2V0ID0gQnJvd3NlcldlYlNvY2tldDtcbmlmICghV2ViU29ja2V0ICYmIHR5cGVvZiB3aW5kb3cgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgdHJ5IHtcbiAgICAgICAgV2ViU29ja2V0ID0gcmVxdWlyZSgnd3MnKTtcbiAgICB9IGNhdGNoIChlKSB7IH1cbn0qL1xuXG4vL3ZhciBTb2NrSlMgPSByZXF1aXJlKCdzb2NranMtY2xpZW50Jyk7XG5cbnZhciBNQVhfUkVUUklFUyA9IDIwMDA7IC8vIEZvcmV2ZXIuLi5cbnZhciBSRVRSWV9USU1FX01TID0gMzAwMDsgLy8gRklYTUU6IEltcGxlbWVudCBleHBvbmVudGlhbCB3YWl0IHRpbWVzLi4uXG5cbnZhciBDT05ORUNUSU5HID0gMDtcbnZhciBPUEVOID0gMTtcbnZhciBDTE9TSU5HID0gMjtcbnZhciBDTE9TRUQgPSAzO1xuXG4vKlxuY29uZmlnID0ge1xuXHRcdHVyaSA6IHdzVXJpLFxuXHRcdHVzZVNvY2tKUyA6IHRydWUgKHVzZSBTb2NrSlMpIC8gZmFsc2UgKHVzZSBXZWJTb2NrZXQpIGJ5IGRlZmF1bHQsXG5cdFx0b25jb25uZWN0ZWQgOiBjYWxsYmFjayBtZXRob2QgdG8gaW52b2tlIHdoZW4gY29ubmVjdGlvbiBpcyBzdWNjZXNzZnVsLFxuXHRcdG9uZGlzY29ubmVjdCA6IGNhbGxiYWNrIG1ldGhvZCB0byBpbnZva2Ugd2hlbiB0aGUgY29ubmVjdGlvbiBpcyBsb3N0LFxuXHRcdG9ucmVjb25uZWN0aW5nIDogY2FsbGJhY2sgbWV0aG9kIHRvIGludm9rZSB3aGVuIHRoZSBjbGllbnQgaXMgcmVjb25uZWN0aW5nLFxuXHRcdG9ucmVjb25uZWN0ZWQgOiBjYWxsYmFjayBtZXRob2QgdG8gaW52b2tlIHdoZW4gdGhlIGNsaWVudCBzdWNjZXNmdWxseSByZWNvbm5lY3RzLFxuXHR9O1xuKi9cbmZ1bmN0aW9uIFdlYlNvY2tldFdpdGhSZWNvbm5lY3Rpb24oY29uZmlnKSB7XG5cbiAgICB2YXIgY2xvc2luZyA9IGZhbHNlO1xuICAgIHZhciByZWdpc3Rlck1lc3NhZ2VIYW5kbGVyO1xuICAgIHZhciB3c1VyaSA9IGNvbmZpZy51cmk7XG4gICAgdmFyIHVzZVNvY2tKUyA9IGNvbmZpZy51c2VTb2NrSlM7XG4gICAgdmFyIHJlY29ubmVjdGluZyA9IGZhbHNlO1xuXG4gICAgdmFyIGZvcmNpbmdEaXNjb25uZWN0aW9uID0gZmFsc2U7XG5cbiAgICB2YXIgd3M7XG5cbiAgICBpZiAodXNlU29ja0pTKSB7XG4gICAgICAgIHdzID0gbmV3IFNvY2tKUyh3c1VyaSk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgd3MgPSBuZXcgV2ViU29ja2V0KHdzVXJpKTtcbiAgICB9XG5cbiAgICB3cy5vbm9wZW4gPSBmdW5jdGlvbigpIHtcbiAgICAgICAgbG9nQ29ubmVjdGVkKHdzLCB3c1VyaSk7XG4gICAgICAgIGlmIChjb25maWcub25jb25uZWN0ZWQpIHtcbiAgICAgICAgICAgIGNvbmZpZy5vbmNvbm5lY3RlZCgpO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIHdzLm9uZXJyb3IgPSBmdW5jdGlvbihlcnJvcikge1xuICAgICAgICBMb2dnZXIuZXJyb3IoXCJDb3VsZCBub3QgY29ubmVjdCB0byBcIiArIHdzVXJpICsgXCIgKGludm9raW5nIG9uZXJyb3IgaWYgZGVmaW5lZClcIiwgZXJyb3IpO1xuICAgICAgICBpZiAoY29uZmlnLm9uZXJyb3IpIHtcbiAgICAgICAgICAgIGNvbmZpZy5vbmVycm9yKGVycm9yKTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICBmdW5jdGlvbiBsb2dDb25uZWN0ZWQod3MsIHdzVXJpKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBMb2dnZXIuZGVidWcoXCJXZWJTb2NrZXQgY29ubmVjdGVkIHRvIFwiICsgd3NVcmkpO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICBMb2dnZXIuZXJyb3IoZSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICB2YXIgcmVjb25uZWN0aW9uT25DbG9zZSA9IGZ1bmN0aW9uKCkge1xuICAgICAgICBpZiAod3MucmVhZHlTdGF0ZSA9PT0gQ0xPU0VEKSB7XG4gICAgICAgICAgICBpZiAoY2xvc2luZykge1xuICAgICAgICAgICAgICAgIExvZ2dlci5kZWJ1ZyhcIkNvbm5lY3Rpb24gY2xvc2VkIGJ5IHVzZXJcIik7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIExvZ2dlci5kZWJ1ZyhcIkNvbm5lY3Rpb24gY2xvc2VkIHVuZXhwZWN0ZWNseS4gUmVjb25uZWN0aW5nLi4uXCIpO1xuICAgICAgICAgICAgICAgIHJlY29ubmVjdFRvU2FtZVVyaShNQVhfUkVUUklFUywgMSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBMb2dnZXIuZGVidWcoXCJDbG9zZSBjYWxsYmFjayBmcm9tIHByZXZpb3VzIHdlYnNvY2tldC4gSWdub3JpbmcgaXRcIik7XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgd3Mub25jbG9zZSA9IHJlY29ubmVjdGlvbk9uQ2xvc2U7XG5cbiAgICBmdW5jdGlvbiByZWNvbm5lY3RUb1NhbWVVcmkobWF4UmV0cmllcywgbnVtUmV0cmllcykge1xuICAgICAgICBMb2dnZXIuZGVidWcoXCJyZWNvbm5lY3RUb1NhbWVVcmkgKGF0dGVtcHQgI1wiICsgbnVtUmV0cmllcyArIFwiLCBtYXg9XCIgKyBtYXhSZXRyaWVzICsgXCIpXCIpO1xuXG4gICAgICAgIGlmIChudW1SZXRyaWVzID09PSAxKSB7XG4gICAgICAgICAgICBpZiAocmVjb25uZWN0aW5nKSB7XG4gICAgICAgICAgICAgICAgTG9nZ2VyLndhcm4oXCJUcnlpbmcgdG8gcmVjb25uZWN0VG9OZXdVcmkgd2hlbiByZWNvbm5lY3RpbmcuLi4gSWdub3JpbmcgdGhpcyByZWNvbm5lY3Rpb24uXCIpXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZWNvbm5lY3RpbmcgPSB0cnVlO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoY29uZmlnLm9ucmVjb25uZWN0aW5nKSB7XG4gICAgICAgICAgICAgICAgY29uZmlnLm9ucmVjb25uZWN0aW5nKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoZm9yY2luZ0Rpc2Nvbm5lY3Rpb24pIHtcbiAgICAgICAgICAgIHJlY29ubmVjdFRvTmV3VXJpKG1heFJldHJpZXMsIG51bVJldHJpZXMsIHdzVXJpKTtcblxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaWYgKGNvbmZpZy5uZXdXc1VyaU9uUmVjb25uZWN0aW9uKSB7XG4gICAgICAgICAgICAgICAgY29uZmlnLm5ld1dzVXJpT25SZWNvbm5lY3Rpb24oZnVuY3Rpb24oZXJyb3IsIG5ld1dzVXJpKSB7XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBMb2dnZXIuZGVidWcoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbigpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWNvbm5lY3RUb1NhbWVVcmkobWF4UmV0cmllcywgbnVtUmV0cmllcyArIDEpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSwgUkVUUllfVElNRV9NUyk7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZWNvbm5lY3RUb05ld1VyaShtYXhSZXRyaWVzLCBudW1SZXRyaWVzLCBuZXdXc1VyaSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZWNvbm5lY3RUb05ld1VyaShtYXhSZXRyaWVzLCBudW1SZXRyaWVzLCB3c1VyaSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBUT0RPIFRlc3QgcmV0cmllcy4gSG93IHRvIGZvcmNlIG5vdCBjb25uZWN0aW9uP1xuICAgIGZ1bmN0aW9uIHJlY29ubmVjdFRvTmV3VXJpKG1heFJldHJpZXMsIG51bVJldHJpZXMsIHJlY29ubmVjdFdzVXJpKSB7XG4gICAgICAgIExvZ2dlci5kZWJ1ZyhcIlJlY29ubmVjdGlvbiBhdHRlbXB0ICNcIiArIG51bVJldHJpZXMpO1xuXG4gICAgICAgIHdzLmNsb3NlKCk7XG5cbiAgICAgICAgd3NVcmkgPSByZWNvbm5lY3RXc1VyaSB8fCB3c1VyaTtcblxuICAgICAgICB2YXIgbmV3V3M7XG4gICAgICAgIGlmICh1c2VTb2NrSlMpIHtcbiAgICAgICAgICAgIG5ld1dzID0gbmV3IFNvY2tKUyh3c1VyaSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBuZXdXcyA9IG5ldyBXZWJTb2NrZXQod3NVcmkpO1xuICAgICAgICB9XG5cbiAgICAgICAgbmV3V3Mub25vcGVuID0gZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICBMb2dnZXIuZGVidWcoXCJSZWNvbm5lY3RlZCBhZnRlciBcIiArIG51bVJldHJpZXMgKyBcIiBhdHRlbXB0cy4uLlwiKTtcbiAgICAgICAgICAgIGxvZ0Nvbm5lY3RlZChuZXdXcywgd3NVcmkpO1xuICAgICAgICAgICAgcmVjb25uZWN0aW5nID0gZmFsc2U7XG4gICAgICAgICAgICByZWdpc3Rlck1lc3NhZ2VIYW5kbGVyKCk7XG4gICAgICAgICAgICBpZiAoY29uZmlnLm9ucmVjb25uZWN0ZWQoKSkge1xuICAgICAgICAgICAgICAgIGNvbmZpZy5vbnJlY29ubmVjdGVkKCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIG5ld1dzLm9uY2xvc2UgPSByZWNvbm5lY3Rpb25PbkNsb3NlO1xuICAgICAgICB9O1xuXG4gICAgICAgIHZhciBvbkVycm9yT3JDbG9zZSA9IGZ1bmN0aW9uKGVycm9yKSB7XG4gICAgICAgICAgICBMb2dnZXIud2FybihcIlJlY29ubmVjdGlvbiBlcnJvcjogXCIsIGVycm9yKTtcblxuICAgICAgICAgICAgaWYgKG51bVJldHJpZXMgPT09IG1heFJldHJpZXMpIHtcbiAgICAgICAgICAgICAgICBpZiAoY29uZmlnLm9uZGlzY29ubmVjdCkge1xuICAgICAgICAgICAgICAgICAgICBjb25maWcub25kaXNjb25uZWN0KCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgICAgICAgICByZWNvbm5lY3RUb1NhbWVVcmkobWF4UmV0cmllcywgbnVtUmV0cmllcyArIDEpO1xuICAgICAgICAgICAgICAgIH0sIFJFVFJZX1RJTUVfTVMpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuXG4gICAgICAgIG5ld1dzLm9uZXJyb3IgPSBvbkVycm9yT3JDbG9zZTtcblxuICAgICAgICB3cyA9IG5ld1dzO1xuICAgIH1cblxuICAgIHRoaXMuY2xvc2UgPSBmdW5jdGlvbigpIHtcbiAgICAgICAgY2xvc2luZyA9IHRydWU7XG4gICAgICAgIHdzLmNsb3NlKCk7XG4gICAgfTtcblxuXG4gICAgLy8gVGhpcyBtZXRob2QgaXMgb25seSBmb3IgdGVzdGluZ1xuICAgIHRoaXMuZm9yY2VDbG9zZSA9IGZ1bmN0aW9uKG1pbGxpcykge1xuICAgICAgICBMb2dnZXIuZGVidWcoXCJUZXN0aW5nOiBGb3JjZSBXZWJTb2NrZXQgY2xvc2VcIik7XG5cbiAgICAgICAgaWYgKG1pbGxpcykge1xuICAgICAgICAgICAgTG9nZ2VyLmRlYnVnKFwiVGVzdGluZzogQ2hhbmdlIHdzVXJpIGZvciBcIiArIG1pbGxpcyArIFwiIG1pbGxpcyB0byBzaW11bGF0ZSBuZXQgZmFpbHVyZVwiKTtcbiAgICAgICAgICAgIHZhciBnb29kV3NVcmkgPSB3c1VyaTtcbiAgICAgICAgICAgIHdzVXJpID0gXCJ3c3M6Ly8yMS4yMzQuMTIuMzQuNDo0NDMvXCI7XG5cbiAgICAgICAgICAgIGZvcmNpbmdEaXNjb25uZWN0aW9uID0gdHJ1ZTtcblxuICAgICAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbigpIHtcbiAgICAgICAgICAgICAgICBMb2dnZXIuZGVidWcoXCJUZXN0aW5nOiBSZWNvdmVyIGdvb2Qgd3NVcmkgXCIgKyBnb29kV3NVcmkpO1xuICAgICAgICAgICAgICAgIHdzVXJpID0gZ29vZFdzVXJpO1xuXG4gICAgICAgICAgICAgICAgZm9yY2luZ0Rpc2Nvbm5lY3Rpb24gPSBmYWxzZTtcblxuICAgICAgICAgICAgfSwgbWlsbGlzKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHdzLmNsb3NlKCk7XG4gICAgfTtcblxuICAgIHRoaXMucmVjb25uZWN0V3MgPSBmdW5jdGlvbigpIHtcbiAgICAgICAgTG9nZ2VyLmRlYnVnKFwicmVjb25uZWN0V3NcIik7XG4gICAgICAgIHJlY29ubmVjdFRvU2FtZVVyaShNQVhfUkVUUklFUywgMSwgd3NVcmkpO1xuICAgIH07XG5cbiAgICB0aGlzLnNlbmQgPSBmdW5jdGlvbihtZXNzYWdlKSB7XG4gICAgICAgIHdzLnNlbmQobWVzc2FnZSk7XG4gICAgfTtcblxuICAgIHRoaXMuYWRkRXZlbnRMaXN0ZW5lciA9IGZ1bmN0aW9uKHR5cGUsIGNhbGxiYWNrKSB7XG4gICAgICAgIHJlZ2lzdGVyTWVzc2FnZUhhbmRsZXIgPSBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgIHdzLmFkZEV2ZW50TGlzdGVuZXIodHlwZSwgY2FsbGJhY2spO1xuICAgICAgICB9O1xuXG4gICAgICAgIHJlZ2lzdGVyTWVzc2FnZUhhbmRsZXIoKTtcbiAgICB9O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IFdlYlNvY2tldFdpdGhSZWNvbm5lY3Rpb247XG4iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE0IEt1cmVudG8gKGh0dHA6Ly9rdXJlbnRvLm9yZy8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuXG52YXIgZGVmaW5lUHJvcGVydHlfSUU4ID0gZmFsc2VcbmlmKE9iamVjdC5kZWZpbmVQcm9wZXJ0eSlcbntcbiAgdHJ5XG4gIHtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoe30sIFwieFwiLCB7fSk7XG4gIH1cbiAgY2F0Y2goZSlcbiAge1xuICAgIGRlZmluZVByb3BlcnR5X0lFOCA9IHRydWVcbiAgfVxufVxuXG4vLyBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9KYXZhU2NyaXB0L1JlZmVyZW5jZS9HbG9iYWxfT2JqZWN0cy9GdW5jdGlvbi9iaW5kXG5pZiAoIUZ1bmN0aW9uLnByb3RvdHlwZS5iaW5kKSB7XG4gIEZ1bmN0aW9uLnByb3RvdHlwZS5iaW5kID0gZnVuY3Rpb24ob1RoaXMpIHtcbiAgICBpZiAodHlwZW9mIHRoaXMgIT09ICdmdW5jdGlvbicpIHtcbiAgICAgIC8vIGNsb3Nlc3QgdGhpbmcgcG9zc2libGUgdG8gdGhlIEVDTUFTY3JpcHQgNVxuICAgICAgLy8gaW50ZXJuYWwgSXNDYWxsYWJsZSBmdW5jdGlvblxuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignRnVuY3Rpb24ucHJvdG90eXBlLmJpbmQgLSB3aGF0IGlzIHRyeWluZyB0byBiZSBib3VuZCBpcyBub3QgY2FsbGFibGUnKTtcbiAgICB9XG5cbiAgICB2YXIgYUFyZ3MgICA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMSksXG4gICAgICAgIGZUb0JpbmQgPSB0aGlzLFxuICAgICAgICBmTk9QICAgID0gZnVuY3Rpb24oKSB7fSxcbiAgICAgICAgZkJvdW5kICA9IGZ1bmN0aW9uKCkge1xuICAgICAgICAgIHJldHVybiBmVG9CaW5kLmFwcGx5KHRoaXMgaW5zdGFuY2VvZiBmTk9QICYmIG9UaGlzXG4gICAgICAgICAgICAgICAgID8gdGhpc1xuICAgICAgICAgICAgICAgICA6IG9UaGlzLFxuICAgICAgICAgICAgICAgICBhQXJncy5jb25jYXQoQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzKSkpO1xuICAgICAgICB9O1xuXG4gICAgZk5PUC5wcm90b3R5cGUgPSB0aGlzLnByb3RvdHlwZTtcbiAgICBmQm91bmQucHJvdG90eXBlID0gbmV3IGZOT1AoKTtcblxuICAgIHJldHVybiBmQm91bmQ7XG4gIH07XG59XG5cblxudmFyIEV2ZW50RW1pdHRlciA9IHJlcXVpcmUoJ2V2ZW50cycpLkV2ZW50RW1pdHRlcjtcblxudmFyIGluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKTtcblxudmFyIHBhY2tlcnMgPSByZXF1aXJlKCcuL3BhY2tlcnMnKTtcbnZhciBNYXBwZXIgPSByZXF1aXJlKCcuL01hcHBlcicpO1xuXG5cbnZhciBCQVNFX1RJTUVPVVQgPSA1MDAwO1xuXG5cbmZ1bmN0aW9uIHVuaWZ5UmVzcG9uc2VNZXRob2RzKHJlc3BvbnNlTWV0aG9kcylcbntcbiAgaWYoIXJlc3BvbnNlTWV0aG9kcykgcmV0dXJuIHt9O1xuXG4gIGZvcih2YXIga2V5IGluIHJlc3BvbnNlTWV0aG9kcylcbiAge1xuICAgIHZhciB2YWx1ZSA9IHJlc3BvbnNlTWV0aG9kc1trZXldO1xuXG4gICAgaWYodHlwZW9mIHZhbHVlID09ICdzdHJpbmcnKVxuICAgICAgcmVzcG9uc2VNZXRob2RzW2tleV0gPVxuICAgICAge1xuICAgICAgICByZXNwb25zZTogdmFsdWVcbiAgICAgIH1cbiAgfTtcblxuICByZXR1cm4gcmVzcG9uc2VNZXRob2RzO1xufTtcblxuZnVuY3Rpb24gdW5pZnlUcmFuc3BvcnQodHJhbnNwb3J0KVxue1xuICBpZighdHJhbnNwb3J0KSByZXR1cm47XG5cbiAgLy8gVHJhbnNwb3J0IGFzIGEgZnVuY3Rpb25cbiAgaWYodHJhbnNwb3J0IGluc3RhbmNlb2YgRnVuY3Rpb24pXG4gICAgcmV0dXJuIHtzZW5kOiB0cmFuc3BvcnR9O1xuXG4gIC8vIFdlYlNvY2tldCAmIERhdGFDaGFubmVsXG4gIGlmKHRyYW5zcG9ydC5zZW5kIGluc3RhbmNlb2YgRnVuY3Rpb24pXG4gICAgcmV0dXJuIHRyYW5zcG9ydDtcblxuICAvLyBNZXNzYWdlIEFQSSAoSW50ZXItd2luZG93ICYgV2ViV29ya2VyKVxuICBpZih0cmFuc3BvcnQucG9zdE1lc3NhZ2UgaW5zdGFuY2VvZiBGdW5jdGlvbilcbiAge1xuICAgIHRyYW5zcG9ydC5zZW5kID0gdHJhbnNwb3J0LnBvc3RNZXNzYWdlO1xuICAgIHJldHVybiB0cmFuc3BvcnQ7XG4gIH1cblxuICAvLyBTdHJlYW0gQVBJXG4gIGlmKHRyYW5zcG9ydC53cml0ZSBpbnN0YW5jZW9mIEZ1bmN0aW9uKVxuICB7XG4gICAgdHJhbnNwb3J0LnNlbmQgPSB0cmFuc3BvcnQud3JpdGU7XG4gICAgcmV0dXJuIHRyYW5zcG9ydDtcbiAgfVxuXG4gIC8vIFRyYW5zcG9ydHMgdGhhdCBvbmx5IGNhbiByZWNlaXZlIG1lc3NhZ2VzLCBidXQgbm90IHNlbmRcbiAgaWYodHJhbnNwb3J0Lm9ubWVzc2FnZSAhPT0gdW5kZWZpbmVkKSByZXR1cm47XG4gIGlmKHRyYW5zcG9ydC5wYXVzZSBpbnN0YW5jZW9mIEZ1bmN0aW9uKSByZXR1cm47XG5cbiAgdGhyb3cgbmV3IFN5bnRheEVycm9yKFwiVHJhbnNwb3J0IGlzIG5vdCBhIGZ1bmN0aW9uIG5vciBhIHZhbGlkIG9iamVjdFwiKTtcbn07XG5cblxuLyoqXG4gKiBSZXByZXNlbnRhdGlvbiBvZiBhIFJQQyBub3RpZmljYXRpb25cbiAqXG4gKiBAY2xhc3NcbiAqXG4gKiBAY29uc3RydWN0b3JcbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gbWV0aG9kIC1tZXRob2Qgb2YgdGhlIG5vdGlmaWNhdGlvblxuICogQHBhcmFtIHBhcmFtcyAtIHBhcmFtZXRlcnMgb2YgdGhlIG5vdGlmaWNhdGlvblxuICovXG5mdW5jdGlvbiBScGNOb3RpZmljYXRpb24obWV0aG9kLCBwYXJhbXMpXG57XG4gIGlmKGRlZmluZVByb3BlcnR5X0lFOClcbiAge1xuICAgIHRoaXMubWV0aG9kID0gbWV0aG9kXG4gICAgdGhpcy5wYXJhbXMgPSBwYXJhbXNcbiAgfVxuICBlbHNlXG4gIHtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywgJ21ldGhvZCcsIHt2YWx1ZTogbWV0aG9kLCBlbnVtZXJhYmxlOiB0cnVlfSk7XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsICdwYXJhbXMnLCB7dmFsdWU6IHBhcmFtcywgZW51bWVyYWJsZTogdHJ1ZX0pO1xuICB9XG59O1xuXG5cbi8qKlxuICogQGNsYXNzXG4gKlxuICogQGNvbnN0cnVjdG9yXG4gKlxuICogQHBhcmFtIHtvYmplY3R9IHBhY2tlclxuICpcbiAqIEBwYXJhbSB7b2JqZWN0fSBbb3B0aW9uc11cbiAqXG4gKiBAcGFyYW0ge29iamVjdH0gW3RyYW5zcG9ydF1cbiAqXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBbb25SZXF1ZXN0XVxuICovXG5mdW5jdGlvbiBScGNCdWlsZGVyKHBhY2tlciwgb3B0aW9ucywgdHJhbnNwb3J0LCBvblJlcXVlc3QpXG57XG4gIHZhciBzZWxmID0gdGhpcztcblxuICBpZighcGFja2VyKVxuICAgIHRocm93IG5ldyBTeW50YXhFcnJvcignUGFja2VyIGlzIG5vdCBkZWZpbmVkJyk7XG5cbiAgaWYoIXBhY2tlci5wYWNrIHx8ICFwYWNrZXIudW5wYWNrKVxuICAgIHRocm93IG5ldyBTeW50YXhFcnJvcignUGFja2VyIGlzIGludmFsaWQnKTtcblxuICB2YXIgcmVzcG9uc2VNZXRob2RzID0gdW5pZnlSZXNwb25zZU1ldGhvZHMocGFja2VyLnJlc3BvbnNlTWV0aG9kcyk7XG5cblxuICBpZihvcHRpb25zIGluc3RhbmNlb2YgRnVuY3Rpb24pXG4gIHtcbiAgICBpZih0cmFuc3BvcnQgIT0gdW5kZWZpbmVkKVxuICAgICAgdGhyb3cgbmV3IFN5bnRheEVycm9yKFwiVGhlcmUgY2FuJ3QgYmUgcGFyYW1ldGVycyBhZnRlciBvblJlcXVlc3RcIik7XG5cbiAgICBvblJlcXVlc3QgPSBvcHRpb25zO1xuICAgIHRyYW5zcG9ydCA9IHVuZGVmaW5lZDtcbiAgICBvcHRpb25zICAgPSB1bmRlZmluZWQ7XG4gIH07XG5cbiAgaWYob3B0aW9ucyAmJiBvcHRpb25zLnNlbmQgaW5zdGFuY2VvZiBGdW5jdGlvbilcbiAge1xuICAgIGlmKHRyYW5zcG9ydCAmJiAhKHRyYW5zcG9ydCBpbnN0YW5jZW9mIEZ1bmN0aW9uKSlcbiAgICAgIHRocm93IG5ldyBTeW50YXhFcnJvcihcIk9ubHkgYSBmdW5jdGlvbiBjYW4gYmUgYWZ0ZXIgdHJhbnNwb3J0XCIpO1xuXG4gICAgb25SZXF1ZXN0ID0gdHJhbnNwb3J0O1xuICAgIHRyYW5zcG9ydCA9IG9wdGlvbnM7XG4gICAgb3B0aW9ucyAgID0gdW5kZWZpbmVkO1xuICB9O1xuXG4gIGlmKHRyYW5zcG9ydCBpbnN0YW5jZW9mIEZ1bmN0aW9uKVxuICB7XG4gICAgaWYob25SZXF1ZXN0ICE9IHVuZGVmaW5lZClcbiAgICAgIHRocm93IG5ldyBTeW50YXhFcnJvcihcIlRoZXJlIGNhbid0IGJlIHBhcmFtZXRlcnMgYWZ0ZXIgb25SZXF1ZXN0XCIpO1xuXG4gICAgb25SZXF1ZXN0ID0gdHJhbnNwb3J0O1xuICAgIHRyYW5zcG9ydCA9IHVuZGVmaW5lZDtcbiAgfTtcblxuICBpZih0cmFuc3BvcnQgJiYgdHJhbnNwb3J0LnNlbmQgaW5zdGFuY2VvZiBGdW5jdGlvbilcbiAgICBpZihvblJlcXVlc3QgJiYgIShvblJlcXVlc3QgaW5zdGFuY2VvZiBGdW5jdGlvbikpXG4gICAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoXCJPbmx5IGEgZnVuY3Rpb24gY2FuIGJlIGFmdGVyIHRyYW5zcG9ydFwiKTtcblxuICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcblxuXG4gIEV2ZW50RW1pdHRlci5jYWxsKHRoaXMpO1xuXG4gIGlmKG9uUmVxdWVzdClcbiAgICB0aGlzLm9uKCdyZXF1ZXN0Jywgb25SZXF1ZXN0KTtcblxuXG4gIGlmKGRlZmluZVByb3BlcnR5X0lFOClcbiAgICB0aGlzLnBlZXJJRCA9IG9wdGlvbnMucGVlcklEXG4gIGVsc2VcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywgJ3BlZXJJRCcsIHt2YWx1ZTogb3B0aW9ucy5wZWVySUR9KTtcblxuICB2YXIgbWF4X3JldHJpZXMgPSBvcHRpb25zLm1heF9yZXRyaWVzIHx8IDA7XG5cblxuICBmdW5jdGlvbiB0cmFuc3BvcnRNZXNzYWdlKGV2ZW50KVxuICB7XG4gICAgc2VsZi5kZWNvZGUoZXZlbnQuZGF0YSB8fCBldmVudCk7XG4gIH07XG5cbiAgdGhpcy5nZXRUcmFuc3BvcnQgPSBmdW5jdGlvbigpXG4gIHtcbiAgICByZXR1cm4gdHJhbnNwb3J0O1xuICB9XG4gIHRoaXMuc2V0VHJhbnNwb3J0ID0gZnVuY3Rpb24odmFsdWUpXG4gIHtcbiAgICAvLyBSZW1vdmUgbGlzdGVuZXIgZnJvbSBvbGQgdHJhbnNwb3J0XG4gICAgaWYodHJhbnNwb3J0KVxuICAgIHtcbiAgICAgIC8vIFczQyB0cmFuc3BvcnRzXG4gICAgICBpZih0cmFuc3BvcnQucmVtb3ZlRXZlbnRMaXN0ZW5lcilcbiAgICAgICAgdHJhbnNwb3J0LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ21lc3NhZ2UnLCB0cmFuc3BvcnRNZXNzYWdlKTtcblxuICAgICAgLy8gTm9kZS5qcyBTdHJlYW1zIEFQSVxuICAgICAgZWxzZSBpZih0cmFuc3BvcnQucmVtb3ZlTGlzdGVuZXIpXG4gICAgICAgIHRyYW5zcG9ydC5yZW1vdmVMaXN0ZW5lcignZGF0YScsIHRyYW5zcG9ydE1lc3NhZ2UpO1xuICAgIH07XG5cbiAgICAvLyBTZXQgbGlzdGVuZXIgb24gbmV3IHRyYW5zcG9ydFxuICAgIGlmKHZhbHVlKVxuICAgIHtcbiAgICAgIC8vIFczQyB0cmFuc3BvcnRzXG4gICAgICBpZih2YWx1ZS5hZGRFdmVudExpc3RlbmVyKVxuICAgICAgICB2YWx1ZS5hZGRFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgdHJhbnNwb3J0TWVzc2FnZSk7XG5cbiAgICAgIC8vIE5vZGUuanMgU3RyZWFtcyBBUElcbiAgICAgIGVsc2UgaWYodmFsdWUuYWRkTGlzdGVuZXIpXG4gICAgICAgIHZhbHVlLmFkZExpc3RlbmVyKCdkYXRhJywgdHJhbnNwb3J0TWVzc2FnZSk7XG4gICAgfTtcblxuICAgIHRyYW5zcG9ydCA9IHVuaWZ5VHJhbnNwb3J0KHZhbHVlKTtcbiAgfVxuXG4gIGlmKCFkZWZpbmVQcm9wZXJ0eV9JRTgpXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsICd0cmFuc3BvcnQnLFxuICAgIHtcbiAgICAgIGdldDogdGhpcy5nZXRUcmFuc3BvcnQuYmluZCh0aGlzKSxcbiAgICAgIHNldDogdGhpcy5zZXRUcmFuc3BvcnQuYmluZCh0aGlzKVxuICAgIH0pXG5cbiAgdGhpcy5zZXRUcmFuc3BvcnQodHJhbnNwb3J0KTtcblxuXG4gIHZhciByZXF1ZXN0X3RpbWVvdXQgICAgICA9IG9wdGlvbnMucmVxdWVzdF90aW1lb3V0ICAgICAgfHwgQkFTRV9USU1FT1VUO1xuICB2YXIgcGluZ19yZXF1ZXN0X3RpbWVvdXQgPSBvcHRpb25zLnBpbmdfcmVxdWVzdF90aW1lb3V0IHx8IHJlcXVlc3RfdGltZW91dDtcbiAgdmFyIHJlc3BvbnNlX3RpbWVvdXQgICAgID0gb3B0aW9ucy5yZXNwb25zZV90aW1lb3V0ICAgICB8fCBCQVNFX1RJTUVPVVQ7XG4gIHZhciBkdXBsaWNhdGVzX3RpbWVvdXQgICA9IG9wdGlvbnMuZHVwbGljYXRlc190aW1lb3V0ICAgfHwgQkFTRV9USU1FT1VUO1xuXG5cbiAgdmFyIHJlcXVlc3RJRCA9IDA7XG5cbiAgdmFyIHJlcXVlc3RzICA9IG5ldyBNYXBwZXIoKTtcbiAgdmFyIHJlc3BvbnNlcyA9IG5ldyBNYXBwZXIoKTtcbiAgdmFyIHByb2Nlc3NlZFJlc3BvbnNlcyA9IG5ldyBNYXBwZXIoKTtcblxuICB2YXIgbWVzc2FnZTJLZXkgPSB7fTtcblxuXG4gIC8qKlxuICAgKiBTdG9yZSB0aGUgcmVzcG9uc2UgdG8gcHJldmVudCB0byBwcm9jZXNzIGR1cGxpY2F0ZSByZXF1ZXN0IGxhdGVyXG4gICAqL1xuICBmdW5jdGlvbiBzdG9yZVJlc3BvbnNlKG1lc3NhZ2UsIGlkLCBkZXN0KVxuICB7XG4gICAgdmFyIHJlc3BvbnNlID1cbiAgICB7XG4gICAgICBtZXNzYWdlOiBtZXNzYWdlLFxuICAgICAgLyoqIFRpbWVvdXQgdG8gYXV0by1jbGVhbiBvbGQgcmVzcG9uc2VzICovXG4gICAgICB0aW1lb3V0OiBzZXRUaW1lb3V0KGZ1bmN0aW9uKClcbiAgICAgIHtcbiAgICAgICAgcmVzcG9uc2VzLnJlbW92ZShpZCwgZGVzdCk7XG4gICAgICB9LFxuICAgICAgcmVzcG9uc2VfdGltZW91dClcbiAgICB9O1xuXG4gICAgcmVzcG9uc2VzLnNldChyZXNwb25zZSwgaWQsIGRlc3QpO1xuICB9O1xuXG4gIC8qKlxuICAgKiBTdG9yZSB0aGUgcmVzcG9uc2UgdG8gaWdub3JlIGR1cGxpY2F0ZWQgbWVzc2FnZXMgbGF0ZXJcbiAgICovXG4gIGZ1bmN0aW9uIHN0b3JlUHJvY2Vzc2VkUmVzcG9uc2UoYWNrLCBmcm9tKVxuICB7XG4gICAgdmFyIHRpbWVvdXQgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uKClcbiAgICB7XG4gICAgICBwcm9jZXNzZWRSZXNwb25zZXMucmVtb3ZlKGFjaywgZnJvbSk7XG4gICAgfSxcbiAgICBkdXBsaWNhdGVzX3RpbWVvdXQpO1xuXG4gICAgcHJvY2Vzc2VkUmVzcG9uc2VzLnNldCh0aW1lb3V0LCBhY2ssIGZyb20pO1xuICB9O1xuXG5cbiAgLyoqXG4gICAqIFJlcHJlc2VudGF0aW9uIG9mIGEgUlBDIHJlcXVlc3RcbiAgICpcbiAgICogQGNsYXNzXG4gICAqIEBleHRlbmRzIFJwY05vdGlmaWNhdGlvblxuICAgKlxuICAgKiBAY29uc3RydWN0b3JcbiAgICpcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1ldGhvZCAtbWV0aG9kIG9mIHRoZSBub3RpZmljYXRpb25cbiAgICogQHBhcmFtIHBhcmFtcyAtIHBhcmFtZXRlcnMgb2YgdGhlIG5vdGlmaWNhdGlvblxuICAgKiBAcGFyYW0ge0ludGVnZXJ9IGlkIC0gaWRlbnRpZmllciBvZiB0aGUgcmVxdWVzdFxuICAgKiBAcGFyYW0gW2Zyb21dIC0gc291cmNlIG9mIHRoZSBub3RpZmljYXRpb25cbiAgICovXG4gIGZ1bmN0aW9uIFJwY1JlcXVlc3QobWV0aG9kLCBwYXJhbXMsIGlkLCBmcm9tLCB0cmFuc3BvcnQpXG4gIHtcbiAgICBScGNOb3RpZmljYXRpb24uY2FsbCh0aGlzLCBtZXRob2QsIHBhcmFtcyk7XG5cbiAgICB0aGlzLmdldFRyYW5zcG9ydCA9IGZ1bmN0aW9uKClcbiAgICB7XG4gICAgICByZXR1cm4gdHJhbnNwb3J0O1xuICAgIH1cbiAgICB0aGlzLnNldFRyYW5zcG9ydCA9IGZ1bmN0aW9uKHZhbHVlKVxuICAgIHtcbiAgICAgIHRyYW5zcG9ydCA9IHVuaWZ5VHJhbnNwb3J0KHZhbHVlKTtcbiAgICB9XG5cbiAgICBpZighZGVmaW5lUHJvcGVydHlfSUU4KVxuICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsICd0cmFuc3BvcnQnLFxuICAgICAge1xuICAgICAgICBnZXQ6IHRoaXMuZ2V0VHJhbnNwb3J0LmJpbmQodGhpcyksXG4gICAgICAgIHNldDogdGhpcy5zZXRUcmFuc3BvcnQuYmluZCh0aGlzKVxuICAgICAgfSlcblxuICAgIHZhciByZXNwb25zZSA9IHJlc3BvbnNlcy5nZXQoaWQsIGZyb20pO1xuXG4gICAgLyoqXG4gICAgICogQGNvbnN0YW50IHtCb29sZWFufSBkdXBsaWNhdGVkXG4gICAgICovXG4gICAgaWYoISh0cmFuc3BvcnQgfHwgc2VsZi5nZXRUcmFuc3BvcnQoKSkpXG4gICAge1xuICAgICAgaWYoZGVmaW5lUHJvcGVydHlfSUU4KVxuICAgICAgICB0aGlzLmR1cGxpY2F0ZWQgPSBCb29sZWFuKHJlc3BvbnNlKVxuICAgICAgZWxzZVxuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywgJ2R1cGxpY2F0ZWQnLFxuICAgICAgICB7XG4gICAgICAgICAgdmFsdWU6IEJvb2xlYW4ocmVzcG9uc2UpXG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHZhciByZXNwb25zZU1ldGhvZCA9IHJlc3BvbnNlTWV0aG9kc1ttZXRob2RdO1xuXG4gICAgdGhpcy5wYWNrID0gcGFja2VyLnBhY2suYmluZChwYWNrZXIsIHRoaXMsIGlkKVxuXG4gICAgLyoqXG4gICAgICogR2VuZXJhdGUgYSByZXNwb25zZSB0byB0aGlzIHJlcXVlc3RcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7RXJyb3J9IFtlcnJvcl1cbiAgICAgKiBAcGFyYW0geyp9IFtyZXN1bHRdXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfVxuICAgICAqL1xuICAgIHRoaXMucmVwbHkgPSBmdW5jdGlvbihlcnJvciwgcmVzdWx0LCB0cmFuc3BvcnQpXG4gICAge1xuICAgICAgLy8gRml4IG9wdGlvbmFsIHBhcmFtZXRlcnNcbiAgICAgIGlmKGVycm9yIGluc3RhbmNlb2YgRnVuY3Rpb24gfHwgZXJyb3IgJiYgZXJyb3Iuc2VuZCBpbnN0YW5jZW9mIEZ1bmN0aW9uKVxuICAgICAge1xuICAgICAgICBpZihyZXN1bHQgIT0gdW5kZWZpbmVkKVxuICAgICAgICAgIHRocm93IG5ldyBTeW50YXhFcnJvcihcIlRoZXJlIGNhbid0IGJlIHBhcmFtZXRlcnMgYWZ0ZXIgY2FsbGJhY2tcIik7XG5cbiAgICAgICAgdHJhbnNwb3J0ID0gZXJyb3I7XG4gICAgICAgIHJlc3VsdCA9IG51bGw7XG4gICAgICAgIGVycm9yID0gdW5kZWZpbmVkO1xuICAgICAgfVxuXG4gICAgICBlbHNlIGlmKHJlc3VsdCBpbnN0YW5jZW9mIEZ1bmN0aW9uXG4gICAgICB8fCByZXN1bHQgJiYgcmVzdWx0LnNlbmQgaW5zdGFuY2VvZiBGdW5jdGlvbilcbiAgICAgIHtcbiAgICAgICAgaWYodHJhbnNwb3J0ICE9IHVuZGVmaW5lZClcbiAgICAgICAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoXCJUaGVyZSBjYW4ndCBiZSBwYXJhbWV0ZXJzIGFmdGVyIGNhbGxiYWNrXCIpO1xuXG4gICAgICAgIHRyYW5zcG9ydCA9IHJlc3VsdDtcbiAgICAgICAgcmVzdWx0ID0gbnVsbDtcbiAgICAgIH07XG5cbiAgICAgIHRyYW5zcG9ydCA9IHVuaWZ5VHJhbnNwb3J0KHRyYW5zcG9ydCk7XG5cbiAgICAgIC8vIER1cGxpY2F0ZWQgcmVxdWVzdCwgcmVtb3ZlIG9sZCByZXNwb25zZSB0aW1lb3V0XG4gICAgICBpZihyZXNwb25zZSlcbiAgICAgICAgY2xlYXJUaW1lb3V0KHJlc3BvbnNlLnRpbWVvdXQpO1xuXG4gICAgICBpZihmcm9tICE9IHVuZGVmaW5lZClcbiAgICAgIHtcbiAgICAgICAgaWYoZXJyb3IpXG4gICAgICAgICAgZXJyb3IuZGVzdCA9IGZyb207XG5cbiAgICAgICAgaWYocmVzdWx0KVxuICAgICAgICAgIHJlc3VsdC5kZXN0ID0gZnJvbTtcbiAgICAgIH07XG5cbiAgICAgIHZhciBtZXNzYWdlO1xuXG4gICAgICAvLyBOZXcgcmVxdWVzdCBvciBvdmVycmlkZW4gb25lLCBjcmVhdGUgbmV3IHJlc3BvbnNlIHdpdGggcHJvdmlkZWQgZGF0YVxuICAgICAgaWYoZXJyb3IgfHwgcmVzdWx0ICE9IHVuZGVmaW5lZClcbiAgICAgIHtcbiAgICAgICAgaWYoc2VsZi5wZWVySUQgIT0gdW5kZWZpbmVkKVxuICAgICAgICB7XG4gICAgICAgICAgaWYoZXJyb3IpXG4gICAgICAgICAgICBlcnJvci5mcm9tID0gc2VsZi5wZWVySUQ7XG4gICAgICAgICAgZWxzZVxuICAgICAgICAgICAgcmVzdWx0LmZyb20gPSBzZWxmLnBlZXJJRDtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFByb3RvY29sIGluZGljYXRlcyB0aGF0IHJlc3BvbnNlcyBoYXMgb3duIHJlcXVlc3QgbWV0aG9kc1xuICAgICAgICBpZihyZXNwb25zZU1ldGhvZClcbiAgICAgICAge1xuICAgICAgICAgIGlmKHJlc3BvbnNlTWV0aG9kLmVycm9yID09IHVuZGVmaW5lZCAmJiBlcnJvcilcbiAgICAgICAgICAgIG1lc3NhZ2UgPVxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBlcnJvcjogZXJyb3JcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICBlbHNlXG4gICAgICAgICAge1xuICAgICAgICAgICAgdmFyIG1ldGhvZCA9IGVycm9yXG4gICAgICAgICAgICAgICAgICAgICAgID8gcmVzcG9uc2VNZXRob2QuZXJyb3JcbiAgICAgICAgICAgICAgICAgICAgICAgOiByZXNwb25zZU1ldGhvZC5yZXNwb25zZTtcblxuICAgICAgICAgICAgbWVzc2FnZSA9XG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIG1ldGhvZDogbWV0aG9kLFxuICAgICAgICAgICAgICBwYXJhbXM6IGVycm9yIHx8IHJlc3VsdFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZVxuICAgICAgICAgIG1lc3NhZ2UgPVxuICAgICAgICAgIHtcbiAgICAgICAgICAgIGVycm9yOiAgZXJyb3IsXG4gICAgICAgICAgICByZXN1bHQ6IHJlc3VsdFxuICAgICAgICAgIH07XG5cbiAgICAgICAgbWVzc2FnZSA9IHBhY2tlci5wYWNrKG1lc3NhZ2UsIGlkKTtcbiAgICAgIH1cblxuICAgICAgLy8gRHVwbGljYXRlICYgbm90LW92ZXJyaWRlbiByZXF1ZXN0LCByZS1zZW5kIG9sZCByZXNwb25zZVxuICAgICAgZWxzZSBpZihyZXNwb25zZSlcbiAgICAgICAgbWVzc2FnZSA9IHJlc3BvbnNlLm1lc3NhZ2U7XG5cbiAgICAgIC8vIE5ldyBlbXB0eSByZXBseSwgcmVzcG9uc2UgbnVsbCB2YWx1ZVxuICAgICAgZWxzZVxuICAgICAgICBtZXNzYWdlID0gcGFja2VyLnBhY2soe3Jlc3VsdDogbnVsbH0sIGlkKTtcblxuICAgICAgLy8gU3RvcmUgdGhlIHJlc3BvbnNlIHRvIHByZXZlbnQgdG8gcHJvY2VzcyBhIGR1cGxpY2F0ZWQgcmVxdWVzdCBsYXRlclxuICAgICAgc3RvcmVSZXNwb25zZShtZXNzYWdlLCBpZCwgZnJvbSk7XG5cbiAgICAgIC8vIFJldHVybiB0aGUgc3RvcmVkIHJlc3BvbnNlIHNvIGl0IGNhbiBiZSBkaXJlY3RseSBzZW5kIGJhY2tcbiAgICAgIHRyYW5zcG9ydCA9IHRyYW5zcG9ydCB8fCB0aGlzLmdldFRyYW5zcG9ydCgpIHx8IHNlbGYuZ2V0VHJhbnNwb3J0KCk7XG5cbiAgICAgIGlmKHRyYW5zcG9ydClcbiAgICAgICAgcmV0dXJuIHRyYW5zcG9ydC5zZW5kKG1lc3NhZ2UpO1xuXG4gICAgICByZXR1cm4gbWVzc2FnZTtcbiAgICB9XG4gIH07XG4gIGluaGVyaXRzKFJwY1JlcXVlc3QsIFJwY05vdGlmaWNhdGlvbik7XG5cblxuICBmdW5jdGlvbiBjYW5jZWwobWVzc2FnZSlcbiAge1xuICAgIHZhciBrZXkgPSBtZXNzYWdlMktleVttZXNzYWdlXTtcbiAgICBpZigha2V5KSByZXR1cm47XG5cbiAgICBkZWxldGUgbWVzc2FnZTJLZXlbbWVzc2FnZV07XG5cbiAgICB2YXIgcmVxdWVzdCA9IHJlcXVlc3RzLnBvcChrZXkuaWQsIGtleS5kZXN0KTtcbiAgICBpZighcmVxdWVzdCkgcmV0dXJuO1xuXG4gICAgY2xlYXJUaW1lb3V0KHJlcXVlc3QudGltZW91dCk7XG5cbiAgICAvLyBTdGFydCBkdXBsaWNhdGVkIHJlc3BvbnNlcyB0aW1lb3V0XG4gICAgc3RvcmVQcm9jZXNzZWRSZXNwb25zZShrZXkuaWQsIGtleS5kZXN0KTtcbiAgfTtcblxuICAvKipcbiAgICogQWxsb3cgdG8gY2FuY2VsIGEgcmVxdWVzdCBhbmQgZG9uJ3Qgd2FpdCBmb3IgYSByZXNwb25zZVxuICAgKlxuICAgKiBJZiBgbWVzc2FnZWAgaXMgbm90IGdpdmVuLCBjYW5jZWwgYWxsIHRoZSByZXF1ZXN0XG4gICAqL1xuICB0aGlzLmNhbmNlbCA9IGZ1bmN0aW9uKG1lc3NhZ2UpXG4gIHtcbiAgICBpZihtZXNzYWdlKSByZXR1cm4gY2FuY2VsKG1lc3NhZ2UpO1xuXG4gICAgZm9yKHZhciBtZXNzYWdlIGluIG1lc3NhZ2UyS2V5KVxuICAgICAgY2FuY2VsKG1lc3NhZ2UpO1xuICB9O1xuXG5cbiAgdGhpcy5jbG9zZSA9IGZ1bmN0aW9uKClcbiAge1xuICAgIC8vIFByZXZlbnQgdG8gcmVjZWl2ZSBuZXcgbWVzc2FnZXNcbiAgICB2YXIgdHJhbnNwb3J0ID0gdGhpcy5nZXRUcmFuc3BvcnQoKTtcbiAgICBpZih0cmFuc3BvcnQgJiYgdHJhbnNwb3J0LmNsb3NlKVxuICAgICAgIHRyYW5zcG9ydC5jbG9zZSgpO1xuXG4gICAgLy8gUmVxdWVzdCAmIHByb2Nlc3NlZCByZXNwb25zZXNcbiAgICB0aGlzLmNhbmNlbCgpO1xuXG4gICAgcHJvY2Vzc2VkUmVzcG9uc2VzLmZvckVhY2goY2xlYXJUaW1lb3V0KTtcblxuICAgIC8vIFJlc3BvbnNlc1xuICAgIHJlc3BvbnNlcy5mb3JFYWNoKGZ1bmN0aW9uKHJlc3BvbnNlKVxuICAgIHtcbiAgICAgIGNsZWFyVGltZW91dChyZXNwb25zZS50aW1lb3V0KTtcbiAgICB9KTtcbiAgfTtcblxuXG4gIC8qKlxuICAgKiBHZW5lcmF0ZXMgYW5kIGVuY29kZSBhIEpzb25SUEMgMi4wIG1lc3NhZ2VcbiAgICpcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1ldGhvZCAtbWV0aG9kIG9mIHRoZSBub3RpZmljYXRpb25cbiAgICogQHBhcmFtIHBhcmFtcyAtIHBhcmFtZXRlcnMgb2YgdGhlIG5vdGlmaWNhdGlvblxuICAgKiBAcGFyYW0gW2Rlc3RdIC0gZGVzdGluYXRpb24gb2YgdGhlIG5vdGlmaWNhdGlvblxuICAgKiBAcGFyYW0ge29iamVjdH0gW3RyYW5zcG9ydF0gLSB0cmFuc3BvcnQgd2hlcmUgdG8gc2VuZCB0aGUgbWVzc2FnZVxuICAgKiBAcGFyYW0gW2NhbGxiYWNrXSAtIGZ1bmN0aW9uIGNhbGxlZCB3aGVuIGEgcmVzcG9uc2UgdG8gdGhpcyByZXF1ZXN0IGlzXG4gICAqICAgcmVjZWl2ZWQuIElmIG5vdCBkZWZpbmVkLCBhIG5vdGlmaWNhdGlvbiB3aWxsIGJlIHNlbmQgaW5zdGVhZFxuICAgKlxuICAgKiBAcmV0dXJucyB7c3RyaW5nfSBBIHJhdyBKc29uUlBDIDIuMCByZXF1ZXN0IG9yIG5vdGlmaWNhdGlvbiBzdHJpbmdcbiAgICovXG4gIHRoaXMuZW5jb2RlID0gZnVuY3Rpb24obWV0aG9kLCBwYXJhbXMsIGRlc3QsIHRyYW5zcG9ydCwgY2FsbGJhY2spXG4gIHtcbiAgICAvLyBGaXggb3B0aW9uYWwgcGFyYW1ldGVyc1xuICAgIGlmKHBhcmFtcyBpbnN0YW5jZW9mIEZ1bmN0aW9uKVxuICAgIHtcbiAgICAgIGlmKGRlc3QgIT0gdW5kZWZpbmVkKVxuICAgICAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoXCJUaGVyZSBjYW4ndCBiZSBwYXJhbWV0ZXJzIGFmdGVyIGNhbGxiYWNrXCIpO1xuXG4gICAgICBjYWxsYmFjayAgPSBwYXJhbXM7XG4gICAgICB0cmFuc3BvcnQgPSB1bmRlZmluZWQ7XG4gICAgICBkZXN0ICAgICAgPSB1bmRlZmluZWQ7XG4gICAgICBwYXJhbXMgICAgPSB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgZWxzZSBpZihkZXN0IGluc3RhbmNlb2YgRnVuY3Rpb24pXG4gICAge1xuICAgICAgaWYodHJhbnNwb3J0ICE9IHVuZGVmaW5lZClcbiAgICAgICAgdGhyb3cgbmV3IFN5bnRheEVycm9yKFwiVGhlcmUgY2FuJ3QgYmUgcGFyYW1ldGVycyBhZnRlciBjYWxsYmFja1wiKTtcblxuICAgICAgY2FsbGJhY2sgID0gZGVzdDtcbiAgICAgIHRyYW5zcG9ydCA9IHVuZGVmaW5lZDtcbiAgICAgIGRlc3QgICAgICA9IHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICBlbHNlIGlmKHRyYW5zcG9ydCBpbnN0YW5jZW9mIEZ1bmN0aW9uKVxuICAgIHtcbiAgICAgIGlmKGNhbGxiYWNrICE9IHVuZGVmaW5lZClcbiAgICAgICAgdGhyb3cgbmV3IFN5bnRheEVycm9yKFwiVGhlcmUgY2FuJ3QgYmUgcGFyYW1ldGVycyBhZnRlciBjYWxsYmFja1wiKTtcblxuICAgICAgY2FsbGJhY2sgID0gdHJhbnNwb3J0O1xuICAgICAgdHJhbnNwb3J0ID0gdW5kZWZpbmVkO1xuICAgIH07XG5cbiAgICBpZihzZWxmLnBlZXJJRCAhPSB1bmRlZmluZWQpXG4gICAge1xuICAgICAgcGFyYW1zID0gcGFyYW1zIHx8IHt9O1xuXG4gICAgICBwYXJhbXMuZnJvbSA9IHNlbGYucGVlcklEO1xuICAgIH07XG5cbiAgICBpZihkZXN0ICE9IHVuZGVmaW5lZClcbiAgICB7XG4gICAgICBwYXJhbXMgPSBwYXJhbXMgfHwge307XG5cbiAgICAgIHBhcmFtcy5kZXN0ID0gZGVzdDtcbiAgICB9O1xuXG4gICAgLy8gRW5jb2RlIG1lc3NhZ2VcbiAgICB2YXIgbWVzc2FnZSA9XG4gICAge1xuICAgICAgbWV0aG9kOiBtZXRob2QsXG4gICAgICBwYXJhbXM6IHBhcmFtc1xuICAgIH07XG5cbiAgICBpZihjYWxsYmFjaylcbiAgICB7XG4gICAgICB2YXIgaWQgPSByZXF1ZXN0SUQrKztcbiAgICAgIHZhciByZXRyaWVkID0gMDtcblxuICAgICAgbWVzc2FnZSA9IHBhY2tlci5wYWNrKG1lc3NhZ2UsIGlkKTtcblxuICAgICAgZnVuY3Rpb24gZGlzcGF0Y2hDYWxsYmFjayhlcnJvciwgcmVzdWx0KVxuICAgICAge1xuICAgICAgICBzZWxmLmNhbmNlbChtZXNzYWdlKTtcblxuICAgICAgICBjYWxsYmFjayhlcnJvciwgcmVzdWx0KTtcbiAgICAgIH07XG5cbiAgICAgIHZhciByZXF1ZXN0ID1cbiAgICAgIHtcbiAgICAgICAgbWVzc2FnZTogICAgICAgICBtZXNzYWdlLFxuICAgICAgICBjYWxsYmFjazogICAgICAgIGRpc3BhdGNoQ2FsbGJhY2ssXG4gICAgICAgIHJlc3BvbnNlTWV0aG9kczogcmVzcG9uc2VNZXRob2RzW21ldGhvZF0gfHwge31cbiAgICAgIH07XG5cbiAgICAgIHZhciBlbmNvZGVfdHJhbnNwb3J0ID0gdW5pZnlUcmFuc3BvcnQodHJhbnNwb3J0KTtcblxuICAgICAgZnVuY3Rpb24gc2VuZFJlcXVlc3QodHJhbnNwb3J0KVxuICAgICAge1xuICAgICAgICB2YXIgcnQgPSAobWV0aG9kID09PSAncGluZycgPyBwaW5nX3JlcXVlc3RfdGltZW91dCA6IHJlcXVlc3RfdGltZW91dCk7XG4gICAgICAgIHJlcXVlc3QudGltZW91dCA9IHNldFRpbWVvdXQodGltZW91dCwgcnQqTWF0aC5wb3coMiwgcmV0cmllZCsrKSk7XG4gICAgICAgIG1lc3NhZ2UyS2V5W21lc3NhZ2VdID0ge2lkOiBpZCwgZGVzdDogZGVzdH07XG4gICAgICAgIHJlcXVlc3RzLnNldChyZXF1ZXN0LCBpZCwgZGVzdCk7XG5cbiAgICAgICAgdHJhbnNwb3J0ID0gdHJhbnNwb3J0IHx8IGVuY29kZV90cmFuc3BvcnQgfHwgc2VsZi5nZXRUcmFuc3BvcnQoKTtcbiAgICAgICAgaWYodHJhbnNwb3J0KVxuICAgICAgICAgIHJldHVybiB0cmFuc3BvcnQuc2VuZChtZXNzYWdlKTtcblxuICAgICAgICByZXR1cm4gbWVzc2FnZTtcbiAgICAgIH07XG5cbiAgICAgIGZ1bmN0aW9uIHJldHJ5KHRyYW5zcG9ydClcbiAgICAgIHtcbiAgICAgICAgdHJhbnNwb3J0ID0gdW5pZnlUcmFuc3BvcnQodHJhbnNwb3J0KTtcblxuICAgICAgICBjb25zb2xlLndhcm4ocmV0cmllZCsnIHJldHJ5IGZvciByZXF1ZXN0IG1lc3NhZ2U6JyxtZXNzYWdlKTtcblxuICAgICAgICB2YXIgdGltZW91dCA9IHByb2Nlc3NlZFJlc3BvbnNlcy5wb3AoaWQsIGRlc3QpO1xuICAgICAgICBjbGVhclRpbWVvdXQodGltZW91dCk7XG5cbiAgICAgICAgcmV0dXJuIHNlbmRSZXF1ZXN0KHRyYW5zcG9ydCk7XG4gICAgICB9O1xuXG4gICAgICBmdW5jdGlvbiB0aW1lb3V0KClcbiAgICAgIHtcbiAgICAgICAgaWYocmV0cmllZCA8IG1heF9yZXRyaWVzKVxuICAgICAgICAgIHJldHVybiByZXRyeSh0cmFuc3BvcnQpO1xuXG4gICAgICAgIHZhciBlcnJvciA9IG5ldyBFcnJvcignUmVxdWVzdCBoYXMgdGltZWQgb3V0Jyk7XG4gICAgICAgICAgICBlcnJvci5yZXF1ZXN0ID0gbWVzc2FnZTtcblxuICAgICAgICBlcnJvci5yZXRyeSA9IHJldHJ5O1xuXG4gICAgICAgIGRpc3BhdGNoQ2FsbGJhY2soZXJyb3IpXG4gICAgICB9O1xuXG4gICAgICByZXR1cm4gc2VuZFJlcXVlc3QodHJhbnNwb3J0KTtcbiAgICB9O1xuXG4gICAgLy8gUmV0dXJuIHRoZSBwYWNrZWQgbWVzc2FnZVxuICAgIG1lc3NhZ2UgPSBwYWNrZXIucGFjayhtZXNzYWdlKTtcblxuICAgIHRyYW5zcG9ydCA9IHRyYW5zcG9ydCB8fCB0aGlzLmdldFRyYW5zcG9ydCgpO1xuICAgIGlmKHRyYW5zcG9ydClcbiAgICAgIHJldHVybiB0cmFuc3BvcnQuc2VuZChtZXNzYWdlKTtcblxuICAgIHJldHVybiBtZXNzYWdlO1xuICB9O1xuXG4gIC8qKlxuICAgKiBEZWNvZGUgYW5kIHByb2Nlc3MgYSBKc29uUlBDIDIuMCBtZXNzYWdlXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBtZXNzYWdlIC0gc3RyaW5nIHdpdGggdGhlIGNvbnRlbnQgb2YgdGhlIG1lc3NhZ2VcbiAgICpcbiAgICogQHJldHVybnMge1JwY05vdGlmaWNhdGlvbnxScGNSZXF1ZXN0fHVuZGVmaW5lZH0gLSB0aGUgcmVwcmVzZW50YXRpb24gb2YgdGhlXG4gICAqICAgbm90aWZpY2F0aW9uIG9yIHRoZSByZXF1ZXN0LiBJZiBhIHJlc3BvbnNlIHdhcyBwcm9jZXNzZWQsIGl0IHdpbGwgcmV0dXJuXG4gICAqICAgYHVuZGVmaW5lZGAgdG8gbm90aWZ5IHRoYXQgaXQgd2FzIHByb2Nlc3NlZFxuICAgKlxuICAgKiBAdGhyb3dzIHtUeXBlRXJyb3J9IC0gTWVzc2FnZSBpcyBub3QgZGVmaW5lZFxuICAgKi9cbiAgdGhpcy5kZWNvZGUgPSBmdW5jdGlvbihtZXNzYWdlLCB0cmFuc3BvcnQpXG4gIHtcbiAgICBpZighbWVzc2FnZSlcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJNZXNzYWdlIGlzIG5vdCBkZWZpbmVkXCIpO1xuXG4gICAgdHJ5XG4gICAge1xuICAgICAgbWVzc2FnZSA9IHBhY2tlci51bnBhY2sobWVzc2FnZSk7XG4gICAgfVxuICAgIGNhdGNoKGUpXG4gICAge1xuICAgICAgLy8gSWdub3JlIGludmFsaWQgbWVzc2FnZXNcbiAgICAgIHJldHVybiBjb25zb2xlLmRlYnVnKGUsIG1lc3NhZ2UpO1xuICAgIH07XG5cbiAgICB2YXIgaWQgICAgID0gbWVzc2FnZS5pZDtcbiAgICB2YXIgYWNrICAgID0gbWVzc2FnZS5hY2s7XG4gICAgdmFyIG1ldGhvZCA9IG1lc3NhZ2UubWV0aG9kO1xuICAgIHZhciBwYXJhbXMgPSBtZXNzYWdlLnBhcmFtcyB8fCB7fTtcblxuICAgIHZhciBmcm9tID0gcGFyYW1zLmZyb207XG4gICAgdmFyIGRlc3QgPSBwYXJhbXMuZGVzdDtcblxuICAgIC8vIElnbm9yZSBtZXNzYWdlcyBzZW5kIGJ5IHVzXG4gICAgaWYoc2VsZi5wZWVySUQgIT0gdW5kZWZpbmVkICYmIGZyb20gPT0gc2VsZi5wZWVySUQpIHJldHVybjtcblxuICAgIC8vIE5vdGlmaWNhdGlvblxuICAgIGlmKGlkID09IHVuZGVmaW5lZCAmJiBhY2sgPT0gdW5kZWZpbmVkKVxuICAgIHtcbiAgICAgIHZhciBub3RpZmljYXRpb24gPSBuZXcgUnBjTm90aWZpY2F0aW9uKG1ldGhvZCwgcGFyYW1zKTtcblxuICAgICAgaWYoc2VsZi5lbWl0KCdyZXF1ZXN0Jywgbm90aWZpY2F0aW9uKSkgcmV0dXJuO1xuICAgICAgcmV0dXJuIG5vdGlmaWNhdGlvbjtcbiAgICB9O1xuXG5cbiAgICBmdW5jdGlvbiBwcm9jZXNzUmVxdWVzdCgpXG4gICAge1xuICAgICAgLy8gSWYgd2UgaGF2ZSBhIHRyYW5zcG9ydCBhbmQgaXQncyBhIGR1cGxpY2F0ZWQgcmVxdWVzdCwgcmVwbHkgaW5tZWRpYXRseVxuICAgICAgdHJhbnNwb3J0ID0gdW5pZnlUcmFuc3BvcnQodHJhbnNwb3J0KSB8fCBzZWxmLmdldFRyYW5zcG9ydCgpO1xuICAgICAgaWYodHJhbnNwb3J0KVxuICAgICAge1xuICAgICAgICB2YXIgcmVzcG9uc2UgPSByZXNwb25zZXMuZ2V0KGlkLCBmcm9tKTtcbiAgICAgICAgaWYocmVzcG9uc2UpXG4gICAgICAgICAgcmV0dXJuIHRyYW5zcG9ydC5zZW5kKHJlc3BvbnNlLm1lc3NhZ2UpO1xuICAgICAgfTtcblxuICAgICAgdmFyIGlkQWNrID0gKGlkICE9IHVuZGVmaW5lZCkgPyBpZCA6IGFjaztcbiAgICAgIHZhciByZXF1ZXN0ID0gbmV3IFJwY1JlcXVlc3QobWV0aG9kLCBwYXJhbXMsIGlkQWNrLCBmcm9tLCB0cmFuc3BvcnQpO1xuXG4gICAgICBpZihzZWxmLmVtaXQoJ3JlcXVlc3QnLCByZXF1ZXN0KSkgcmV0dXJuO1xuICAgICAgcmV0dXJuIHJlcXVlc3Q7XG4gICAgfTtcblxuICAgIGZ1bmN0aW9uIHByb2Nlc3NSZXNwb25zZShyZXF1ZXN0LCBlcnJvciwgcmVzdWx0KVxuICAgIHtcbiAgICAgIHJlcXVlc3QuY2FsbGJhY2soZXJyb3IsIHJlc3VsdCk7XG4gICAgfTtcblxuICAgIGZ1bmN0aW9uIGR1cGxpY2F0ZWRSZXNwb25zZSh0aW1lb3V0KVxuICAgIHtcbiAgICAgIGNvbnNvbGUud2FybihcIlJlc3BvbnNlIGFscmVhZHkgcHJvY2Vzc2VkXCIsIG1lc3NhZ2UpO1xuXG4gICAgICAvLyBVcGRhdGUgZHVwbGljYXRlZCByZXNwb25zZXMgdGltZW91dFxuICAgICAgY2xlYXJUaW1lb3V0KHRpbWVvdXQpO1xuICAgICAgc3RvcmVQcm9jZXNzZWRSZXNwb25zZShhY2ssIGZyb20pO1xuICAgIH07XG5cblxuICAgIC8vIFJlcXVlc3QsIG9yIHJlc3BvbnNlIHdpdGggb3duIG1ldGhvZFxuICAgIGlmKG1ldGhvZClcbiAgICB7XG4gICAgICAvLyBDaGVjayBpZiBpdCdzIGEgcmVzcG9uc2Ugd2l0aCBvd24gbWV0aG9kXG4gICAgICBpZihkZXN0ID09IHVuZGVmaW5lZCB8fCBkZXN0ID09IHNlbGYucGVlcklEKVxuICAgICAge1xuICAgICAgICB2YXIgcmVxdWVzdCA9IHJlcXVlc3RzLmdldChhY2ssIGZyb20pO1xuICAgICAgICBpZihyZXF1ZXN0KVxuICAgICAgICB7XG4gICAgICAgICAgdmFyIHJlc3BvbnNlTWV0aG9kcyA9IHJlcXVlc3QucmVzcG9uc2VNZXRob2RzO1xuXG4gICAgICAgICAgaWYobWV0aG9kID09IHJlc3BvbnNlTWV0aG9kcy5lcnJvcilcbiAgICAgICAgICAgIHJldHVybiBwcm9jZXNzUmVzcG9uc2UocmVxdWVzdCwgcGFyYW1zKTtcblxuICAgICAgICAgIGlmKG1ldGhvZCA9PSByZXNwb25zZU1ldGhvZHMucmVzcG9uc2UpXG4gICAgICAgICAgICByZXR1cm4gcHJvY2Vzc1Jlc3BvbnNlKHJlcXVlc3QsIG51bGwsIHBhcmFtcyk7XG5cbiAgICAgICAgICByZXR1cm4gcHJvY2Vzc1JlcXVlc3QoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBwcm9jZXNzZWQgPSBwcm9jZXNzZWRSZXNwb25zZXMuZ2V0KGFjaywgZnJvbSk7XG4gICAgICAgIGlmKHByb2Nlc3NlZClcbiAgICAgICAgICByZXR1cm4gZHVwbGljYXRlZFJlc3BvbnNlKHByb2Nlc3NlZCk7XG4gICAgICB9XG5cbiAgICAgIC8vIFJlcXVlc3RcbiAgICAgIHJldHVybiBwcm9jZXNzUmVxdWVzdCgpO1xuICAgIH07XG5cbiAgICB2YXIgZXJyb3IgID0gbWVzc2FnZS5lcnJvcjtcbiAgICB2YXIgcmVzdWx0ID0gbWVzc2FnZS5yZXN1bHQ7XG5cbiAgICAvLyBJZ25vcmUgcmVzcG9uc2VzIG5vdCBzZW5kIHRvIHVzXG4gICAgaWYoZXJyb3IgICYmIGVycm9yLmRlc3QgICYmIGVycm9yLmRlc3QgICE9IHNlbGYucGVlcklEKSByZXR1cm47XG4gICAgaWYocmVzdWx0ICYmIHJlc3VsdC5kZXN0ICYmIHJlc3VsdC5kZXN0ICE9IHNlbGYucGVlcklEKSByZXR1cm47XG5cbiAgICAvLyBSZXNwb25zZVxuICAgIHZhciByZXF1ZXN0ID0gcmVxdWVzdHMuZ2V0KGFjaywgZnJvbSk7XG4gICAgaWYoIXJlcXVlc3QpXG4gICAge1xuICAgICAgdmFyIHByb2Nlc3NlZCA9IHByb2Nlc3NlZFJlc3BvbnNlcy5nZXQoYWNrLCBmcm9tKTtcbiAgICAgIGlmKHByb2Nlc3NlZClcbiAgICAgICAgcmV0dXJuIGR1cGxpY2F0ZWRSZXNwb25zZShwcm9jZXNzZWQpO1xuXG4gICAgICByZXR1cm4gY29uc29sZS53YXJuKFwiTm8gY2FsbGJhY2sgd2FzIGRlZmluZWQgZm9yIHRoaXMgbWVzc2FnZVwiLCBtZXNzYWdlKTtcbiAgICB9O1xuXG4gICAgLy8gUHJvY2VzcyByZXNwb25zZVxuICAgIHByb2Nlc3NSZXNwb25zZShyZXF1ZXN0LCBlcnJvciwgcmVzdWx0KTtcbiAgfTtcbn07XG5pbmhlcml0cyhScGNCdWlsZGVyLCBFdmVudEVtaXR0ZXIpO1xuXG5cblJwY0J1aWxkZXIuUnBjTm90aWZpY2F0aW9uID0gUnBjTm90aWZpY2F0aW9uO1xuXG5cbm1vZHVsZS5leHBvcnRzID0gUnBjQnVpbGRlcjtcblxudmFyIGNsaWVudHMgPSByZXF1aXJlKCcuL2NsaWVudHMnKTtcbnZhciB0cmFuc3BvcnRzID0gcmVxdWlyZSgnLi9jbGllbnRzL3RyYW5zcG9ydHMnKTtcblxuUnBjQnVpbGRlci5jbGllbnRzID0gY2xpZW50cztcblJwY0J1aWxkZXIuY2xpZW50cy50cmFuc3BvcnRzID0gdHJhbnNwb3J0cztcblJwY0J1aWxkZXIucGFja2VycyA9IHBhY2tlcnM7XG4iLCIvKipcbiAqIEpzb25SUEMgMi4wIHBhY2tlclxuICovXG5cbi8qKlxuICogUGFjayBhIEpzb25SUEMgMi4wIG1lc3NhZ2VcbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gbWVzc2FnZSAtIG9iamVjdCB0byBiZSBwYWNrYWdlZC4gSXQgcmVxdWlyZXMgdG8gaGF2ZSBhbGwgdGhlXG4gKiAgIGZpZWxkcyBuZWVkZWQgYnkgdGhlIEpzb25SUEMgMi4wIG1lc3NhZ2UgdGhhdCBpdCdzIGdvaW5nIHRvIGJlIGdlbmVyYXRlZFxuICpcbiAqIEByZXR1cm4ge1N0cmluZ30gLSB0aGUgc3RyaW5naWZpZWQgSnNvblJQQyAyLjAgbWVzc2FnZVxuICovXG5mdW5jdGlvbiBwYWNrKG1lc3NhZ2UsIGlkKVxue1xuICB2YXIgcmVzdWx0ID1cbiAge1xuICAgIGpzb25ycGM6IFwiMi4wXCJcbiAgfTtcblxuICAvLyBSZXF1ZXN0XG4gIGlmKG1lc3NhZ2UubWV0aG9kKVxuICB7XG4gICAgcmVzdWx0Lm1ldGhvZCA9IG1lc3NhZ2UubWV0aG9kO1xuXG4gICAgaWYobWVzc2FnZS5wYXJhbXMpXG4gICAgICByZXN1bHQucGFyYW1zID0gbWVzc2FnZS5wYXJhbXM7XG5cbiAgICAvLyBSZXF1ZXN0IGlzIGEgbm90aWZpY2F0aW9uXG4gICAgaWYoaWQgIT0gdW5kZWZpbmVkKVxuICAgICAgcmVzdWx0LmlkID0gaWQ7XG4gIH1cblxuICAvLyBSZXNwb25zZVxuICBlbHNlIGlmKGlkICE9IHVuZGVmaW5lZClcbiAge1xuICAgIGlmKG1lc3NhZ2UuZXJyb3IpXG4gICAge1xuICAgICAgaWYobWVzc2FnZS5yZXN1bHQgIT09IHVuZGVmaW5lZClcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkJvdGggcmVzdWx0IGFuZCBlcnJvciBhcmUgZGVmaW5lZFwiKTtcblxuICAgICAgcmVzdWx0LmVycm9yID0gbWVzc2FnZS5lcnJvcjtcbiAgICB9XG4gICAgZWxzZSBpZihtZXNzYWdlLnJlc3VsdCAhPT0gdW5kZWZpbmVkKVxuICAgICAgcmVzdWx0LnJlc3VsdCA9IG1lc3NhZ2UucmVzdWx0O1xuICAgIGVsc2VcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJObyByZXN1bHQgb3IgZXJyb3IgaXMgZGVmaW5lZFwiKTtcblxuICAgIHJlc3VsdC5pZCA9IGlkO1xuICB9O1xuXG4gIHJldHVybiBKU09OLnN0cmluZ2lmeShyZXN1bHQpO1xufTtcblxuLyoqXG4gKiBVbnBhY2sgYSBKc29uUlBDIDIuMCBtZXNzYWdlXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2UgLSBzdHJpbmcgd2l0aCB0aGUgY29udGVudCBvZiB0aGUgSnNvblJQQyAyLjAgbWVzc2FnZVxuICpcbiAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gLSBJbnZhbGlkIEpzb25SUEMgdmVyc2lvblxuICpcbiAqIEByZXR1cm4ge09iamVjdH0gLSBvYmplY3QgZmlsbGVkIHdpdGggdGhlIEpzb25SUEMgMi4wIG1lc3NhZ2UgY29udGVudFxuICovXG5mdW5jdGlvbiB1bnBhY2sobWVzc2FnZSlcbntcbiAgdmFyIHJlc3VsdCA9IG1lc3NhZ2U7XG5cbiAgaWYodHlwZW9mIG1lc3NhZ2UgPT09ICdzdHJpbmcnIHx8IG1lc3NhZ2UgaW5zdGFuY2VvZiBTdHJpbmcpIHtcbiAgICByZXN1bHQgPSBKU09OLnBhcnNlKG1lc3NhZ2UpO1xuICB9XG5cbiAgLy8gQ2hlY2sgaWYgaXQncyBhIHZhbGlkIG1lc3NhZ2VcblxuICB2YXIgdmVyc2lvbiA9IHJlc3VsdC5qc29ucnBjO1xuICBpZih2ZXJzaW9uICE9PSAnMi4wJylcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiSW52YWxpZCBKc29uUlBDIHZlcnNpb24gJ1wiICsgdmVyc2lvbiArIFwiJzogXCIgKyBtZXNzYWdlKTtcblxuICAvLyBSZXNwb25zZVxuICBpZihyZXN1bHQubWV0aG9kID09IHVuZGVmaW5lZClcbiAge1xuICAgIGlmKHJlc3VsdC5pZCA9PSB1bmRlZmluZWQpXG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiSW52YWxpZCBtZXNzYWdlOiBcIittZXNzYWdlKTtcblxuICAgIHZhciByZXN1bHRfZGVmaW5lZCA9IHJlc3VsdC5yZXN1bHQgIT09IHVuZGVmaW5lZDtcbiAgICB2YXIgZXJyb3JfZGVmaW5lZCAgPSByZXN1bHQuZXJyb3IgICE9PSB1bmRlZmluZWQ7XG5cbiAgICAvLyBDaGVjayBvbmx5IHJlc3VsdCBvciBlcnJvciBpcyBkZWZpbmVkLCBub3QgYm90aCBvciBub25lXG4gICAgaWYocmVzdWx0X2RlZmluZWQgJiYgZXJyb3JfZGVmaW5lZClcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJCb3RoIHJlc3VsdCBhbmQgZXJyb3IgYXJlIGRlZmluZWQ6IFwiK21lc3NhZ2UpO1xuXG4gICAgaWYoIXJlc3VsdF9kZWZpbmVkICYmICFlcnJvcl9kZWZpbmVkKVxuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIk5vIHJlc3VsdCBvciBlcnJvciBpcyBkZWZpbmVkOiBcIittZXNzYWdlKTtcblxuICAgIHJlc3VsdC5hY2sgPSByZXN1bHQuaWQ7XG4gICAgZGVsZXRlIHJlc3VsdC5pZDtcbiAgfVxuXG4gIC8vIFJldHVybiB1bnBhY2tlZCBtZXNzYWdlXG4gIHJldHVybiByZXN1bHQ7XG59O1xuXG5cbmV4cG9ydHMucGFjayAgID0gcGFjaztcbmV4cG9ydHMudW5wYWNrID0gdW5wYWNrO1xuIiwiZnVuY3Rpb24gcGFjayhtZXNzYWdlKVxue1xuICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiTm90IHlldCBpbXBsZW1lbnRlZFwiKTtcbn07XG5cbmZ1bmN0aW9uIHVucGFjayhtZXNzYWdlKVxue1xuICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiTm90IHlldCBpbXBsZW1lbnRlZFwiKTtcbn07XG5cblxuZXhwb3J0cy5wYWNrICAgPSBwYWNrO1xuZXhwb3J0cy51bnBhY2sgPSB1bnBhY2s7XG4iLCJ2YXIgSnNvblJQQyA9IHJlcXVpcmUoJy4vSnNvblJQQycpO1xudmFyIFhtbFJQQyAgPSByZXF1aXJlKCcuL1htbFJQQycpO1xuXG5cbmV4cG9ydHMuSnNvblJQQyA9IEpzb25SUEM7XG5leHBvcnRzLlhtbFJQQyAgPSBYbWxSUEM7XG4iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE0LTIwMTUgS3VyZW50byAoaHR0cDovL2t1cmVudG8ub3JnLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICovXG5cbnZhciBmcmVlaWNlID0gcmVxdWlyZSgnZnJlZWljZScpXG52YXIgaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpXG52YXIgVUFQYXJzZXIgPSByZXF1aXJlKCd1YS1wYXJzZXItanMnKVxudmFyIHV1aWQgPSByZXF1aXJlKCd1dWlkJylcbnZhciBoYXJrID0gcmVxdWlyZSgnaGFyaycpXG5cbnZhciBFdmVudEVtaXR0ZXIgPSByZXF1aXJlKCdldmVudHMnKS5FdmVudEVtaXR0ZXJcbnZhciByZWN1cnNpdmUgPSByZXF1aXJlKCdtZXJnZScpLnJlY3Vyc2l2ZS5iaW5kKHVuZGVmaW5lZCwgdHJ1ZSlcbnZhciBzZHBUcmFuc2xhdG9yID0gcmVxdWlyZSgnc2RwLXRyYW5zbGF0b3InKVxudmFyIGxvZ2dlciA9IHdpbmRvdy5Mb2dnZXIgfHwgY29uc29sZVxuXG4vLyB2YXIgZ1VNID0gbmF2aWdhdG9yLm1lZGlhRGV2aWNlcy5nZXRVc2VyTWVkaWEgfHwgZnVuY3Rpb24gKGNvbnN0cmFpbnRzKSB7XG4vLyAgIHJldHVybiBuZXcgUHJvbWlzZShuYXZpZ2F0b3IuZ2V0VXNlck1lZGlhKGNvbnN0cmFpbnRzLCBmdW5jdGlvbiAoc3RyZWFtKSB7XG4vLyAgICAgdmlkZW9TdHJlYW0gPSBzdHJlYW1cbi8vICAgICBzdGFydCgpXG4vLyAgIH0pLmVyb3IoY2FsbGJhY2spKTtcbi8vIH1cblxuLyp0cnkge1xuICByZXF1aXJlKCdrdXJlbnRvLWJyb3dzZXItZXh0ZW5zaW9ucycpXG59IGNhdGNoIChlcnJvcikge1xuICBpZiAodHlwZW9mIGdldFNjcmVlbkNvbnN0cmFpbnRzID09PSAndW5kZWZpbmVkJykge1xuICAgIGxvZ2dlci53YXJuKCdzY3JlZW4gc2hhcmluZyBpcyBub3QgYXZhaWxhYmxlJylcblxuICAgIGdldFNjcmVlbkNvbnN0cmFpbnRzID0gZnVuY3Rpb24gZ2V0U2NyZWVuQ29uc3RyYWludHMoc2VuZFNvdXJjZSwgY2FsbGJhY2spIHtcbiAgICAgIGNhbGxiYWNrKG5ldyBFcnJvcihcIlRoaXMgbGlicmFyeSBpcyBub3QgZW5hYmxlZCBmb3Igc2NyZWVuIHNoYXJpbmdcIikpXG4gICAgfVxuICB9XG59Ki9cblxudmFyIE1FRElBX0NPTlNUUkFJTlRTID0ge1xuICBhdWRpbzogdHJ1ZSxcbiAgdmlkZW86IHtcbiAgICB3aWR0aDogNjQwLFxuICAgIGZyYW1lcmF0ZTogMTVcbiAgfVxufVxuXG4vLyBTb21laG93LCB0aGUgVUFQYXJzZXIgY29uc3RydWN0b3IgZ2V0cyBhbiBlbXB0eSB3aW5kb3cgb2JqZWN0LlxuLy8gV2UgbmVlZCB0byBwYXNzIHRoZSB1c2VyIGFnZW50IHN0cmluZyBpbiBvcmRlciB0byBnZXQgaW5mb3JtYXRpb25cbnZhciB1YSA9ICh3aW5kb3cgJiYgd2luZG93Lm5hdmlnYXRvcikgPyB3aW5kb3cubmF2aWdhdG9yLnVzZXJBZ2VudCA6ICcnXG52YXIgcGFyc2VyID0gbmV3IFVBUGFyc2VyKHVhKVxudmFyIGJyb3dzZXIgPSBwYXJzZXIuZ2V0QnJvd3NlcigpXG5cbnZhciB1c2VQbGFuQiA9IGZhbHNlXG5pZiAoYnJvd3Nlci5uYW1lID09PSAnQ2hyb21lJyB8fCBicm93c2VyLm5hbWUgPT09ICdDaHJvbWl1bScpIHtcbiAgbG9nZ2VyLmRlYnVnKGJyb3dzZXIubmFtZSArIFwiOiB1c2luZyBTRFAgUGxhbkJcIilcbiAgdXNlUGxhbkIgPSB0cnVlXG59XG5cbmZ1bmN0aW9uIG5vb3AoZXJyb3IpIHtcbiAgaWYgKGVycm9yKSBsb2dnZXIuZXJyb3IoZXJyb3IpXG59XG5cbmZ1bmN0aW9uIHRyYWNrU3RvcCh0cmFjaykge1xuICB0cmFjay5zdG9wICYmIHRyYWNrLnN0b3AoKVxufVxuXG5mdW5jdGlvbiBzdHJlYW1TdG9wKHN0cmVhbSkge1xuICBzdHJlYW0uZ2V0VHJhY2tzKCkuZm9yRWFjaCh0cmFja1N0b3ApXG59XG5cbi8qKlxuICogUmV0dXJucyBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiBhIFNlc3Npb25EZXNjcmlwdGlvbiBvYmplY3QuXG4gKi9cbnZhciBkdW1wU0RQID0gZnVuY3Rpb24gKGRlc2NyaXB0aW9uKSB7XG4gIGlmICh0eXBlb2YgZGVzY3JpcHRpb24gPT09ICd1bmRlZmluZWQnIHx8IGRlc2NyaXB0aW9uID09PSBudWxsKSB7XG4gICAgcmV0dXJuICcnXG4gIH1cblxuICByZXR1cm4gJ3R5cGU6ICcgKyBkZXNjcmlwdGlvbi50eXBlICsgJ1xcclxcbicgKyBkZXNjcmlwdGlvbi5zZHBcbn1cblxuZnVuY3Rpb24gYnVmZmVyaXplQ2FuZGlkYXRlcyhwYywgb25lcnJvcikge1xuICB2YXIgY2FuZGlkYXRlc1F1ZXVlID0gW11cblxuICBwYy5hZGRFdmVudExpc3RlbmVyKCdzaWduYWxpbmdzdGF0ZWNoYW5nZScsIGZ1bmN0aW9uICgpIHtcbiAgICBpZiAodGhpcy5zaWduYWxpbmdTdGF0ZSA9PT0gJ3N0YWJsZScpIHtcbiAgICAgIHdoaWxlIChjYW5kaWRhdGVzUXVldWUubGVuZ3RoKSB7XG4gICAgICAgIHZhciBlbnRyeSA9IGNhbmRpZGF0ZXNRdWV1ZS5zaGlmdCgpXG5cbiAgICAgICAgdGhpcy5hZGRJY2VDYW5kaWRhdGUoZW50cnkuY2FuZGlkYXRlLCBlbnRyeS5jYWxsYmFjaywgZW50cnkuY2FsbGJhY2spXG4gICAgICB9XG4gICAgfVxuICB9KVxuXG4gIHJldHVybiBmdW5jdGlvbiAoY2FuZGlkYXRlLCBjYWxsYmFjaykge1xuICAgIGNhbGxiYWNrID0gY2FsbGJhY2sgfHwgb25lcnJvclxuXG4gICAgc3dpdGNoIChwYy5zaWduYWxpbmdTdGF0ZSkge1xuICAgIGNhc2UgJ2Nsb3NlZCc6XG4gICAgICBjYWxsYmFjayhuZXcgRXJyb3IoJ1BlZXJDb25uZWN0aW9uIG9iamVjdCBpcyBjbG9zZWQnKSlcbiAgICAgIGJyZWFrXG4gICAgY2FzZSAnc3RhYmxlJzpcbiAgICAgIGlmIChwYy5yZW1vdGVEZXNjcmlwdGlvbikge1xuICAgICAgICBwYy5hZGRJY2VDYW5kaWRhdGUoY2FuZGlkYXRlLCBjYWxsYmFjaywgY2FsbGJhY2spXG4gICAgICAgIGJyZWFrXG4gICAgICB9XG4gICAgZGVmYXVsdDpcbiAgICAgIGNhbmRpZGF0ZXNRdWV1ZS5wdXNoKHtcbiAgICAgICAgY2FuZGlkYXRlOiBjYW5kaWRhdGUsXG4gICAgICAgIGNhbGxiYWNrOiBjYWxsYmFja1xuICAgICAgfSlcbiAgICB9XG4gIH1cbn1cblxuLyogU2ltdWxjYXN0IHV0aWxpdGllcyAqL1xuXG5mdW5jdGlvbiByZW1vdmVGSURGcm9tT2ZmZXIoc2RwKSB7XG4gIHZhciBuID0gc2RwLmluZGV4T2YoXCJhPXNzcmMtZ3JvdXA6RklEXCIpO1xuXG4gIGlmIChuID4gMCkge1xuICAgIHJldHVybiBzZHAuc2xpY2UoMCwgbik7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIHNkcDtcbiAgfVxufVxuXG5mdW5jdGlvbiBnZXRTaW11bGNhc3RJbmZvKHZpZGVvU3RyZWFtKSB7XG4gIHZhciB2aWRlb1RyYWNrcyA9IHZpZGVvU3RyZWFtLmdldFZpZGVvVHJhY2tzKCk7XG4gIGlmICghdmlkZW9UcmFja3MubGVuZ3RoKSB7XG4gICAgbG9nZ2VyLndhcm4oJ05vIHZpZGVvIHRyYWNrcyBhdmFpbGFibGUgaW4gdGhlIHZpZGVvIHN0cmVhbScpXG4gICAgcmV0dXJuICcnXG4gIH1cbiAgdmFyIGxpbmVzID0gW1xuICAgICdhPXgtZ29vZ2xlLWZsYWc6Y29uZmVyZW5jZScsXG4gICAgJ2E9c3NyYy1ncm91cDpTSU0gMSAyIDMnLFxuICAgICdhPXNzcmM6MSBjbmFtZTpsb2NhbFZpZGVvJyxcbiAgICAnYT1zc3JjOjEgbXNpZDonICsgdmlkZW9TdHJlYW0uaWQgKyAnICcgKyB2aWRlb1RyYWNrc1swXS5pZCxcbiAgICAnYT1zc3JjOjEgbXNsYWJlbDonICsgdmlkZW9TdHJlYW0uaWQsXG4gICAgJ2E9c3NyYzoxIGxhYmVsOicgKyB2aWRlb1RyYWNrc1swXS5pZCxcbiAgICAnYT1zc3JjOjIgY25hbWU6bG9jYWxWaWRlbycsXG4gICAgJ2E9c3NyYzoyIG1zaWQ6JyArIHZpZGVvU3RyZWFtLmlkICsgJyAnICsgdmlkZW9UcmFja3NbMF0uaWQsXG4gICAgJ2E9c3NyYzoyIG1zbGFiZWw6JyArIHZpZGVvU3RyZWFtLmlkLFxuICAgICdhPXNzcmM6MiBsYWJlbDonICsgdmlkZW9UcmFja3NbMF0uaWQsXG4gICAgJ2E9c3NyYzozIGNuYW1lOmxvY2FsVmlkZW8nLFxuICAgICdhPXNzcmM6MyBtc2lkOicgKyB2aWRlb1N0cmVhbS5pZCArICcgJyArIHZpZGVvVHJhY2tzWzBdLmlkLFxuICAgICdhPXNzcmM6MyBtc2xhYmVsOicgKyB2aWRlb1N0cmVhbS5pZCxcbiAgICAnYT1zc3JjOjMgbGFiZWw6JyArIHZpZGVvVHJhY2tzWzBdLmlkXG4gIF07XG5cbiAgbGluZXMucHVzaCgnJyk7XG5cbiAgcmV0dXJuIGxpbmVzLmpvaW4oJ1xcbicpO1xufVxuXG4vKipcbiAqIFdyYXBwZXIgb2JqZWN0IG9mIGFuIFJUQ1BlZXJDb25uZWN0aW9uLiBUaGlzIG9iamVjdCBpcyBhaW1lZCB0byBzaW1wbGlmeSB0aGVcbiAqIGRldmVsb3BtZW50IG9mIFdlYlJUQy1iYXNlZCBhcHBsaWNhdGlvbnMuXG4gKlxuICogQGNvbnN0cnVjdG9yIG1vZHVsZTprdXJlbnRvVXRpbHMuV2ViUnRjUGVlclxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBtb2RlIE1vZGUgaW4gd2hpY2ggdGhlIFBlZXJDb25uZWN0aW9uIHdpbGwgYmUgY29uZmlndXJlZC5cbiAqICBWYWxpZCB2YWx1ZXMgYXJlOiAncmVjdicsICdzZW5kJywgYW5kICdzZW5kUmVjdidcbiAqIEBwYXJhbSBsb2NhbFZpZGVvIFZpZGVvIHRhZyBmb3IgdGhlIGxvY2FsIHN0cmVhbVxuICogQHBhcmFtIHJlbW90ZVZpZGVvIFZpZGVvIHRhZyBmb3IgdGhlIHJlbW90ZSBzdHJlYW1cbiAqIEBwYXJhbSB7TWVkaWFTdHJlYW19IHZpZGVvU3RyZWFtIFN0cmVhbSB0byBiZSB1c2VkIGFzIHByaW1hcnkgc291cmNlXG4gKiAgKHR5cGljYWxseSB2aWRlbyBhbmQgYXVkaW8sIG9yIG9ubHkgdmlkZW8gaWYgY29tYmluZWQgd2l0aCBhdWRpb1N0cmVhbSkgZm9yXG4gKiAgbG9jYWxWaWRlbyBhbmQgdG8gYmUgYWRkZWQgYXMgc3RyZWFtIHRvIHRoZSBSVENQZWVyQ29ubmVjdGlvblxuICogQHBhcmFtIHtNZWRpYVN0cmVhbX0gYXVkaW9TdHJlYW0gU3RyZWFtIHRvIGJlIHVzZWQgYXMgc2Vjb25kIHNvdXJjZVxuICogICh0eXBpY2FsbHkgZm9yIGF1ZGlvKSBmb3IgbG9jYWxWaWRlbyBhbmQgdG8gYmUgYWRkZWQgYXMgc3RyZWFtIHRvIHRoZVxuICogIFJUQ1BlZXJDb25uZWN0aW9uXG4gKi9cbmZ1bmN0aW9uIFdlYlJ0Y1BlZXIobW9kZSwgb3B0aW9ucywgY2FsbGJhY2spIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIFdlYlJ0Y1BlZXIpKSB7XG4gICAgcmV0dXJuIG5ldyBXZWJSdGNQZWVyKG1vZGUsIG9wdGlvbnMsIGNhbGxiYWNrKVxuICB9XG5cbiAgV2ViUnRjUGVlci5zdXBlcl8uY2FsbCh0aGlzKVxuXG4gIGlmIChvcHRpb25zIGluc3RhbmNlb2YgRnVuY3Rpb24pIHtcbiAgICBjYWxsYmFjayA9IG9wdGlvbnNcbiAgICBvcHRpb25zID0gdW5kZWZpbmVkXG4gIH1cblxuICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fVxuICBjYWxsYmFjayA9IChjYWxsYmFjayB8fCBub29wKS5iaW5kKHRoaXMpXG5cbiAgdmFyIHNlbGYgPSB0aGlzXG4gIHZhciBsb2NhbFZpZGVvID0gb3B0aW9ucy5sb2NhbFZpZGVvXG4gIHZhciByZW1vdGVWaWRlbyA9IG9wdGlvbnMucmVtb3RlVmlkZW9cbiAgdmFyIHZpZGVvU3RyZWFtID0gb3B0aW9ucy52aWRlb1N0cmVhbVxuICB2YXIgYXVkaW9TdHJlYW0gPSBvcHRpb25zLmF1ZGlvU3RyZWFtXG4gIHZhciBtZWRpYUNvbnN0cmFpbnRzID0gb3B0aW9ucy5tZWRpYUNvbnN0cmFpbnRzXG5cbiAgdmFyIGNvbm5lY3Rpb25Db25zdHJhaW50cyA9IG9wdGlvbnMuY29ubmVjdGlvbkNvbnN0cmFpbnRzXG4gIHZhciBwYyA9IG9wdGlvbnMucGVlckNvbm5lY3Rpb25cbiAgdmFyIHNlbmRTb3VyY2UgPSBvcHRpb25zLnNlbmRTb3VyY2UgfHwgJ3dlYmNhbSdcblxuICB2YXIgZGF0YUNoYW5uZWxDb25maWcgPSBvcHRpb25zLmRhdGFDaGFubmVsQ29uZmlnXG4gIHZhciB1c2VEYXRhQ2hhbm5lbHMgPSBvcHRpb25zLmRhdGFDaGFubmVscyB8fCBmYWxzZVxuICB2YXIgZGF0YUNoYW5uZWxcblxuICB2YXIgZ3VpZCA9IHV1aWQudjQoKVxuICB2YXIgY29uZmlndXJhdGlvbiA9IHJlY3Vyc2l2ZSh7XG4gICAgICBpY2VTZXJ2ZXJzOiBmcmVlaWNlKClcbiAgICB9LFxuICAgIG9wdGlvbnMuY29uZmlndXJhdGlvbilcblxuICB2YXIgb25pY2VjYW5kaWRhdGUgPSBvcHRpb25zLm9uaWNlY2FuZGlkYXRlXG4gIGlmIChvbmljZWNhbmRpZGF0ZSkgdGhpcy5vbignaWNlY2FuZGlkYXRlJywgb25pY2VjYW5kaWRhdGUpXG5cbiAgdmFyIG9uY2FuZGlkYXRlZ2F0aGVyaW5nZG9uZSA9IG9wdGlvbnMub25jYW5kaWRhdGVnYXRoZXJpbmdkb25lXG4gIGlmIChvbmNhbmRpZGF0ZWdhdGhlcmluZ2RvbmUpIHtcbiAgICB0aGlzLm9uKCdjYW5kaWRhdGVnYXRoZXJpbmdkb25lJywgb25jYW5kaWRhdGVnYXRoZXJpbmdkb25lKVxuICB9XG5cbiAgdmFyIHNpbXVsY2FzdCA9IG9wdGlvbnMuc2ltdWxjYXN0XG4gIHZhciBtdWx0aXN0cmVhbSA9IG9wdGlvbnMubXVsdGlzdHJlYW1cbiAgdmFyIGludGVyb3AgPSBuZXcgc2RwVHJhbnNsYXRvci5JbnRlcm9wKClcbiAgdmFyIGNhbmRpZGF0ZXNRdWV1ZU91dCA9IFtdXG4gIHZhciBjYW5kaWRhdGVnYXRoZXJpbmdkb25lID0gZmFsc2VcblxuICBPYmplY3QuZGVmaW5lUHJvcGVydGllcyh0aGlzLCB7XG4gICAgJ3BlZXJDb25uZWN0aW9uJzoge1xuICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBwY1xuICAgICAgfVxuICAgIH0sXG5cbiAgICAnaWQnOiB7XG4gICAgICB2YWx1ZTogb3B0aW9ucy5pZCB8fCBndWlkLFxuICAgICAgd3JpdGFibGU6IGZhbHNlXG4gICAgfSxcblxuICAgICdyZW1vdGVWaWRlbyc6IHtcbiAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gcmVtb3RlVmlkZW9cbiAgICAgIH1cbiAgICB9LFxuXG4gICAgJ2xvY2FsVmlkZW8nOiB7XG4gICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIGxvY2FsVmlkZW9cbiAgICAgIH1cbiAgICB9LFxuXG4gICAgJ2RhdGFDaGFubmVsJzoge1xuICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBkYXRhQ2hhbm5lbFxuICAgICAgfVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBAbWVtYmVyIHsoZXh0ZXJuYWw6SW1hZ2VEYXRhfHVuZGVmaW5lZCl9IGN1cnJlbnRGcmFtZVxuICAgICAqL1xuICAgICdjdXJyZW50RnJhbWUnOiB7XG4gICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgLy8gW1RvRG9dIEZpbmQgc29sdXRpb24gd2hlbiB3ZSBoYXZlIGEgcmVtb3RlIHN0cmVhbSBidXQgd2UgZGlkbid0IHNldFxuICAgICAgICAvLyBhIHJlbW90ZVZpZGVvIHRhZ1xuICAgICAgICBpZiAoIXJlbW90ZVZpZGVvKSByZXR1cm47XG5cbiAgICAgICAgaWYgKHJlbW90ZVZpZGVvLnJlYWR5U3RhdGUgPCByZW1vdGVWaWRlby5IQVZFX0NVUlJFTlRfREFUQSlcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ05vIHZpZGVvIHN0cmVhbSBkYXRhIGF2YWlsYWJsZScpXG5cbiAgICAgICAgdmFyIGNhbnZhcyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2NhbnZhcycpXG4gICAgICAgIGNhbnZhcy53aWR0aCA9IHJlbW90ZVZpZGVvLnZpZGVvV2lkdGhcbiAgICAgICAgY2FudmFzLmhlaWdodCA9IHJlbW90ZVZpZGVvLnZpZGVvSGVpZ2h0XG5cbiAgICAgICAgY2FudmFzLmdldENvbnRleHQoJzJkJykuZHJhd0ltYWdlKHJlbW90ZVZpZGVvLCAwLCAwKVxuXG4gICAgICAgIHJldHVybiBjYW52YXNcbiAgICAgIH1cbiAgICB9XG4gIH0pXG5cbiAgLy8gSW5pdCBQZWVyQ29ubmVjdGlvblxuICBpZiAoIXBjKSB7XG4gICAgcGMgPSBuZXcgUlRDUGVlckNvbm5lY3Rpb24oY29uZmlndXJhdGlvbik7XG4gICAgaWYgKHVzZURhdGFDaGFubmVscyAmJiAhZGF0YUNoYW5uZWwpIHtcbiAgICAgIHZhciBkY0lkID0gJ1dlYlJ0Y1BlZXItJyArIHNlbGYuaWRcbiAgICAgIHZhciBkY09wdGlvbnMgPSB1bmRlZmluZWRcbiAgICAgIGlmIChkYXRhQ2hhbm5lbENvbmZpZykge1xuICAgICAgICBkY0lkID0gZGF0YUNoYW5uZWxDb25maWcuaWQgfHwgZGNJZFxuICAgICAgICBkY09wdGlvbnMgPSBkYXRhQ2hhbm5lbENvbmZpZy5vcHRpb25zXG4gICAgICB9XG4gICAgICBkYXRhQ2hhbm5lbCA9IHBjLmNyZWF0ZURhdGFDaGFubmVsKGRjSWQsIGRjT3B0aW9ucyk7XG4gICAgICBpZiAoZGF0YUNoYW5uZWxDb25maWcpIHtcbiAgICAgICAgZGF0YUNoYW5uZWwub25vcGVuID0gZGF0YUNoYW5uZWxDb25maWcub25vcGVuO1xuICAgICAgICBkYXRhQ2hhbm5lbC5vbmNsb3NlID0gZGF0YUNoYW5uZWxDb25maWcub25jbG9zZTtcbiAgICAgICAgZGF0YUNoYW5uZWwub25tZXNzYWdlID0gZGF0YUNoYW5uZWxDb25maWcub25tZXNzYWdlO1xuICAgICAgICBkYXRhQ2hhbm5lbC5vbmJ1ZmZlcmVkYW1vdW50bG93ID0gZGF0YUNoYW5uZWxDb25maWcub25idWZmZXJlZGFtb3VudGxvdztcbiAgICAgICAgZGF0YUNoYW5uZWwub25lcnJvciA9IGRhdGFDaGFubmVsQ29uZmlnLm9uZXJyb3IgfHwgbm9vcDtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwYy5hZGRFdmVudExpc3RlbmVyKCdpY2VjYW5kaWRhdGUnLCBmdW5jdGlvbiAoZXZlbnQpIHtcbiAgICB2YXIgY2FuZGlkYXRlID0gZXZlbnQuY2FuZGlkYXRlXG5cbiAgICBpZiAoRXZlbnRFbWl0dGVyLmxpc3RlbmVyQ291bnQoc2VsZiwgJ2ljZWNhbmRpZGF0ZScpIHx8XG4gICAgICBFdmVudEVtaXR0ZXIubGlzdGVuZXJDb3VudChcbiAgICAgICAgc2VsZiwgJ2NhbmRpZGF0ZWdhdGhlcmluZ2RvbmUnKSkge1xuICAgICAgaWYgKGNhbmRpZGF0ZSkge1xuICAgICAgICB2YXIgY2FuZFxuXG4gICAgICAgIGlmIChtdWx0aXN0cmVhbSAmJiB1c2VQbGFuQikge1xuICAgICAgICAgIGNhbmQgPSBpbnRlcm9wLmNhbmRpZGF0ZVRvVW5pZmllZFBsYW4oY2FuZGlkYXRlKVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNhbmQgPSBjYW5kaWRhdGVcbiAgICAgICAgfVxuXG4gICAgICAgIHNlbGYuZW1pdCgnaWNlY2FuZGlkYXRlJywgY2FuZClcbiAgICAgICAgY2FuZGlkYXRlZ2F0aGVyaW5nZG9uZSA9IGZhbHNlXG4gICAgICB9IGVsc2UgaWYgKCFjYW5kaWRhdGVnYXRoZXJpbmdkb25lKSB7XG4gICAgICAgIHNlbGYuZW1pdCgnY2FuZGlkYXRlZ2F0aGVyaW5nZG9uZScpXG4gICAgICAgIGNhbmRpZGF0ZWdhdGhlcmluZ2RvbmUgPSB0cnVlXG4gICAgICB9XG4gICAgfSBlbHNlIGlmICghY2FuZGlkYXRlZ2F0aGVyaW5nZG9uZSkge1xuICAgICAgLy8gTm90IGxpc3RlbmluZyB0byAnaWNlY2FuZGlkYXRlJyBvciAnY2FuZGlkYXRlZ2F0aGVyaW5nZG9uZScgZXZlbnRzLCBxdWV1ZVxuICAgICAgLy8gdGhlIGNhbmRpZGF0ZSB1bnRpbCBvbmUgb2YgdGhlbSBpcyBsaXN0ZW5lZFxuICAgICAgY2FuZGlkYXRlc1F1ZXVlT3V0LnB1c2goY2FuZGlkYXRlKVxuXG4gICAgICBpZiAoIWNhbmRpZGF0ZSkgY2FuZGlkYXRlZ2F0aGVyaW5nZG9uZSA9IHRydWVcbiAgICB9XG4gIH0pXG5cbiAgcGMub250cmFjayA9IG9wdGlvbnMub25hZGRzdHJlYW1cbiAgcGMub25uZWdvdGlhdGlvbm5lZWRlZCA9IG9wdGlvbnMub25uZWdvdGlhdGlvbm5lZWRlZFxuICB0aGlzLm9uKCduZXdMaXN0ZW5lcicsIGZ1bmN0aW9uIChldmVudCwgbGlzdGVuZXIpIHtcbiAgICBpZiAoZXZlbnQgPT09ICdpY2VjYW5kaWRhdGUnIHx8IGV2ZW50ID09PSAnY2FuZGlkYXRlZ2F0aGVyaW5nZG9uZScpIHtcbiAgICAgIHdoaWxlIChjYW5kaWRhdGVzUXVldWVPdXQubGVuZ3RoKSB7XG4gICAgICAgIHZhciBjYW5kaWRhdGUgPSBjYW5kaWRhdGVzUXVldWVPdXQuc2hpZnQoKVxuXG4gICAgICAgIGlmICghY2FuZGlkYXRlID09PSAoZXZlbnQgPT09ICdjYW5kaWRhdGVnYXRoZXJpbmdkb25lJykpIHtcbiAgICAgICAgICBsaXN0ZW5lcihjYW5kaWRhdGUpXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH0pXG5cbiAgdmFyIGFkZEljZUNhbmRpZGF0ZSA9IGJ1ZmZlcml6ZUNhbmRpZGF0ZXMocGMpXG5cbiAgLyoqXG4gICAqIENhbGxiYWNrIGZ1bmN0aW9uIGludm9rZWQgd2hlbiBhbiBJQ0UgY2FuZGlkYXRlIGlzIHJlY2VpdmVkLiBEZXZlbG9wZXJzIGFyZVxuICAgKiBleHBlY3RlZCB0byBpbnZva2UgdGhpcyBmdW5jdGlvbiBpbiBvcmRlciB0byBjb21wbGV0ZSB0aGUgU0RQIG5lZ290aWF0aW9uLlxuICAgKlxuICAgKiBAZnVuY3Rpb24gbW9kdWxlOmt1cmVudG9VdGlscy5XZWJSdGNQZWVyLnByb3RvdHlwZS5hZGRJY2VDYW5kaWRhdGVcbiAgICpcbiAgICogQHBhcmFtIGljZUNhbmRpZGF0ZSAtIExpdGVyYWwgb2JqZWN0IHdpdGggdGhlIElDRSBjYW5kaWRhdGUgZGVzY3JpcHRpb25cbiAgICogQHBhcmFtIGNhbGxiYWNrIC0gQ2FsbGVkIHdoZW4gdGhlIElDRSBjYW5kaWRhdGUgaGFzIGJlZW4gYWRkZWQuXG4gICAqL1xuICB0aGlzLmFkZEljZUNhbmRpZGF0ZSA9IGZ1bmN0aW9uIChpY2VDYW5kaWRhdGUsIGNhbGxiYWNrKSB7XG4gICAgdmFyIGNhbmRpZGF0ZVxuXG4gICAgaWYgKG11bHRpc3RyZWFtICYmIHVzZVBsYW5CKSB7XG4gICAgICBjYW5kaWRhdGUgPSBpbnRlcm9wLmNhbmRpZGF0ZVRvUGxhbkIoaWNlQ2FuZGlkYXRlKVxuICAgIH0gZWxzZSB7XG4gICAgICBjYW5kaWRhdGUgPSBuZXcgUlRDSWNlQ2FuZGlkYXRlKGljZUNhbmRpZGF0ZSlcbiAgICB9XG5cbiAgICBsb2dnZXIuZGVidWcoJ1JlbW90ZSBJQ0UgY2FuZGlkYXRlIHJlY2VpdmVkJywgaWNlQ2FuZGlkYXRlKVxuICAgIGNhbGxiYWNrID0gKGNhbGxiYWNrIHx8IG5vb3ApLmJpbmQodGhpcylcbiAgICBhZGRJY2VDYW5kaWRhdGUoY2FuZGlkYXRlLCBjYWxsYmFjaylcbiAgfVxuXG4gIHRoaXMuZ2VuZXJhdGVPZmZlciA9IGZ1bmN0aW9uIChjYWxsYmFjaykge1xuICAgIGNhbGxiYWNrID0gY2FsbGJhY2suYmluZCh0aGlzKVxuXG4gICAgdmFyIG9mZmVyQXVkaW8gPSB0cnVlXG4gICAgdmFyIG9mZmVyVmlkZW8gPSB0cnVlXG4gICAgLy8gQ29uc3RyYWludHMgbXVzdCBoYXZlIGJvdGggYmxvY2tzXG4gICAgaWYgKG1lZGlhQ29uc3RyYWludHMpIHtcbiAgICAgIG9mZmVyQXVkaW8gPSAodHlwZW9mIG1lZGlhQ29uc3RyYWludHMuYXVkaW8gPT09ICdib29sZWFuJykgP1xuICAgICAgICBtZWRpYUNvbnN0cmFpbnRzLmF1ZGlvIDogdHJ1ZVxuICAgICAgb2ZmZXJWaWRlbyA9ICh0eXBlb2YgbWVkaWFDb25zdHJhaW50cy52aWRlbyA9PT0gJ2Jvb2xlYW4nKSA/XG4gICAgICAgIG1lZGlhQ29uc3RyYWludHMudmlkZW8gOiB0cnVlXG4gICAgfVxuXG4gICAgdmFyIGJyb3dzZXJEZXBlbmRhbnRDb25zdHJhaW50cyA9IHtcbiAgICAgIG9mZmVyVG9SZWNlaXZlQXVkaW86IChtb2RlICE9PSAnc2VuZG9ubHknICYmIG9mZmVyQXVkaW8pLFxuICAgICAgb2ZmZXJUb1JlY2VpdmVWaWRlbzogKG1vZGUgIT09ICdzZW5kb25seScgJiYgb2ZmZXJWaWRlbylcbiAgICB9XG5cbiAgICAvL0ZJWE1FOiBjbGFyaWZ5IHBvc3NpYmxlIGNvbnN0cmFpbnRzIHBhc3NlZCB0byBjcmVhdGVPZmZlcigpXG4gICAgLyp2YXIgY29uc3RyYWludHMgPSByZWN1cnNpdmUoYnJvd3NlckRlcGVuZGFudENvbnN0cmFpbnRzLFxuICAgICAgY29ubmVjdGlvbkNvbnN0cmFpbnRzKSovXG5cbiAgICB2YXIgY29uc3RyYWludHMgPSBicm93c2VyRGVwZW5kYW50Q29uc3RyYWludHM7XG5cbiAgICBsb2dnZXIuZGVidWcoJ2NvbnN0cmFpbnRzOiAnICsgSlNPTi5zdHJpbmdpZnkoY29uc3RyYWludHMpKVxuXG4gICAgcGMuY3JlYXRlT2ZmZXIoY29uc3RyYWludHMpLnRoZW4oZnVuY3Rpb24gKG9mZmVyKSB7XG4gICAgICBsb2dnZXIuZGVidWcoJ0NyZWF0ZWQgU0RQIG9mZmVyJylcbiAgICAgIG9mZmVyID0gbWFuZ2xlU2RwVG9BZGRTaW11bGNhc3Qob2ZmZXIpXG4gICAgICByZXR1cm4gcGMuc2V0TG9jYWxEZXNjcmlwdGlvbihvZmZlcilcbiAgICB9KS50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciBsb2NhbERlc2NyaXB0aW9uID0gcGMubG9jYWxEZXNjcmlwdGlvblxuICAgICAgbG9nZ2VyLmRlYnVnKCdMb2NhbCBkZXNjcmlwdGlvbiBzZXQnLCBsb2NhbERlc2NyaXB0aW9uLnNkcClcbiAgICAgIGlmIChtdWx0aXN0cmVhbSAmJiB1c2VQbGFuQikge1xuICAgICAgICBsb2NhbERlc2NyaXB0aW9uID0gaW50ZXJvcC50b1VuaWZpZWRQbGFuKGxvY2FsRGVzY3JpcHRpb24pXG4gICAgICAgIGxvZ2dlci5kZWJ1Zygnb2ZmZXI6Om9yaWdQbGFuQi0+VW5pZmllZFBsYW4nLCBkdW1wU0RQKFxuICAgICAgICAgIGxvY2FsRGVzY3JpcHRpb24pKVxuICAgICAgfVxuICAgICAgY2FsbGJhY2sobnVsbCwgbG9jYWxEZXNjcmlwdGlvbi5zZHAsIHNlbGYucHJvY2Vzc0Fuc3dlci5iaW5kKFxuICAgICAgICBzZWxmKSlcbiAgICB9KS5jYXRjaChjYWxsYmFjaylcbiAgfVxuXG4gIHRoaXMuZ2V0TG9jYWxTZXNzaW9uRGVzY3JpcHRvciA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gcGMubG9jYWxEZXNjcmlwdGlvblxuICB9XG5cbiAgdGhpcy5nZXRSZW1vdGVTZXNzaW9uRGVzY3JpcHRvciA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gcGMucmVtb3RlRGVzY3JpcHRpb25cbiAgfVxuXG4gIGZ1bmN0aW9uIHNldFJlbW90ZVZpZGVvKCkge1xuICAgIGlmIChyZW1vdGVWaWRlbykge1xuICAgICAgdmFyIHN0cmVhbSA9IHBjLmdldFJlbW90ZVN0cmVhbXMoKVswXVxuICAgICAgdmFyIHVybCA9IHN0cmVhbSA/IFVSTC5jcmVhdGVPYmplY3RVUkwoc3RyZWFtKSA6ICcnXG5cbiAgICAgIHJlbW90ZVZpZGVvLnBhdXNlKClcbiAgICAgIHJlbW90ZVZpZGVvLnNyYyA9IHVybFxuICAgICAgcmVtb3RlVmlkZW8ubG9hZCgpXG5cbiAgICAgIGxvZ2dlci5kZWJ1ZygnUmVtb3RlIFVSTDonLCB1cmwpXG4gICAgfVxuICB9XG5cbiAgdGhpcy5zaG93TG9jYWxWaWRlbyA9IGZ1bmN0aW9uICgpIHtcbiAgICBsb2NhbFZpZGVvLnNyYyA9IFVSTC5jcmVhdGVPYmplY3RVUkwodmlkZW9TdHJlYW0pXG4gICAgbG9jYWxWaWRlby5tdXRlZCA9IHRydWVcbiAgfVxuXG4gIHRoaXMuc2VuZCA9IGZ1bmN0aW9uIChkYXRhKSB7XG4gICAgaWYgKGRhdGFDaGFubmVsICYmIGRhdGFDaGFubmVsLnJlYWR5U3RhdGUgPT09ICdvcGVuJykge1xuICAgICAgZGF0YUNoYW5uZWwuc2VuZChkYXRhKVxuICAgIH0gZWxzZSB7XG4gICAgICBsb2dnZXIud2FybihcbiAgICAgICAgJ1RyeWluZyB0byBzZW5kIGRhdGEgb3ZlciBhIG5vbi1leGlzdGluZyBvciBjbG9zZWQgZGF0YSBjaGFubmVsJylcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQ2FsbGJhY2sgZnVuY3Rpb24gaW52b2tlZCB3aGVuIGEgU0RQIGFuc3dlciBpcyByZWNlaXZlZC4gRGV2ZWxvcGVycyBhcmVcbiAgICogZXhwZWN0ZWQgdG8gaW52b2tlIHRoaXMgZnVuY3Rpb24gaW4gb3JkZXIgdG8gY29tcGxldGUgdGhlIFNEUCBuZWdvdGlhdGlvbi5cbiAgICpcbiAgICogQGZ1bmN0aW9uIG1vZHVsZTprdXJlbnRvVXRpbHMuV2ViUnRjUGVlci5wcm90b3R5cGUucHJvY2Vzc0Fuc3dlclxuICAgKlxuICAgKiBAcGFyYW0gc2RwQW5zd2VyIC0gRGVzY3JpcHRpb24gb2Ygc2RwQW5zd2VyXG4gICAqIEBwYXJhbSBjYWxsYmFjayAtXG4gICAqICAgICAgICAgICAgSW52b2tlZCBhZnRlciB0aGUgU0RQIGFuc3dlciBpcyBwcm9jZXNzZWQsIG9yIHRoZXJlIGlzIGFuIGVycm9yLlxuICAgKi9cbiAgdGhpcy5wcm9jZXNzQW5zd2VyID0gZnVuY3Rpb24gKHNkcEFuc3dlciwgY2FsbGJhY2spIHtcbiAgICBjYWxsYmFjayA9IChjYWxsYmFjayB8fCBub29wKS5iaW5kKHRoaXMpXG5cbiAgICB2YXIgYW5zd2VyID0gbmV3IFJUQ1Nlc3Npb25EZXNjcmlwdGlvbih7XG4gICAgICB0eXBlOiAnYW5zd2VyJyxcbiAgICAgIHNkcDogc2RwQW5zd2VyXG4gICAgfSlcblxuICAgIGlmIChtdWx0aXN0cmVhbSAmJiB1c2VQbGFuQikge1xuICAgICAgdmFyIHBsYW5CQW5zd2VyID0gaW50ZXJvcC50b1BsYW5CKGFuc3dlcilcbiAgICAgIGxvZ2dlci5kZWJ1ZygnYXNud2VyOjpwbGFuQicsIGR1bXBTRFAocGxhbkJBbnN3ZXIpKVxuICAgICAgYW5zd2VyID0gcGxhbkJBbnN3ZXJcbiAgICB9XG5cbiAgICBsb2dnZXIuZGVidWcoJ1NEUCBhbnN3ZXIgcmVjZWl2ZWQsIHNldHRpbmcgcmVtb3RlIGRlc2NyaXB0aW9uJylcblxuICAgIGlmIChwYy5zaWduYWxpbmdTdGF0ZSA9PT0gJ2Nsb3NlZCcpIHtcbiAgICAgIHJldHVybiBjYWxsYmFjaygnUGVlckNvbm5lY3Rpb24gaXMgY2xvc2VkJylcbiAgICB9XG5cbiAgICBwYy5zZXRSZW1vdGVEZXNjcmlwdGlvbihhbnN3ZXIsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgc2V0UmVtb3RlVmlkZW8oKVxuXG4gICAgICAgIGNhbGxiYWNrKClcbiAgICAgIH0sXG4gICAgICBjYWxsYmFjaylcbiAgfVxuXG4gIC8qKlxuICAgKiBDYWxsYmFjayBmdW5jdGlvbiBpbnZva2VkIHdoZW4gYSBTRFAgb2ZmZXIgaXMgcmVjZWl2ZWQuIERldmVsb3BlcnMgYXJlXG4gICAqIGV4cGVjdGVkIHRvIGludm9rZSB0aGlzIGZ1bmN0aW9uIGluIG9yZGVyIHRvIGNvbXBsZXRlIHRoZSBTRFAgbmVnb3RpYXRpb24uXG4gICAqXG4gICAqIEBmdW5jdGlvbiBtb2R1bGU6a3VyZW50b1V0aWxzLldlYlJ0Y1BlZXIucHJvdG90eXBlLnByb2Nlc3NPZmZlclxuICAgKlxuICAgKiBAcGFyYW0gc2RwT2ZmZXIgLSBEZXNjcmlwdGlvbiBvZiBzZHBPZmZlclxuICAgKiBAcGFyYW0gY2FsbGJhY2sgLSBDYWxsZWQgd2hlbiB0aGUgcmVtb3RlIGRlc2NyaXB0aW9uIGhhcyBiZWVuIHNldFxuICAgKiAgc3VjY2Vzc2Z1bGx5LlxuICAgKi9cbiAgdGhpcy5wcm9jZXNzT2ZmZXIgPSBmdW5jdGlvbiAoc2RwT2ZmZXIsIGNhbGxiYWNrKSB7XG4gICAgY2FsbGJhY2sgPSBjYWxsYmFjay5iaW5kKHRoaXMpXG5cbiAgICB2YXIgb2ZmZXIgPSBuZXcgUlRDU2Vzc2lvbkRlc2NyaXB0aW9uKHtcbiAgICAgIHR5cGU6ICdvZmZlcicsXG4gICAgICBzZHA6IHNkcE9mZmVyXG4gICAgfSlcblxuICAgIGlmIChtdWx0aXN0cmVhbSAmJiB1c2VQbGFuQikge1xuICAgICAgdmFyIHBsYW5CT2ZmZXIgPSBpbnRlcm9wLnRvUGxhbkIob2ZmZXIpXG4gICAgICBsb2dnZXIuZGVidWcoJ29mZmVyOjpwbGFuQicsIGR1bXBTRFAocGxhbkJPZmZlcikpXG4gICAgICBvZmZlciA9IHBsYW5CT2ZmZXJcbiAgICB9XG5cbiAgICBsb2dnZXIuZGVidWcoJ1NEUCBvZmZlciByZWNlaXZlZCwgc2V0dGluZyByZW1vdGUgZGVzY3JpcHRpb24nKVxuXG4gICAgaWYgKHBjLnNpZ25hbGluZ1N0YXRlID09PSAnY2xvc2VkJykge1xuICAgICAgcmV0dXJuIGNhbGxiYWNrKCdQZWVyQ29ubmVjdGlvbiBpcyBjbG9zZWQnKVxuICAgIH1cblxuICAgIHBjLnNldFJlbW90ZURlc2NyaXB0aW9uKG9mZmVyKS50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICAgIHJldHVybiBzZXRSZW1vdGVWaWRlbygpXG4gICAgfSkudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICByZXR1cm4gcGMuY3JlYXRlQW5zd2VyKClcbiAgICB9KS50aGVuKGZ1bmN0aW9uIChhbnN3ZXIpIHtcbiAgICAgIGFuc3dlciA9IG1hbmdsZVNkcFRvQWRkU2ltdWxjYXN0KGFuc3dlcilcbiAgICAgIGxvZ2dlci5kZWJ1ZygnQ3JlYXRlZCBTRFAgYW5zd2VyJylcbiAgICAgIHJldHVybiBwYy5zZXRMb2NhbERlc2NyaXB0aW9uKGFuc3dlcilcbiAgICB9KS50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciBsb2NhbERlc2NyaXB0aW9uID0gcGMubG9jYWxEZXNjcmlwdGlvblxuICAgICAgaWYgKG11bHRpc3RyZWFtICYmIHVzZVBsYW5CKSB7XG4gICAgICAgIGxvY2FsRGVzY3JpcHRpb24gPSBpbnRlcm9wLnRvVW5pZmllZFBsYW4obG9jYWxEZXNjcmlwdGlvbilcbiAgICAgICAgbG9nZ2VyLmRlYnVnKCdhbnN3ZXI6Om9yaWdQbGFuQi0+VW5pZmllZFBsYW4nLCBkdW1wU0RQKFxuICAgICAgICAgIGxvY2FsRGVzY3JpcHRpb24pKVxuICAgICAgfVxuICAgICAgbG9nZ2VyLmRlYnVnKCdMb2NhbCBkZXNjcmlwdGlvbiBzZXQnLCBsb2NhbERlc2NyaXB0aW9uLnNkcClcbiAgICAgIGNhbGxiYWNrKG51bGwsIGxvY2FsRGVzY3JpcHRpb24uc2RwKVxuICAgIH0pLmNhdGNoKGNhbGxiYWNrKVxuICB9XG5cbiAgZnVuY3Rpb24gbWFuZ2xlU2RwVG9BZGRTaW11bGNhc3QoYW5zd2VyKSB7XG4gICAgaWYgKHNpbXVsY2FzdCkge1xuICAgICAgaWYgKGJyb3dzZXIubmFtZSA9PT0gJ0Nocm9tZScgfHwgYnJvd3Nlci5uYW1lID09PSAnQ2hyb21pdW0nKSB7XG4gICAgICAgIGxvZ2dlci5kZWJ1ZygnQWRkaW5nIG11bHRpY2FzdCBpbmZvJylcbiAgICAgICAgYW5zd2VyID0gbmV3IFJUQ1Nlc3Npb25EZXNjcmlwdGlvbih7XG4gICAgICAgICAgJ3R5cGUnOiBhbnN3ZXIudHlwZSxcbiAgICAgICAgICAnc2RwJzogcmVtb3ZlRklERnJvbU9mZmVyKGFuc3dlci5zZHApICsgZ2V0U2ltdWxjYXN0SW5mbyhcbiAgICAgICAgICAgIHZpZGVvU3RyZWFtKVxuICAgICAgICB9KVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbG9nZ2VyLndhcm4oJ1NpbXVsY2FzdCBpcyBvbmx5IGF2YWlsYWJsZSBpbiBDaHJvbWUgYnJvd3Nlci4nKVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBhbnN3ZXJcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGlzIGZ1bmN0aW9uIGNyZWF0ZXMgdGhlIFJUQ1BlZXJDb25uZWN0aW9uIG9iamVjdCB0YWtpbmcgaW50byBhY2NvdW50IHRoZVxuICAgKiBwcm9wZXJ0aWVzIHJlY2VpdmVkIGluIHRoZSBjb25zdHJ1Y3Rvci4gSXQgc3RhcnRzIHRoZSBTRFAgbmVnb3RpYXRpb25cbiAgICogcHJvY2VzczogZ2VuZXJhdGVzIHRoZSBTRFAgb2ZmZXIgYW5kIGludm9rZXMgdGhlIG9uc2Rwb2ZmZXIgY2FsbGJhY2suIFRoaXNcbiAgICogY2FsbGJhY2sgaXMgZXhwZWN0ZWQgdG8gc2VuZCB0aGUgU0RQIG9mZmVyLCBpbiBvcmRlciB0byBvYnRhaW4gYW4gU0RQXG4gICAqIGFuc3dlciBmcm9tIGFub3RoZXIgcGVlci5cbiAgICovXG4gIGZ1bmN0aW9uIHN0YXJ0KCkge1xuICAgIGlmIChwYy5zaWduYWxpbmdTdGF0ZSA9PT0gJ2Nsb3NlZCcpIHtcbiAgICAgIGNhbGxiYWNrKFxuICAgICAgICAnVGhlIHBlZXIgY29ubmVjdGlvbiBvYmplY3QgaXMgaW4gXCJjbG9zZWRcIiBzdGF0ZS4gVGhpcyBpcyBtb3N0IGxpa2VseSBkdWUgdG8gYW4gaW52b2NhdGlvbiBvZiB0aGUgZGlzcG9zZSBtZXRob2QgYmVmb3JlIGFjY2VwdGluZyBpbiB0aGUgZGlhbG9ndWUnXG4gICAgICApXG4gICAgfVxuXG4gICAgaWYgKHZpZGVvU3RyZWFtICYmIGxvY2FsVmlkZW8pIHtcbiAgICAgIHNlbGYuc2hvd0xvY2FsVmlkZW8oKVxuICAgIH1cblxuICAgIGlmICh2aWRlb1N0cmVhbSkge1xuICAgICAgcGMuYWRkU3RyZWFtKHZpZGVvU3RyZWFtKVxuICAgIH1cblxuICAgIGlmIChhdWRpb1N0cmVhbSkge1xuICAgICAgcGMuYWRkU3RyZWFtKGF1ZGlvU3RyZWFtKVxuICAgIH1cblxuICAgIC8vIFtIYWNrXSBodHRwczovL2NvZGUuZ29vZ2xlLmNvbS9wL2Nocm9taXVtL2lzc3Vlcy9kZXRhaWw/aWQ9NDQzNTU4XG4gICAgdmFyIGJyb3dzZXIgPSBwYXJzZXIuZ2V0QnJvd3NlcigpXG4gICAgaWYgKG1vZGUgPT09ICdzZW5kb25seScgJiZcbiAgICAgIChicm93c2VyLm5hbWUgPT09ICdDaHJvbWUnIHx8IGJyb3dzZXIubmFtZSA9PT0gJ0Nocm9taXVtJykgJiZcbiAgICAgIGJyb3dzZXIubWFqb3IgPT09IDM5KSB7XG4gICAgICBtb2RlID0gJ3NlbmRyZWN2J1xuICAgIH1cblxuICAgIGNhbGxiYWNrKClcbiAgfVxuXG4gIGlmIChtb2RlICE9PSAncmVjdm9ubHknICYmICF2aWRlb1N0cmVhbSAmJiAhYXVkaW9TdHJlYW0pIHtcbiAgICBmdW5jdGlvbiBnZXRNZWRpYShjb25zdHJhaW50cykge1xuICAgICAgaWYgKGNvbnN0cmFpbnRzID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgY29uc3RyYWludHMgPSBNRURJQV9DT05TVFJBSU5UU1xuICAgICAgfVxuXG4gICAgICBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmdldFVzZXJNZWRpYShjb25zdHJhaW50cykudGhlbihmdW5jdGlvbiAoc3RyZWFtKSB7XG4gICAgICAgIHZpZGVvU3RyZWFtID0gc3RyZWFtXG4gICAgICAgIHN0YXJ0KClcbiAgICAgIH0pLmNhdGNoKGNhbGxiYWNrKTtcbiAgICB9XG4gICAgaWYgKHNlbmRTb3VyY2UgPT09ICd3ZWJjYW0nKSB7XG4gICAgICBnZXRNZWRpYShtZWRpYUNvbnN0cmFpbnRzKVxuICAgIH0gZWxzZSB7XG4gICAgICBnZXRTY3JlZW5Db25zdHJhaW50cyhzZW5kU291cmNlLCBmdW5jdGlvbiAoZXJyb3IsIGNvbnN0cmFpbnRzXykge1xuICAgICAgICBpZiAoZXJyb3IpXG4gICAgICAgICAgcmV0dXJuIGNhbGxiYWNrKGVycm9yKVxuXG4gICAgICAgIGNvbnN0cmFpbnRzID0gW21lZGlhQ29uc3RyYWludHNdXG4gICAgICAgIGNvbnN0cmFpbnRzLnVuc2hpZnQoY29uc3RyYWludHNfKVxuICAgICAgICBnZXRNZWRpYShyZWN1cnNpdmUuYXBwbHkodW5kZWZpbmVkLCBjb25zdHJhaW50cykpXG4gICAgICB9LCBndWlkKVxuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBzZXRUaW1lb3V0KHN0YXJ0LCAwKVxuICB9XG5cbiAgdGhpcy5vbignX2Rpc3Bvc2UnLCBmdW5jdGlvbiAoKSB7XG4gICAgaWYgKGxvY2FsVmlkZW8pIHtcbiAgICAgIGxvY2FsVmlkZW8ucGF1c2UoKVxuICAgICAgbG9jYWxWaWRlby5zcmMgPSAnJ1xuICAgICAgbG9jYWxWaWRlby5sb2FkKClcbiAgICAgIC8vVW5tdXRlIGxvY2FsIHZpZGVvIGluIGNhc2UgdGhlIHZpZGVvIHRhZyBpcyBsYXRlciB1c2VkIGZvciByZW1vdGUgdmlkZW9cbiAgICAgIGxvY2FsVmlkZW8ubXV0ZWQgPSBmYWxzZVxuICAgIH1cbiAgICBpZiAocmVtb3RlVmlkZW8pIHtcbiAgICAgIHJlbW90ZVZpZGVvLnBhdXNlKClcbiAgICAgIHJlbW90ZVZpZGVvLnNyYyA9ICcnXG4gICAgICByZW1vdGVWaWRlby5sb2FkKClcbiAgICB9XG4gICAgc2VsZi5yZW1vdmVBbGxMaXN0ZW5lcnMoKVxuXG4gICAgaWYgKHdpbmRvdy5jYW5jZWxDaG9vc2VEZXNrdG9wTWVkaWEgIT09IHVuZGVmaW5lZCkge1xuICAgICAgd2luZG93LmNhbmNlbENob29zZURlc2t0b3BNZWRpYShndWlkKVxuICAgIH1cbiAgfSlcbn1cbmluaGVyaXRzKFdlYlJ0Y1BlZXIsIEV2ZW50RW1pdHRlcilcblxuZnVuY3Rpb24gY3JlYXRlRW5hYmxlRGVzY3JpcHRvcih0eXBlKSB7XG4gIHZhciBtZXRob2QgPSAnZ2V0JyArIHR5cGUgKyAnVHJhY2tzJ1xuXG4gIHJldHVybiB7XG4gICAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgIC8vIFtUb0RvXSBTaG91bGQgcmV0dXJuIHVuZGVmaW5lZCBpZiBub3QgYWxsIHRyYWNrcyBoYXZlIHRoZSBzYW1lIHZhbHVlP1xuXG4gICAgICBpZiAoIXRoaXMucGVlckNvbm5lY3Rpb24pIHJldHVyblxuXG4gICAgICB2YXIgc3RyZWFtcyA9IHRoaXMucGVlckNvbm5lY3Rpb24uZ2V0TG9jYWxTdHJlYW1zKClcbiAgICAgIGlmICghc3RyZWFtcy5sZW5ndGgpIHJldHVyblxuXG4gICAgICBmb3IgKHZhciBpID0gMCwgc3RyZWFtOyBzdHJlYW0gPSBzdHJlYW1zW2ldOyBpKyspIHtcbiAgICAgICAgdmFyIHRyYWNrcyA9IHN0cmVhbVttZXRob2RdKClcbiAgICAgICAgZm9yICh2YXIgaiA9IDAsIHRyYWNrOyB0cmFjayA9IHRyYWNrc1tqXTsgaisrKVxuICAgICAgICAgIGlmICghdHJhY2suZW5hYmxlZCkgcmV0dXJuIGZhbHNlXG4gICAgICB9XG5cbiAgICAgIHJldHVybiB0cnVlXG4gICAgfSxcbiAgICBzZXQ6IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgZnVuY3Rpb24gdHJhY2tTZXRFbmFibGUodHJhY2spIHtcbiAgICAgICAgdHJhY2suZW5hYmxlZCA9IHZhbHVlXG4gICAgICB9XG5cbiAgICAgIHRoaXMucGVlckNvbm5lY3Rpb24uZ2V0TG9jYWxTdHJlYW1zKCkuZm9yRWFjaChmdW5jdGlvbiAoc3RyZWFtKSB7XG4gICAgICAgIHN0cmVhbVttZXRob2RdKCkuZm9yRWFjaCh0cmFja1NldEVuYWJsZSlcbiAgICAgIH0pXG4gICAgfVxuICB9XG59XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKFdlYlJ0Y1BlZXIucHJvdG90eXBlLCB7XG4gICdlbmFibGVkJzoge1xuICAgIGVudW1lcmFibGU6IHRydWUsXG4gICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgICByZXR1cm4gdGhpcy5hdWRpb0VuYWJsZWQgJiYgdGhpcy52aWRlb0VuYWJsZWRcbiAgICB9LFxuICAgIHNldDogZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICB0aGlzLmF1ZGlvRW5hYmxlZCA9IHRoaXMudmlkZW9FbmFibGVkID0gdmFsdWVcbiAgICB9XG4gIH0sXG4gICdhdWRpb0VuYWJsZWQnOiBjcmVhdGVFbmFibGVEZXNjcmlwdG9yKCdBdWRpbycpLFxuICAndmlkZW9FbmFibGVkJzogY3JlYXRlRW5hYmxlRGVzY3JpcHRvcignVmlkZW8nKVxufSlcblxuV2ViUnRjUGVlci5wcm90b3R5cGUuZ2V0TG9jYWxTdHJlYW0gPSBmdW5jdGlvbiAoaW5kZXgpIHtcbiAgaWYgKHRoaXMucGVlckNvbm5lY3Rpb24pIHtcbiAgICByZXR1cm4gdGhpcy5wZWVyQ29ubmVjdGlvbi5nZXRMb2NhbFN0cmVhbXMoKVtpbmRleCB8fCAwXVxuICB9XG59XG5cbldlYlJ0Y1BlZXIucHJvdG90eXBlLmdldFJlbW90ZVN0cmVhbSA9IGZ1bmN0aW9uIChpbmRleCkge1xuICBpZiAodGhpcy5wZWVyQ29ubmVjdGlvbikge1xuICAgIHJldHVybiB0aGlzLnBlZXJDb25uZWN0aW9uLmdldFJlbW90ZVN0cmVhbXMoKVtpbmRleCB8fCAwXVxuICB9XG59XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIFRoaXMgbWV0aG9kIGZyZWVzIHRoZSByZXNvdXJjZXMgdXNlZCBieSBXZWJSdGNQZWVyLlxuICpcbiAqIEBmdW5jdGlvbiBtb2R1bGU6a3VyZW50b1V0aWxzLldlYlJ0Y1BlZXIucHJvdG90eXBlLmRpc3Bvc2VcbiAqL1xuV2ViUnRjUGVlci5wcm90b3R5cGUuZGlzcG9zZSA9IGZ1bmN0aW9uICgpIHtcbiAgbG9nZ2VyLmRlYnVnKCdEaXNwb3NpbmcgV2ViUnRjUGVlcicpXG5cbiAgdmFyIHBjID0gdGhpcy5wZWVyQ29ubmVjdGlvblxuICB2YXIgZGMgPSB0aGlzLmRhdGFDaGFubmVsXG4gIHRyeSB7XG4gICAgaWYgKGRjKSB7XG4gICAgICBpZiAoZGMuc2lnbmFsaW5nU3RhdGUgPT09ICdjbG9zZWQnKSByZXR1cm5cblxuICAgICAgZGMuY2xvc2UoKVxuICAgIH1cblxuICAgIGlmIChwYykge1xuICAgICAgaWYgKHBjLnNpZ25hbGluZ1N0YXRlID09PSAnY2xvc2VkJykgcmV0dXJuXG5cbiAgICAgIHBjLmdldExvY2FsU3RyZWFtcygpLmZvckVhY2goc3RyZWFtU3RvcClcblxuICAgICAgLy8gRklYTUUgVGhpcyBpcyBub3QgeWV0IGltcGxlbWVudGVkIGluIGZpcmVmb3hcbiAgICAgIC8vIGlmKHZpZGVvU3RyZWFtKSBwYy5yZW1vdmVTdHJlYW0odmlkZW9TdHJlYW0pO1xuICAgICAgLy8gaWYoYXVkaW9TdHJlYW0pIHBjLnJlbW92ZVN0cmVhbShhdWRpb1N0cmVhbSk7XG5cbiAgICAgIHBjLmNsb3NlKClcbiAgICB9XG4gIH0gY2F0Y2ggKGVycikge1xuICAgIGxvZ2dlci53YXJuKCdFeGNlcHRpb24gZGlzcG9zaW5nIHdlYnJ0YyBwZWVyICcgKyBlcnIpXG4gIH1cblxuICB0aGlzLmVtaXQoJ19kaXNwb3NlJylcbn1cblxuLy9cbi8vIFNwZWNpYWxpemVkIGNoaWxkIGNsYXNzZXNcbi8vXG5cbmZ1bmN0aW9uIFdlYlJ0Y1BlZXJSZWN2b25seShvcHRpb25zLCBjYWxsYmFjaykge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgV2ViUnRjUGVlclJlY3Zvbmx5KSkge1xuICAgIHJldHVybiBuZXcgV2ViUnRjUGVlclJlY3Zvbmx5KG9wdGlvbnMsIGNhbGxiYWNrKVxuICB9XG5cbiAgV2ViUnRjUGVlclJlY3Zvbmx5LnN1cGVyXy5jYWxsKHRoaXMsICdyZWN2b25seScsIG9wdGlvbnMsIGNhbGxiYWNrKVxufVxuaW5oZXJpdHMoV2ViUnRjUGVlclJlY3Zvbmx5LCBXZWJSdGNQZWVyKVxuXG5mdW5jdGlvbiBXZWJSdGNQZWVyU2VuZG9ubHkob3B0aW9ucywgY2FsbGJhY2spIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIFdlYlJ0Y1BlZXJTZW5kb25seSkpIHtcbiAgICByZXR1cm4gbmV3IFdlYlJ0Y1BlZXJTZW5kb25seShvcHRpb25zLCBjYWxsYmFjaylcbiAgfVxuXG4gIFdlYlJ0Y1BlZXJTZW5kb25seS5zdXBlcl8uY2FsbCh0aGlzLCAnc2VuZG9ubHknLCBvcHRpb25zLCBjYWxsYmFjaylcbn1cbmluaGVyaXRzKFdlYlJ0Y1BlZXJTZW5kb25seSwgV2ViUnRjUGVlcilcblxuZnVuY3Rpb24gV2ViUnRjUGVlclNlbmRyZWN2KG9wdGlvbnMsIGNhbGxiYWNrKSB7XG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBXZWJSdGNQZWVyU2VuZHJlY3YpKSB7XG4gICAgcmV0dXJuIG5ldyBXZWJSdGNQZWVyU2VuZHJlY3Yob3B0aW9ucywgY2FsbGJhY2spXG4gIH1cblxuICBXZWJSdGNQZWVyU2VuZHJlY3Yuc3VwZXJfLmNhbGwodGhpcywgJ3NlbmRyZWN2Jywgb3B0aW9ucywgY2FsbGJhY2spXG59XG5pbmhlcml0cyhXZWJSdGNQZWVyU2VuZHJlY3YsIFdlYlJ0Y1BlZXIpXG5cbmZ1bmN0aW9uIGhhcmtVdGlscyhzdHJlYW0sIG9wdGlvbnMpIHtcbiAgcmV0dXJuIGhhcmsoc3RyZWFtLCBvcHRpb25zKTtcbn1cblxuZXhwb3J0cy5idWZmZXJpemVDYW5kaWRhdGVzID0gYnVmZmVyaXplQ2FuZGlkYXRlc1xuXG5leHBvcnRzLldlYlJ0Y1BlZXJSZWN2b25seSA9IFdlYlJ0Y1BlZXJSZWN2b25seVxuZXhwb3J0cy5XZWJSdGNQZWVyU2VuZG9ubHkgPSBXZWJSdGNQZWVyU2VuZG9ubHlcbmV4cG9ydHMuV2ViUnRjUGVlclNlbmRyZWN2ID0gV2ViUnRjUGVlclNlbmRyZWN2XG5leHBvcnRzLmhhcmsgPSBoYXJrVXRpbHNcbiIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTQgS3VyZW50byAoaHR0cDovL2t1cmVudG8ub3JnLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG4vKipcbiAqIFRoaXMgbW9kdWxlIGNvbnRhaW5zIGEgc2V0IG9mIHJldXNhYmxlIGNvbXBvbmVudHMgdGhhdCBoYXZlIGJlZW4gZm91bmQgdXNlZnVsXG4gKiBkdXJpbmcgdGhlIGRldmVsb3BtZW50IG9mIHRoZSBXZWJSVEMgYXBwbGljYXRpb25zIHdpdGggS3VyZW50by5cbiAqIFxuICogQG1vZHVsZSBrdXJlbnRvVXRpbHNcbiAqIFxuICogQGNvcHlyaWdodCAyMDE0IEt1cmVudG8gKGh0dHA6Ly9rdXJlbnRvLm9yZy8pXG4gKiBAbGljZW5zZSBBTHYyXG4gKi9cblxudmFyIFdlYlJ0Y1BlZXIgPSByZXF1aXJlKCcuL1dlYlJ0Y1BlZXInKTtcblxuZXhwb3J0cy5XZWJSdGNQZWVyID0gV2ViUnRjUGVlcjtcbiIsImltcG9ydCB7IE9wZW5WaWR1IH0gZnJvbSAnLi9PcGVuVmlkdSc7XG5cbi8vVGhpcyBleHBvcnQgd2l0aCAtLXN0YW5kYWxvbmUgb3B0aW9uIGFsbG93cyB1c2luZyBPcGVuVmlkdSBmcm9tIGJvd3NlciB3aXRoIG5hbWVzcGFjZVxuLy9leHBvcnQgeyBPcGVuVmlkdSB9IGZyb20gJy4vT3BlblZpZHUnO1xuXG4vL1RoaXMgXCJoYWNrXCIgYWxsb3dzIHRvIHVzZSBPcGVuVmlkdSBmcm9tIHRoZSBnbG9iYWwgc3BhY2Ugd2luZG93XG5pZih3aW5kb3cpe1xuICAgIHdpbmRvd1tcIk9wZW5WaWR1XCJdID0gT3BlblZpZHU7XG59XG5cbi8vQ29tbWFuZCB0byBnZW5lcmF0ZSBidW5kbGUuanMgd2l0aG91dCBuYW1lc3BhY2Vcbi8vd2F0Y2hpZnkgTWFpbi50cyAtcCBbIHRzaWZ5IF0gLS1leGNsdWRlIGt1cmVudG8tYnJvd3Nlci1leHRlbnNpb25zIC0tZGVidWcgLW8gLi4vc3RhdGljL2pzL09wZW5WaWR1LmpzIC12IiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNyBPcGVuVmlkdSAoaHR0cDovL29wZW52aWR1LmlvLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuaW1wb3J0IHsgT3BlblZpZHVJbnRlcm5hbCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvT3BlblZpZHVJbnRlcm5hbCc7XG5cbmltcG9ydCB7IFNlc3Npb24gfSBmcm9tICcuL1Nlc3Npb24nO1xuaW1wb3J0IHsgUHVibGlzaGVyIH0gZnJvbSAnLi9QdWJsaXNoZXInO1xuXG5pbXBvcnQgKiBhcyBhZGFwdGVyIGZyb20gJ3dlYnJ0Yy1hZGFwdGVyJztcblxuaWYgKHdpbmRvdykge1xuICAgIHdpbmRvd1tcImFkYXB0ZXJcIl0gPSBhZGFwdGVyO1xufVxuXG5leHBvcnQgY2xhc3MgT3BlblZpZHUge1xuXG4gICAgb3BlblZpZHU6IE9wZW5WaWR1SW50ZXJuYWw7XG5cbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgdGhpcy5vcGVuVmlkdSA9IG5ldyBPcGVuVmlkdUludGVybmFsKCk7XG4gICAgICAgIGNvbnNvbGUuaW5mbyhcIidPcGVuVmlkdScgaW5pdGlhbGl6ZWRcIik7XG4gICAgfTtcblxuICAgIGluaXRTZXNzaW9uKGFwaUtleTogc3RyaW5nLCBzZXNzaW9uSWQ6IHN0cmluZyk6IFNlc3Npb247XG4gICAgaW5pdFNlc3Npb24oc2Vzc2lvbklkOiBzdHJpbmcpOiBTZXNzaW9uO1xuXG4gICAgaW5pdFNlc3Npb24ocGFyYW0xLCBwYXJhbTI/KTogYW55IHtcbiAgICAgICAgaWYgKHRoaXMuY2hlY2tTeXN0ZW1SZXF1aXJlbWVudHMoKSkge1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBwYXJhbTIgPT0gXCJzdHJpbmdcIikge1xuICAgICAgICAgICAgICAgIHJldHVybiBuZXcgU2Vzc2lvbih0aGlzLm9wZW5WaWR1LmluaXRTZXNzaW9uKHBhcmFtMiksIHRoaXMpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFNlc3Npb24odGhpcy5vcGVuVmlkdS5pbml0U2Vzc2lvbihwYXJhbTEpLCB0aGlzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGFsZXJ0KFwiQnJvd3NlciBub3Qgc3VwcG9ydGVkXCIpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgaW5pdFB1Ymxpc2hlcihwYXJlbnRJZDogc3RyaW5nKTogUHVibGlzaGVyO1xuICAgIGluaXRQdWJsaXNoZXIocGFyZW50SWQ6IHN0cmluZywgY2FtZXJhT3B0aW9uczogYW55KTogUHVibGlzaGVyO1xuICAgIGluaXRQdWJsaXNoZXIocGFyZW50SWQ6IHN0cmluZywgY2FtZXJhT3B0aW9uczogYW55LCBjYWxsYmFjazogYW55KTogUHVibGlzaGVyO1xuXG4gICAgaW5pdFB1Ymxpc2hlcihwYXJlbnRJZDogc3RyaW5nLCBjYW1lcmFPcHRpb25zPzogYW55LCBjYWxsYmFjaz86IEZ1bmN0aW9uKTogYW55IHtcbiAgICAgICAgaWYgKHRoaXMuY2hlY2tTeXN0ZW1SZXF1aXJlbWVudHMoKSkge1xuICAgICAgICAgICAgaWYgKGNhbWVyYU9wdGlvbnMgIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIGxldCBjYW1lcmFPcHRpb25zQXV4ID0ge1xuICAgICAgICAgICAgICAgICAgICBzZW5kQXVkaW86IGNhbWVyYU9wdGlvbnMuYXVkaW8gIT0gbnVsbCA/IGNhbWVyYU9wdGlvbnMuYXVkaW8gOiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICBzZW5kVmlkZW86IGNhbWVyYU9wdGlvbnMudmlkZW8gIT0gbnVsbCA/IGNhbWVyYU9wdGlvbnMudmlkZW8gOiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICBhY3RpdmVBdWRpbzogY2FtZXJhT3B0aW9ucy5hY3RpdmVBdWRpbyAhPSBudWxsID8gY2FtZXJhT3B0aW9ucy5hY3RpdmVBdWRpbyA6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgIGFjdGl2ZVZpZGVvOiBjYW1lcmFPcHRpb25zLmFjdGl2ZVZpZGVvICE9IG51bGwgPyBjYW1lcmFPcHRpb25zLmFjdGl2ZVZpZGVvIDogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgZGF0YTogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgbWVkaWFDb25zdHJhaW50czogdGhpcy5vcGVuVmlkdS5nZW5lcmF0ZU1lZGlhQ29uc3RyYWludHMoY2FtZXJhT3B0aW9ucylcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIGNhbWVyYU9wdGlvbnMgPSBjYW1lcmFPcHRpb25zQXV4O1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjYW1lcmFPcHRpb25zID0ge1xuICAgICAgICAgICAgICAgICAgICBzZW5kQXVkaW86IHRydWUsXG4gICAgICAgICAgICAgICAgICAgIHNlbmRWaWRlbzogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgYWN0aXZlQXVkaW86IHRydWUsXG4gICAgICAgICAgICAgICAgICAgIGFjdGl2ZVZpZGVvOiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICBkYXRhOiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICBtZWRpYUNvbnN0cmFpbnRzOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBhdWRpbzogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHZpZGVvOiB7IHdpZHRoOiB7IGlkZWFsOiAxMjgwIH0gfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFyIHB1Ymxpc2hlciA9IG5ldyBQdWJsaXNoZXIodGhpcy5vcGVuVmlkdS5pbml0UHVibGlzaGVyVGFnZ2VkKHBhcmVudElkLCBjYW1lcmFPcHRpb25zLCBjYWxsYmFjayksIHBhcmVudElkKTtcbiAgICAgICAgICAgIFxuICAgICAgICAgICAgY29uc29sZS5pbmZvKFwiJ1B1Ymxpc2hlcicgaW5pdGlhbGl6ZWRcIik7XG4gICAgICAgICAgICByZXR1cm4gcHVibGlzaGVyO1xuXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBhbGVydChcIkJyb3dzZXIgbm90IHN1cHBvcnRlZFwiKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGNoZWNrU3lzdGVtUmVxdWlyZW1lbnRzKCk6IG51bWJlciB7XG4gICAgICAgIGxldCBicm93c2VyID0gYWRhcHRlci5icm93c2VyRGV0YWlscy5icm93c2VyO1xuICAgICAgICBsZXQgdmVyc2lvbiA9IGFkYXB0ZXIuYnJvd3NlckRldGFpbHMudmVyc2lvbjtcblxuICAgICAgICAvL0J1ZyBmaXg6ICduYXZpZ2F0b3IudXNlckFnZW50JyBpbiBGaXJlZm94IGZvciBVYnVudHUgMTQuMDQgZG9lcyBub3QgcmV0dXJuIFwiRmlyZWZveC9bdmVyc2lvbl1cIiBpbiB0aGUgc3RyaW5nLCBzbyB2ZXJzaW9uIHJldHVybmVkIGlzIG51bGxcbiAgICAgICAgaWYgKChicm93c2VyID09ICdmaXJlZm94JykgJiYgKHZlcnNpb24gPT0gbnVsbCkpIHtcbiAgICAgICAgICAgIHJldHVybiAxO1xuICAgICAgICB9XG4gICAgICAgIGlmICgoKGJyb3dzZXIgPT0gJ2Nocm9tZScpICYmICh2ZXJzaW9uID49IDI4KSkgfHwgKChicm93c2VyID09ICdlZGdlJykgJiYgKHZlcnNpb24gPj0gMTIpKSB8fCAoKGJyb3dzZXIgPT0gJ2ZpcmVmb3gnKSAmJiAodmVyc2lvbiA+PSAyMikpKSB7XG4gICAgICAgICAgICByZXR1cm4gMTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiAwO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZ2V0RGV2aWNlcyhjYWxsYmFjaykge1xuICAgICAgICBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmVudW1lcmF0ZURldmljZXMoKS50aGVuKChkZXZpY2VJbmZvcykgPT4ge1xuICAgICAgICAgICAgY2FsbGJhY2sobnVsbCwgZGV2aWNlSW5mb3MpO1xuICAgICAgICB9KS5jYXRjaCgoZXJyb3IpID0+IHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoXCJFcnJvciBnZXR0aW5nIGRldmljZXNcIiwgZXJyb3IpO1xuICAgICAgICAgICAgY2FsbGJhY2soZXJyb3IsIG51bGwpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBlbmFibGVQcm9kTW9kZSgpIHtcbiAgICAgICAgY29uc29sZS5sb2cgPSBmdW5jdGlvbigpIHt9O1xuICAgICAgICBjb25zb2xlLmRlYnVnID0gZnVuY3Rpb24oKSB7fTtcbiAgICAgICAgY29uc29sZS5pbmZvID0gZnVuY3Rpb24oKSB7fTtcbiAgICAgICAgY29uc29sZS53YXJuID0gZnVuY3Rpb24oKSB7fTtcbiAgICB9XG5cbn1cbiIsIi8qXG4gKiBvcHRpb25zOiBuYW1lOiBYWFggZGF0YTogdHJ1ZSAoTWF5YmUgdGhpcyBpcyBiYXNlZCBvbiB3ZWJydGMpIGF1ZGlvOiB0cnVlLFxuICogdmlkZW86IHRydWUsIHVybDogXCJmaWxlOi8vLy4uLlwiID4gUGxheWVyIHNjcmVlbjogdHJ1ZSA+IERlc2t0b3AgKGltcGxpY2l0XG4gKiB2aWRlbzp0cnVlLCBhdWRpbzpmYWxzZSkgYXVkaW86IHRydWUsIHZpZGVvOiB0cnVlID4gV2ViY2FtXG4gKlxuICogc3RyZWFtLmhhc0F1ZGlvKCk7IHN0cmVhbS5oYXNWaWRlbygpOyBzdHJlYW0uaGFzRGF0YSgpO1xuICovXG5pbXBvcnQgeyBTdHJlYW0sIFN0cmVhbU9wdGlvbnMsIFZpZGVvT3B0aW9ucyB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvU3RyZWFtJztcbmltcG9ydCB7IFNlc3Npb24gfSBmcm9tICcuL1Nlc3Npb24nO1xuXG5pbXBvcnQgRXZlbnRFbWl0dGVyID0gcmVxdWlyZSgnd29sZnk4Ny1ldmVudGVtaXR0ZXInKTtcblxuZXhwb3J0IGNsYXNzIFB1Ymxpc2hlciB7XG5cbiAgICBwcml2YXRlIGVlID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuXG4gICAgYWNjZXNzQWxsb3dlZCA9IGZhbHNlO1xuICAgIGVsZW1lbnQ6IEVsZW1lbnQ7XG4gICAgaWQ6IHN0cmluZztcbiAgICBzdHJlYW06IFN0cmVhbTtcbiAgICBzZXNzaW9uOiBTZXNzaW9uOyAvL0luaXRpYWxpemVkIGJ5IFNlc3Npb24ucHVibGlzaChQdWJsaXNoZXIpXG5cbiAgICBjb25zdHJ1Y3RvcihzdHJlYW06IFN0cmVhbSwgcGFyZW50SWQ6IHN0cmluZykge1xuICAgICAgICB0aGlzLnN0cmVhbSA9IHN0cmVhbTtcblxuICAgICAgICB0aGlzLnN0cmVhbS5hZGRFdmVudExpc3RlbmVyKCdjYW1lcmEtYWNjZXNzLWNoYW5nZWQnLCAoZXZlbnQpID0+IHtcbiAgICAgICAgICAgIHRoaXMuYWNjZXNzQWxsb3dlZCA9IGV2ZW50LmFjY2Vzc0FsbG93ZWQ7XG4gICAgICAgICAgICBpZiAodGhpcy5hY2Nlc3NBbGxvd2VkKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ2FjY2Vzc0FsbG93ZWQnKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ2FjY2Vzc0RlbmllZCcpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgICBpZiAoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQocGFyZW50SWQpICE9IG51bGwpIHtcbiAgICAgICAgICAgIHRoaXMuZWxlbWVudCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKHBhcmVudElkKSEhO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHVibGlzaEF1ZGlvKHZhbHVlOiBib29sZWFuKSB7XG4gICAgICAgIHRoaXMuc3RyZWFtLmdldFdlYlJ0Y1BlZXIoKS5hdWRpb0VuYWJsZWQgPSB2YWx1ZTtcbiAgICB9XG5cbiAgICBwdWJsaXNoVmlkZW8odmFsdWU6IGJvb2xlYW4pIHtcbiAgICAgICAgdGhpcy5zdHJlYW0uZ2V0V2ViUnRjUGVlcigpLnZpZGVvRW5hYmxlZCA9IHZhbHVlO1xuICAgIH1cblxuICAgIGRlc3Ryb3koKSB7XG4gICAgICAgIHRoaXMuc2Vzc2lvbi51bnB1Ymxpc2godGhpcyk7XG4gICAgICAgIHRoaXMuc3RyZWFtLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5zdHJlYW0ucmVtb3ZlVmlkZW8odGhpcy5lbGVtZW50KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgc3Vic2NyaWJlVG9SZW1vdGUoKSB7XG4gICAgICAgIHRoaXMuc3RyZWFtLnN1YnNjcmliZVRvTXlSZW1vdGUoKTtcbiAgICB9XG5cbiAgICBvbihldmVudE5hbWU6IHN0cmluZywgY2FsbGJhY2spIHtcbiAgICAgICAgdGhpcy5lZS5hZGRMaXN0ZW5lcihldmVudE5hbWUsIGV2ZW50ID0+IHtcbiAgICAgICAgICAgIGlmIChldmVudCkge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIkV2ZW50ICdcIiArIGV2ZW50TmFtZSArIFwiJyB0cmlnZ2VyZWQgYnkgJ1B1Ymxpc2hlcidcIiwgZXZlbnQpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJFdmVudCAnXCIgKyBldmVudE5hbWUgKyBcIicgdHJpZ2dlcmVkIGJ5ICdQdWJsaXNoZXInXCIpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FsbGJhY2soZXZlbnQpO1xuICAgICAgICB9KTtcbiAgICAgICAgaWYgKGV2ZW50TmFtZSA9PSAndmlkZW9FbGVtZW50Q3JlYXRlZCcpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLnN0cmVhbS5pc1ZpZGVvRUxlbWVudENyZWF0ZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgndmlkZW9FbGVtZW50Q3JlYXRlZCcsIFt7XG4gICAgICAgICAgICAgICAgICAgIGVsZW1lbnQ6IHRoaXMuc3RyZWFtLmdldFZpZGVvRWxlbWVudCgpXG4gICAgICAgICAgICAgICAgfV0pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5hZGRPbmNlRXZlbnRMaXN0ZW5lcigndmlkZW8tZWxlbWVudC1jcmVhdGVkLWJ5LXN0cmVhbScsIChlbGVtZW50KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuaWQgPSBlbGVtZW50LmlkO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgndmlkZW9FbGVtZW50Q3JlYXRlZCcsIFt7XG4gICAgICAgICAgICAgICAgICAgICAgICBlbGVtZW50OiBlbGVtZW50LmVsZW1lbnRcbiAgICAgICAgICAgICAgICAgICAgfV0pO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChldmVudE5hbWUgPT0gJ3ZpZGVvUGxheWluZycpIHtcbiAgICAgICAgICAgIHZhciB2aWRlbyA9IHRoaXMuc3RyZWFtLmdldFZpZGVvRWxlbWVudCgpO1xuICAgICAgICAgICAgaWYgKCF0aGlzLnN0cmVhbS5kaXNwbGF5TXlSZW1vdGUoKSAmJiB2aWRlbyAmJlxuICAgICAgICAgICAgICAgIHZpZGVvLmN1cnJlbnRUaW1lID4gMCAmJiBcbiAgICAgICAgICAgICAgICB2aWRlby5wYXVzZWQgPT0gZmFsc2UgJiYgXG4gICAgICAgICAgICAgICAgdmlkZW8uZW5kZWQgPT0gZmFsc2UgJiZcbiAgICAgICAgICAgICAgICB2aWRlby5yZWFkeVN0YXRlID09IDQpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3ZpZGVvUGxheWluZycsIFt7XG4gICAgICAgICAgICAgICAgICAgICAgICBlbGVtZW50OiB0aGlzLnN0cmVhbS5nZXRWaWRlb0VsZW1lbnQoKVxuICAgICAgICAgICAgICAgICAgICB9XSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmFkZE9uY2VFdmVudExpc3RlbmVyKCd2aWRlby1pcy1wbGF5aW5nJywgKGVsZW1lbnQpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3ZpZGVvUGxheWluZycsIFt7XG4gICAgICAgICAgICAgICAgICAgICAgICBlbGVtZW50OiBlbGVtZW50LmVsZW1lbnRcbiAgICAgICAgICAgICAgICAgICAgfV0pO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChldmVudE5hbWUgPT0gJ3JlbW90ZVZpZGVvUGxheWluZycpIHtcbiAgICAgICAgICAgIHZhciB2aWRlbyA9IHRoaXMuc3RyZWFtLmdldFZpZGVvRWxlbWVudCgpO1xuICAgICAgICAgICAgaWYgKHRoaXMuc3RyZWFtLmRpc3BsYXlNeVJlbW90ZSgpICYmIHZpZGVvICYmXG4gICAgICAgICAgICAgICAgdmlkZW8uY3VycmVudFRpbWUgPiAwICYmIFxuICAgICAgICAgICAgICAgIHZpZGVvLnBhdXNlZCA9PSBmYWxzZSAmJiBcbiAgICAgICAgICAgICAgICB2aWRlby5lbmRlZCA9PSBmYWxzZSAmJlxuICAgICAgICAgICAgICAgIHZpZGVvLnJlYWR5U3RhdGUgPT0gNCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgncmVtb3RlVmlkZW9QbGF5aW5nJywgW3tcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnQ6IHRoaXMuc3RyZWFtLmdldFZpZGVvRWxlbWVudCgpXG4gICAgICAgICAgICAgICAgICAgIH1dKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uYWRkT25jZUV2ZW50TGlzdGVuZXIoJ3JlbW90ZS12aWRlby1pcy1wbGF5aW5nJywgKGVsZW1lbnQpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3JlbW90ZVZpZGVvUGxheWluZycsIFt7XG4gICAgICAgICAgICAgICAgICAgICAgICBlbGVtZW50OiBlbGVtZW50LmVsZW1lbnRcbiAgICAgICAgICAgICAgICAgICAgfV0pO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChldmVudE5hbWUgPT0gJ2FjY2Vzc0FsbG93ZWQnKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uYWNjZXNzSXNBbGxvd2VkKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ2FjY2Vzc0FsbG93ZWQnKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uYWRkRXZlbnRMaXN0ZW5lcignYWNjZXNzLWFsbG93ZWQtYnktcHVibGlzaGVyJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgnYWNjZXNzQWxsb3dlZCcpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChldmVudE5hbWUgPT0gJ2FjY2Vzc0RlbmllZCcpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLnN0cmVhbS5hY2Nlc3NJc0RlbmllZCkge1xuICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdhY2Nlc3NEZW5pZWQnKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uYWRkRXZlbnRMaXN0ZW5lcignYWNjZXNzLWRlbmllZC1ieS1wdWJsaXNoZXInLCAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdhY2Nlc3NEZW5pZWQnKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbn0iLCJpbXBvcnQgeyBTZXNzaW9uSW50ZXJuYWwsIFNlc3Npb25PcHRpb25zIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9TZXNzaW9uSW50ZXJuYWwnO1xuaW1wb3J0IHsgU3RyZWFtIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9TdHJlYW0nO1xuaW1wb3J0IHsgQ29ubmVjdGlvbiB9IGZyb20gXCIuLi9PcGVuVmlkdUludGVybmFsL0Nvbm5lY3Rpb25cIjtcblxuaW1wb3J0IHsgT3BlblZpZHUgfSBmcm9tICcuL09wZW5WaWR1JztcbmltcG9ydCB7IFB1Ymxpc2hlciB9IGZyb20gJy4vUHVibGlzaGVyJztcbmltcG9ydCB7IFN1YnNjcmliZXIgfSBmcm9tICcuL1N1YnNjcmliZXInO1xuXG5pbXBvcnQgRXZlbnRFbWl0dGVyID0gcmVxdWlyZSgnd29sZnk4Ny1ldmVudGVtaXR0ZXInKTtcblxuZXhwb3J0IGNsYXNzIFNlc3Npb24ge1xuXG4gICAgc2Vzc2lvbklkOiBTdHJpbmc7XG4gICAgLy9jYXBhYmlsaXRpZXM6IENhcGFiaWxpdGllc1xuICAgIGNvbm5lY3Rpb246IENvbm5lY3Rpb247XG5cbiAgICBwcml2YXRlIGVlID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuXG4gICAgY29uc3RydWN0b3IocHJpdmF0ZSBzZXNzaW9uOiBTZXNzaW9uSW50ZXJuYWwsIHByaXZhdGUgb3BlblZpZHU6IE9wZW5WaWR1KSB7XG4gICAgICAgIHRoaXMuc2Vzc2lvbklkID0gc2Vzc2lvbi5nZXRTZXNzaW9uSWQoKTtcblxuICAgICAgICAvLyBMaXN0ZW5zIHRvIHRoZSBkZWFjdGl2YXRpb24gb2YgdGhlIGRlZmF1bHQgYmVoYXZpb3VyIHVwb24gdGhlIGRlbGV0aW9uIG9mIGEgU3RyZWFtIG9iamVjdFxuICAgICAgICB0aGlzLnNlc3Npb24uYWRkRXZlbnRMaXN0ZW5lcignc3RyZWFtLWRlc3Ryb3llZC1kZWZhdWx0JywgZXZlbnQgPT4ge1xuICAgICAgICAgICAgZXZlbnQuc3RyZWFtLnJlbW92ZVZpZGVvKCk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIExpc3RlbnMgdG8gdGhlIGRlYWN0aXZhdGlvbiBvZiB0aGUgZGVmYXVsdCBiZWhhdmlvdXIgdXBvbiB0aGUgZGlzY29ubmVjdGlvbiBvZiBhIFNlc3Npb25cbiAgICAgICAgdGhpcy5zZXNzaW9uLmFkZEV2ZW50TGlzdGVuZXIoJ3Nlc3Npb24tZGlzY29ubmVjdGVkLWRlZmF1bHQnLCAoKSA9PiB7XG4gICAgICAgICAgICBsZXQgczogU3RyZWFtO1xuICAgICAgICAgICAgZm9yIChzIG9mIHRoaXMub3BlblZpZHUub3BlblZpZHUuZ2V0UmVtb3RlU3RyZWFtcygpKSB7XG4gICAgICAgICAgICAgICAgcy5yZW1vdmVWaWRlbygpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHRoaXMuY29ubmVjdGlvbikge1xuICAgICAgICAgICAgICAgIGZvciAobGV0IHN0cmVhbUlkIGluIHRoaXMuY29ubmVjdGlvbi5nZXRTdHJlYW1zKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jb25uZWN0aW9uLmdldFN0cmVhbXMoKVtzdHJlYW1JZF0ucmVtb3ZlVmlkZW8oKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIFNldHMgb3IgdXBkYXRlcyB0aGUgdmFsdWUgb2YgJ2Nvbm5lY3Rpb24nIHByb3BlcnR5LiBUcmlnZ2VyZWQgYnkgU2Vzc2lvbkludGVybmFsIHdoZW4gc3VjY2VzZnVsIGNvbm5lY3Rpb25cbiAgICAgICAgdGhpcy5zZXNzaW9uLmFkZEV2ZW50TGlzdGVuZXIoJ3VwZGF0ZS1jb25uZWN0aW9uLW9iamVjdCcsIGV2ZW50ID0+IHtcbiAgICAgICAgICAgIHRoaXMuY29ubmVjdGlvbiA9IGV2ZW50LmNvbm5lY3Rpb247XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIGNvbm5lY3QodG9rZW46IHN0cmluZywgY2FsbGJhY2s6IGFueSk7XG4gICAgY29ubmVjdCh0b2tlbjogc3RyaW5nLCBtZXRhZGF0YTogYW55LCBjYWxsYmFjazogYW55KTtcblxuICAgIGNvbm5lY3QocGFyYW0xLCBwYXJhbTIsIHBhcmFtMz8pIHtcbiAgICAgICAgLy8gRWFybHkgY29uZmlndXJhdGlvbiB0byBkZWFjdGl2YXRlIGF1dG9tYXRpYyBzdWJzY3JpcHRpb24gdG8gc3RyZWFtc1xuICAgICAgICBpZiAocGFyYW0zKSB7XG4gICAgICAgICAgICB0aGlzLnNlc3Npb24uY29uZmlndXJlKHtcbiAgICAgICAgICAgICAgICBzZXNzaW9uSWQ6IHRoaXMuc2Vzc2lvbi5nZXRTZXNzaW9uSWQoKSxcbiAgICAgICAgICAgICAgICBwYXJ0aWNpcGFudElkOiBwYXJhbTEsXG4gICAgICAgICAgICAgICAgbWV0YWRhdGE6IHRoaXMuc2Vzc2lvbi5zdHJpbmdDbGllbnRNZXRhZGF0YShwYXJhbTIpLFxuICAgICAgICAgICAgICAgIHN1YnNjcmliZVRvU3RyZWFtczogZmFsc2VcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgdGhpcy5zZXNzaW9uLmNvbm5lY3QocGFyYW0xLCBwYXJhbTMpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5zZXNzaW9uLmNvbmZpZ3VyZSh7XG4gICAgICAgICAgICAgICAgc2Vzc2lvbklkOiB0aGlzLnNlc3Npb24uZ2V0U2Vzc2lvbklkKCksXG4gICAgICAgICAgICAgICAgcGFydGljaXBhbnRJZDogcGFyYW0xLFxuICAgICAgICAgICAgICAgIG1ldGFkYXRhOiAnJyxcbiAgICAgICAgICAgICAgICBzdWJzY3JpYmVUb1N0cmVhbXM6IGZhbHNlXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5jb25uZWN0KHBhcmFtMSwgcGFyYW0yKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGRpc2Nvbm5lY3QoKSB7XG4gICAgICAgIHRoaXMub3BlblZpZHUub3BlblZpZHUuY2xvc2UoZmFsc2UpO1xuICAgICAgICB0aGlzLnNlc3Npb24uZW1pdEV2ZW50KCdzZXNzaW9uRGlzY29ubmVjdGVkJywgW3tcbiAgICAgICAgICAgIHByZXZlbnREZWZhdWx0OiAoKSA9PiB7IHRoaXMuc2Vzc2lvbi5yZW1vdmVFdmVudCgnc2Vzc2lvbi1kaXNjb25uZWN0ZWQtZGVmYXVsdCcpOyB9XG4gICAgICAgIH1dKTtcbiAgICAgICAgdGhpcy5zZXNzaW9uLmVtaXRFdmVudCgnc2Vzc2lvbi1kaXNjb25uZWN0ZWQtZGVmYXVsdCcsIFt7fV0pO1xuICAgIH1cblxuICAgIHB1Ymxpc2gocHVibGlzaGVyOiBQdWJsaXNoZXIpIHtcbiAgICAgICAgcHVibGlzaGVyLnNlc3Npb24gPSB0aGlzO1xuICAgICAgICBwdWJsaXNoZXIuc3RyZWFtLnB1Ymxpc2goKTtcbiAgICB9XG5cbiAgICB1bnB1Ymxpc2gocHVibGlzaGVyOiBQdWJsaXNoZXIpIHtcbiAgICAgICAgdGhpcy5zZXNzaW9uLnVucHVibGlzaChwdWJsaXNoZXIuc3RyZWFtKTtcbiAgICB9XG5cbiAgICBvbihldmVudE5hbWU6IHN0cmluZywgY2FsbGJhY2spIHtcbiAgICAgICAgdGhpcy5zZXNzaW9uLmFkZEV2ZW50TGlzdGVuZXIoZXZlbnROYW1lLCBldmVudCA9PiB7XG4gICAgICAgICAgICBpZiAoZXZlbnQpIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJFdmVudCAnXCIgKyBldmVudE5hbWUgKyBcIicgdHJpZ2dlcmVkIGJ5ICdTZXNzaW9uJ1wiLCBldmVudCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIkV2ZW50ICdcIiArIGV2ZW50TmFtZSArIFwiJyB0cmlnZ2VyZWQgYnkgJ1Nlc3Npb24nXCIpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FsbGJhY2soZXZlbnQpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBvbmNlKGV2ZW50TmFtZTogc3RyaW5nLCBjYWxsYmFjaykge1xuICAgICAgICB0aGlzLnNlc3Npb24uYWRkT25jZUV2ZW50TGlzdGVuZXIoZXZlbnROYW1lLCBldmVudCA9PiB7XG4gICAgICAgICAgICBjYWxsYmFjayhldmVudCk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIG9mZihldmVudE5hbWU6IHN0cmluZywgZXZlbnRIYW5kbGVyKSB7XG4gICAgICAgIHRoaXMuc2Vzc2lvbi5yZW1vdmVMaXN0ZW5lcihldmVudE5hbWUsIGV2ZW50SGFuZGxlcik7XG4gICAgfVxuXG4gICAgc3Vic2NyaWJlKHN0cmVhbTogU3RyZWFtLCBodG1sSWQ6IHN0cmluZywgdmlkZW9PcHRpb25zOiBhbnkpOiBTdWJzY3JpYmVyO1xuICAgIHN1YnNjcmliZShzdHJlYW06IFN0cmVhbSwgaHRtbElkOiBzdHJpbmcpOiBTdWJzY3JpYmVyO1xuXG4gICAgc3Vic2NyaWJlKHBhcmFtMSwgcGFyYW0yLCBwYXJhbTM/KTogU3Vic2NyaWJlciB7XG4gICAgICAgIC8vIFN1YnNjcmlwdGlvblxuICAgICAgICB0aGlzLnNlc3Npb24uc3Vic2NyaWJlKHBhcmFtMSk7XG4gICAgICAgIGxldCBzdWJzY3JpYmVyID0gbmV3IFN1YnNjcmliZXIocGFyYW0xLCBwYXJhbTIpO1xuICAgICAgICBwYXJhbTEucGxheU9ubHlWaWRlbyhwYXJhbTIsIG51bGwpO1xuICAgICAgICByZXR1cm4gc3Vic2NyaWJlcjtcbiAgICB9XG5cbiAgICB1bnN1YnNjcmliZShzdWJzY3JpYmVyOiBTdWJzY3JpYmVyKSB7XG4gICAgICAgIHRoaXMuc2Vzc2lvbi51bnN1c2NyaWJlKHN1YnNjcmliZXIuc3RyZWFtKTtcbiAgICAgICAgc3Vic2NyaWJlci5zdHJlYW0ucmVtb3ZlVmlkZW8oKTtcbiAgICB9XG5cblxuXG5cbiAgICAvKiBTaG9ydGN1dCBldmVudCBBUEkgKi9cblxuICAgIG9uU3RyZWFtQ3JlYXRlZChjYWxsYmFjaykge1xuICAgICAgICB0aGlzLnNlc3Npb24uYWRkRXZlbnRMaXN0ZW5lcihcInN0cmVhbUNyZWF0ZWRcIiwgc3RyZWFtRXZlbnQgPT4ge1xuICAgICAgICAgICAgY2FsbGJhY2soc3RyZWFtRXZlbnQuc3RyZWFtKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgb25TdHJlYW1EZXN0cm95ZWQoY2FsbGJhY2spIHtcbiAgICAgICAgdGhpcy5zZXNzaW9uLmFkZEV2ZW50TGlzdGVuZXIoXCJzdHJlYW1EZXN0cm95ZWRcIiwgc3RyZWFtRXZlbnQgPT4ge1xuICAgICAgICAgICAgY2FsbGJhY2soc3RyZWFtRXZlbnQuc3RyZWFtKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgb25QYXJ0aWNpcGFudEpvaW5lZChjYWxsYmFjaykge1xuICAgICAgICB0aGlzLnNlc3Npb24uYWRkRXZlbnRMaXN0ZW5lcihcInBhcnRpY2lwYW50LWpvaW5lZFwiLCBwYXJ0aWNpcGFudEV2ZW50ID0+IHtcbiAgICAgICAgICAgIGNhbGxiYWNrKHBhcnRpY2lwYW50RXZlbnQuY29ubmVjdGlvbik7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIG9uUGFydGljaXBhbnRMZWZ0KGNhbGxiYWNrKSB7XG4gICAgICAgIHRoaXMuc2Vzc2lvbi5hZGRFdmVudExpc3RlbmVyKFwicGFydGljaXBhbnQtbGVmdFwiLCBwYXJ0aWNpcGFudEV2ZW50ID0+IHtcbiAgICAgICAgICAgIGNhbGxiYWNrKHBhcnRpY2lwYW50RXZlbnQuY29ubmVjdGlvbik7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIG9uUGFydGljaXBhbnRQdWJsaXNoZWQoY2FsbGJhY2spIHtcbiAgICAgICAgdGhpcy5zZXNzaW9uLmFkZEV2ZW50TGlzdGVuZXIoXCJwYXJ0aWNpcGFudC1wdWJsaXNoZWRcIiwgcGFydGljaXBhbnRFdmVudCA9PiB7XG4gICAgICAgICAgICBjYWxsYmFjayhwYXJ0aWNpcGFudEV2ZW50LmNvbm5lY3Rpb24pO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBvblBhcnRpY2lwYW50RXZpY3RlZChjYWxsYmFjaykge1xuICAgICAgICB0aGlzLnNlc3Npb24uYWRkRXZlbnRMaXN0ZW5lcihcInBhcnRpY2lwYW50LWV2aWN0ZWRcIiwgcGFydGljaXBhbnRFdmVudCA9PiB7XG4gICAgICAgICAgICBjYWxsYmFjayhwYXJ0aWNpcGFudEV2ZW50LmNvbm5lY3Rpb24pO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBvblJvb21DbG9zZWQoY2FsbGJhY2spIHtcbiAgICAgICAgdGhpcy5zZXNzaW9uLmFkZEV2ZW50TGlzdGVuZXIoXCJyb29tLWNsb3NlZFwiLCByb29tRXZlbnQgPT4ge1xuICAgICAgICAgICAgY2FsbGJhY2socm9vbUV2ZW50LnJvb20pO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBvbkxvc3RDb25uZWN0aW9uKGNhbGxiYWNrKSB7XG4gICAgICAgIHRoaXMuc2Vzc2lvbi5hZGRFdmVudExpc3RlbmVyKFwibG9zdC1jb25uZWN0aW9uXCIsIHJvb21FdmVudCA9PiB7XG4gICAgICAgICAgICBjYWxsYmFjayhyb29tRXZlbnQucm9vbSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIG9uTWVkaWFFcnJvcihjYWxsYmFjaykge1xuICAgICAgICB0aGlzLnNlc3Npb24uYWRkRXZlbnRMaXN0ZW5lcihcImVycm9yLW1lZGlhXCIsIGVycm9yRXZlbnQgPT4ge1xuICAgICAgICAgICAgY2FsbGJhY2soZXJyb3JFdmVudC5lcnJvcilcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyogU2hvcnRjdXQgZXZlbnQgQVBJICovXG59XG4iLCJpbXBvcnQgeyBTdHJlYW0sIFN0cmVhbU9wdGlvbnMsIFZpZGVvT3B0aW9ucyB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvU3RyZWFtJztcblxuaW1wb3J0IEV2ZW50RW1pdHRlciA9IHJlcXVpcmUoJ3dvbGZ5ODctZXZlbnRlbWl0dGVyJyk7XG5cbmV4cG9ydCBjbGFzcyBTdWJzY3JpYmVyIHtcblxuICAgIHByaXZhdGUgZWUgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG5cbiAgICBlbGVtZW50OiBFbGVtZW50O1xuICAgIGlkOiBzdHJpbmc7XG4gICAgc3RyZWFtOiBTdHJlYW07XG5cbiAgICBjb25zdHJ1Y3RvcihzdHJlYW06IFN0cmVhbSwgcGFyZW50SWQ6IHN0cmluZykge1xuICAgICAgICB0aGlzLnN0cmVhbSA9IHN0cmVhbTtcbiAgICAgICAgaWYgKGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKHBhcmVudElkKSAhPSBudWxsKSB7XG4gICAgICAgICAgICB0aGlzLmVsZW1lbnQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChwYXJlbnRJZCkhITtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIG9uKGV2ZW50TmFtZTogc3RyaW5nLCBjYWxsYmFjaykge1xuICAgICAgICB0aGlzLmVlLmFkZExpc3RlbmVyKGV2ZW50TmFtZSwgZXZlbnQgPT4ge1xuICAgICAgICAgICAgaWYgKGV2ZW50KSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKFwiRXZlbnQgJ1wiICsgZXZlbnROYW1lICsgXCInIHRyaWdnZXJlZCBieSAnU3Vic2NyaWJlcidcIiwgZXZlbnQpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJFdmVudCAnXCIgKyBldmVudE5hbWUgKyBcIicgdHJpZ2dlcmVkIGJ5ICdTdWJzY3JpYmVyJ1wiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhbGxiYWNrKGV2ZW50KTtcbiAgICAgICAgfSk7XG4gICAgICAgIGlmIChldmVudE5hbWUgPT0gJ3ZpZGVvRWxlbWVudENyZWF0ZWQnKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uaXNWaWRlb0VMZW1lbnRDcmVhdGVkKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3ZpZGVvRWxlbWVudENyZWF0ZWQnLCBbe1xuICAgICAgICAgICAgICAgICAgICBlbGVtZW50OiB0aGlzLnN0cmVhbS5nZXRWaWRlb0VsZW1lbnQoKVxuICAgICAgICAgICAgICAgIH1dKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uYWRkT25jZUV2ZW50TGlzdGVuZXIoJ3ZpZGVvLWVsZW1lbnQtY3JlYXRlZC1ieS1zdHJlYW0nLCBlbGVtZW50ID0+IHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS53YXJuKFwiU3Vic2NyaWJlciBlbWl0dGluZyB2aWRlb0VsZW1lbnRDcmVhdGVkXCIpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmlkID0gZWxlbWVudC5pZDtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3ZpZGVvRWxlbWVudENyZWF0ZWQnLCBbe1xuICAgICAgICAgICAgICAgICAgICAgICAgZWxlbWVudDogZWxlbWVudFxuICAgICAgICAgICAgICAgICAgICB9XSk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGV2ZW50TmFtZSA9PSAndmlkZW9QbGF5aW5nJykge1xuICAgICAgICAgICAgdmFyIHZpZGVvID0gdGhpcy5zdHJlYW0uZ2V0VmlkZW9FbGVtZW50KCk7XG4gICAgICAgICAgICBpZiAoIXRoaXMuc3RyZWFtLmRpc3BsYXlNeVJlbW90ZSgpICYmIHZpZGVvICYmXG4gICAgICAgICAgICAgICAgdmlkZW8uY3VycmVudFRpbWUgPiAwICYmIFxuICAgICAgICAgICAgICAgIHZpZGVvLnBhdXNlZCA9PSBmYWxzZSAmJiBcbiAgICAgICAgICAgICAgICB2aWRlby5lbmRlZCA9PSBmYWxzZSAmJlxuICAgICAgICAgICAgICAgIHZpZGVvLnJlYWR5U3RhdGUgPT0gNCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgndmlkZW9QbGF5aW5nJywgW3tcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnQ6IHRoaXMuc3RyZWFtLmdldFZpZGVvRWxlbWVudCgpXG4gICAgICAgICAgICAgICAgICAgIH1dKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uYWRkT25jZUV2ZW50TGlzdGVuZXIoJ3ZpZGVvLWlzLXBsYXlpbmcnLCAoZWxlbWVudCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgndmlkZW9QbGF5aW5nJywgW3tcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnQ6IGVsZW1lbnQuZWxlbWVudFxuICAgICAgICAgICAgICAgICAgICB9XSk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG59IiwiaW1wb3J0IHsgU3RyZWFtLCBTdHJlYW1PcHRpb25zIH0gZnJvbSAnLi9TdHJlYW0nO1xuaW1wb3J0IHsgT3BlblZpZHVJbnRlcm5hbCB9IGZyb20gJy4vT3BlblZpZHVJbnRlcm5hbCc7XG5pbXBvcnQgeyBTZXNzaW9uSW50ZXJuYWwgfSBmcm9tICcuL1Nlc3Npb25JbnRlcm5hbCc7XG5cbnR5cGUgT2JqTWFwPFQ+ID0geyBbczogc3RyaW5nXTogVDsgfVxuXG5leHBvcnQgaW50ZXJmYWNlIENvbm5lY3Rpb25PcHRpb25zIHtcbiAgICBpZDogc3RyaW5nO1xuICAgIG1ldGFkYXRhOiBzdHJpbmc7XG4gICAgc3RyZWFtcz86IFN0cmVhbU9wdGlvbnNbXTtcbiAgICBhdWRpb0FjdGl2ZTogYm9vbGVhbjtcbiAgICB2aWRlb0FjdGl2ZTogYm9vbGVhbjtcbn1cblxuZXhwb3J0IGNsYXNzIENvbm5lY3Rpb24ge1xuXG4gICAgcHVibGljIGNvbm5lY3Rpb25JZDogc3RyaW5nO1xuICAgIHB1YmxpYyBkYXRhOiBzdHJpbmc7XG4gICAgcHVibGljIGNyZWF0aW9uVGltZTogbnVtYmVyO1xuICAgIHByaXZhdGUgc3RyZWFtczogT2JqTWFwPFN0cmVhbT4gPSB7fTtcbiAgICBwcml2YXRlIHN0cmVhbXNPcHRzOiBTdHJlYW1PcHRpb25zW10gPSBbXTtcblxuICAgIGNvbnN0cnVjdG9yKCBwcml2YXRlIG9wZW5WaWR1OiBPcGVuVmlkdUludGVybmFsLCBwcml2YXRlIGxvY2FsOiBib29sZWFuLCBwcml2YXRlIHJvb206IFNlc3Npb25JbnRlcm5hbCwgcHJpdmF0ZSBvcHRpb25zPzogQ29ubmVjdGlvbk9wdGlvbnMgKSB7XG5cbiAgICAgICAgY29uc29sZS5pbmZvKCBcIidDb25uZWN0aW9uJyBjcmVhdGVkIChcIiArICggbG9jYWwgPyBcImxvY2FsXCIgOiBcInJlbW90ZVwiICkgKyBcIilcIiArICggbG9jYWwgPyBcIlwiIDogXCIsIHdpdGggJ2Nvbm5lY3Rpb25JZCcgW1wiICsgKG9wdGlvbnMgPyBvcHRpb25zLmlkIDogJycpICsgXCJdIFwiICkpO1xuXG4gICAgICAgIGlmICggb3B0aW9ucyApIHtcblxuICAgICAgICAgICAgdGhpcy5jb25uZWN0aW9uSWQgPSBvcHRpb25zLmlkO1xuICAgICAgICAgICAgdGhpcy5kYXRhID0gb3B0aW9ucy5tZXRhZGF0YTtcblxuICAgICAgICAgICAgaWYgKCBvcHRpb25zLnN0cmVhbXMgKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5pbml0U3RyZWFtcyhvcHRpb25zKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBcbiAgICB9XG5cbiAgICBhZGRTdHJlYW0oIHN0cmVhbTogU3RyZWFtICkge1xuICAgICAgICB0aGlzLnN0cmVhbXNbc3RyZWFtLmdldElkSW5QYXJ0aWNpcGFudCgpXSA9IHN0cmVhbTtcbiAgICAgICAgdGhpcy5yb29tLmdldFN0cmVhbXMoKVtzdHJlYW0uZ2V0SWRJblBhcnRpY2lwYW50KCldID0gc3RyZWFtO1xuICAgIH1cblxuICAgIGdldFN0cmVhbXMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnN0cmVhbXM7XG4gICAgfVxuXG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgZm9yICggbGV0IGtleSBpbiB0aGlzLnN0cmVhbXMgKSB7XG4gICAgICAgICAgICB0aGlzLnN0cmVhbXNba2V5XS5kaXNwb3NlKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBzZW5kSWNlQ2FuZGlkYXRlKCBjYW5kaWRhdGUgKSB7XG5cbiAgICAgICAgY29uc29sZS5kZWJ1ZygoIHRoaXMubG9jYWwgPyBcIkxvY2FsXCIgOiBcIlJlbW90ZVwiICksIFwiY2FuZGlkYXRlIGZvclwiLFxuICAgICAgICAgICAgdGhpcy5jb25uZWN0aW9uSWQsIEpTT04uc3RyaW5naWZ5KCBjYW5kaWRhdGUgKSApO1xuXG4gICAgICAgIHRoaXMub3BlblZpZHUuc2VuZFJlcXVlc3QoIFwib25JY2VDYW5kaWRhdGVcIiwge1xuICAgICAgICAgICAgZW5kcG9pbnROYW1lOiB0aGlzLmNvbm5lY3Rpb25JZCxcbiAgICAgICAgICAgIGNhbmRpZGF0ZTogY2FuZGlkYXRlLmNhbmRpZGF0ZSxcbiAgICAgICAgICAgIHNkcE1pZDogY2FuZGlkYXRlLnNkcE1pZCxcbiAgICAgICAgICAgIHNkcE1MaW5lSW5kZXg6IGNhbmRpZGF0ZS5zZHBNTGluZUluZGV4XG4gICAgICAgIH0sIGZ1bmN0aW9uKCBlcnJvciwgcmVzcG9uc2UgKSB7XG4gICAgICAgICAgICBpZiAoIGVycm9yICkge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoIFwiRXJyb3Igc2VuZGluZyBJQ0UgY2FuZGlkYXRlOiBcIlxuICAgICAgICAgICAgICAgICAgICArIEpTT04uc3RyaW5naWZ5KCBlcnJvciApICk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIGluaXRTdHJlYW1zKG9wdGlvbnMpIHtcbiAgICAgICAgZm9yICggbGV0IHN0cmVhbU9wdGlvbnMgb2Ygb3B0aW9ucy5zdHJlYW1zICkge1xuICAgICAgICAgICAgXG4gICAgICAgICAgICBsZXQgc3RyZWFtT3B0cyA9IHtcbiAgICAgICAgICAgICAgICBpZDogc3RyZWFtT3B0aW9ucy5pZCxcbiAgICAgICAgICAgICAgICBjb25uZWN0aW9uOiB0aGlzLFxuICAgICAgICAgICAgICAgIHNlbmRBdWRpbzogc3RyZWFtT3B0aW9ucy5zZW5kQXVkaW8sXG4gICAgICAgICAgICAgICAgc2VuZFZpZGVvOiBzdHJlYW1PcHRpb25zLnNlbmRWaWRlbyxcbiAgICAgICAgICAgICAgICByZWN2QXVkaW86ICggc3RyZWFtT3B0aW9ucy5hdWRpb0FjdGl2ZSA9PSB1bmRlZmluZWQgPyB0cnVlIDogc3RyZWFtT3B0aW9ucy5hdWRpb0FjdGl2ZSApLFxuICAgICAgICAgICAgICAgIHJlY3ZWaWRlbzogKCBzdHJlYW1PcHRpb25zLnZpZGVvQWN0aXZlID09IHVuZGVmaW5lZCA/IHRydWUgOiBzdHJlYW1PcHRpb25zLnZpZGVvQWN0aXZlICksXG4gICAgICAgICAgICAgICAgYWN0aXZlQXVkaW86IHN0cmVhbU9wdGlvbnMuYWN0aXZlQXVkaW8sXG4gICAgICAgICAgICAgICAgYWN0aXZlVmlkZW86IHN0cmVhbU9wdGlvbnMuYWN0aXZlVmlkZW8sXG4gICAgICAgICAgICAgICAgZGF0YTogc3RyZWFtT3B0aW9ucy5kYXRhLFxuICAgICAgICAgICAgICAgIG1lZGlhQ29uc3RyYWludHM6IHN0cmVhbU9wdGlvbnMubWVkaWFDb25zdHJhaW50c1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbGV0IHN0cmVhbSA9IG5ldyBTdHJlYW0odGhpcy5vcGVuVmlkdSwgZmFsc2UsIHRoaXMucm9vbSwgc3RyZWFtT3B0cyApO1xuXG4gICAgICAgICAgICB0aGlzLmFkZFN0cmVhbSggc3RyZWFtICk7XG4gICAgICAgICAgICB0aGlzLnN0cmVhbXNPcHRzLnB1c2goIHN0cmVhbU9wdHMgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnNvbGUuaW5mbyhcIlJlbW90ZSAnQ29ubmVjdGlvbicgd2l0aCAnY29ubmVjdGlvbklkJyBbXCIgKyB0aGlzLmNvbm5lY3Rpb25JZCArIFwiXSBpcyBub3cgY29uZmlndXJlZCBmb3IgcmVjZWl2aW5nIFN0cmVhbXMgd2l0aCBvcHRpb25zOiBcIiwgdGhpcy5zdHJlYW1zT3B0cyApO1xuICAgIH1cbn0iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3IE9wZW5WaWR1IChodHRwOi8vb3BlbnZpZHUuaW8vKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5pbXBvcnQgeyBTZXNzaW9uSW50ZXJuYWwsIFNlc3Npb25PcHRpb25zIH0gZnJvbSAnLi9TZXNzaW9uSW50ZXJuYWwnO1xuaW1wb3J0IHsgU3RyZWFtIH0gZnJvbSAnLi9TdHJlYW0nO1xuaW1wb3J0ICogYXMgUnBjQnVpbGRlciBmcm9tICcuLi9LdXJlbnRvVXRpbHMva3VyZW50by1qc29ucnBjJztcblxuZXhwb3J0IHR5cGUgQ2FsbGJhY2s8VD4gPSAoZXJyb3I/OiBhbnksIG9wZW5WaWR1PzogVCkgPT4gdm9pZDtcblxuZXhwb3J0IGNsYXNzIE9wZW5WaWR1SW50ZXJuYWwge1xuXG4gICAgcHJpdmF0ZSB3c1VyaTtcbiAgICBwcml2YXRlIHNlc3Npb246IFNlc3Npb25JbnRlcm5hbDtcbiAgICBwcml2YXRlIGpzb25ScGNDbGllbnQ6IGFueTtcbiAgICBwcml2YXRlIHJwY1BhcmFtczogYW55O1xuICAgIHByaXZhdGUgY2FsbGJhY2s6IENhbGxiYWNrPE9wZW5WaWR1SW50ZXJuYWw+O1xuICAgIHByaXZhdGUgY2FtZXJhOiBTdHJlYW07XG4gICAgcHJpdmF0ZSByZW1vdGVTdHJlYW1zOiBTdHJlYW1bXSA9IFtdO1xuXG4gICAgcHJpdmF0ZSBzZWNyZXQ6IHN0cmluZztcblxuICAgIGNvbnN0cnVjdG9yKCkgeyB9O1xuXG5cbiAgICAvKiBORVcgTUVUSE9EUyAqL1xuICAgIGluaXRTZXNzaW9uKHNlc3Npb25JZCkge1xuICAgICAgICBjb25zb2xlLmluZm8oXCInU2Vzc2lvbicgaW5pdGlhbGl6ZWQgd2l0aCAnc2Vzc2lvbklkJyBbXCIgKyBzZXNzaW9uSWQgKyBcIl1cIik7XG4gICAgICAgIHRoaXMuc2Vzc2lvbiA9IG5ldyBTZXNzaW9uSW50ZXJuYWwodGhpcywgc2Vzc2lvbklkKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuc2Vzc2lvbjtcbiAgICB9XG5cbiAgICBpbml0UHVibGlzaGVyVGFnZ2VkKHBhcmVudElkOiBzdHJpbmcsIGNhbWVyYU9wdGlvbnM6IGFueSwgY2FsbGJhY2s/KSB7XG5cbiAgICAgICAgdGhpcy5nZXRDYW1lcmEoY2FtZXJhT3B0aW9ucyk7XG5cbiAgICAgICAgaWYgKGNhbGxiYWNrID09IG51bGwpIHtcbiAgICAgICAgICAgIHRoaXMuY2FtZXJhLnJlcXVlc3RDYW1lcmFBY2Nlc3MoKGVycm9yLCBjYW1lcmEpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihcIkVycm9yIGFjY2Vzc2luZyB0aGUgY2FtZXJhXCIsIGVycm9yKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY2FtZXJhLnNldFZpZGVvRWxlbWVudCh0aGlzLmNhbWVyYVJlYWR5KGNhbWVyYSEsIHBhcmVudElkKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5jYW1lcmE7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmNhbWVyYS5yZXF1ZXN0Q2FtZXJhQWNjZXNzKChlcnJvciwgY2FtZXJhKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrKGVycm9yKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY2FtZXJhLnNldFZpZGVvRWxlbWVudCh0aGlzLmNhbWVyYVJlYWR5KGNhbWVyYSEsIHBhcmVudElkKSk7XG4gICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrKHVuZGVmaW5lZCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5jYW1lcmE7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBjYW1lcmFSZWFkeShjYW1lcmE6IFN0cmVhbSwgcGFyZW50SWQ6IHN0cmluZykge1xuICAgICAgICB0aGlzLmNhbWVyYSA9IGNhbWVyYTtcbiAgICAgICAgbGV0IHZpZGVvRWxlbWVudCA9IHRoaXMuY2FtZXJhLnBsYXlPbmx5VmlkZW8ocGFyZW50SWQsIG51bGwpO1xuICAgICAgICB0aGlzLmNhbWVyYS5lbWl0U3RyZWFtUmVhZHlFdmVudCgpO1xuICAgICAgICByZXR1cm4gdmlkZW9FbGVtZW50O1xuICAgIH1cblxuICAgIGluaXRQdWJsaXNoZXIoY2FtZXJhT3B0aW9uczogYW55LCBjYWxsYmFjaykge1xuICAgICAgICB0aGlzLmdldENhbWVyYShjYW1lcmFPcHRpb25zKTtcbiAgICAgICAgdGhpcy5jYW1lcmEucmVxdWVzdENhbWVyYUFjY2VzcygoZXJyb3IsIGNhbWVyYSkgPT4ge1xuICAgICAgICAgICAgaWYgKGVycm9yKSBjYWxsYmFjayhlcnJvcik7XG4gICAgICAgICAgICBlbHNlIGNhbGxiYWNrKHVuZGVmaW5lZCk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIGdldExvY2FsU3RyZWFtKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5jYW1lcmE7XG4gICAgfVxuXG4gICAgZ2V0UmVtb3RlU3RyZWFtcygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucmVtb3RlU3RyZWFtcztcbiAgICB9XG4gICAgLyogTkVXIE1FVEhPRFMgKi9cblxuICAgIGdldFdzVXJpKCkge1xuICAgICAgICByZXR1cm4gdGhpcy53c1VyaTtcbiAgICB9XG5cbiAgICBzZXRXc1VyaSh3c1VyaTogc3RyaW5nKSB7XG4gICAgICAgIHRoaXMud3NVcmkgPSB3c1VyaTtcbiAgICB9XG5cbiAgICBnZXRTZWNyZXQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnNlY3JldDtcbiAgICB9XG5cbiAgICBzZXRTZWNyZXQoc2VjcmV0OiBzdHJpbmcpIHtcbiAgICAgICAgdGhpcy5zZWNyZXQgPSBzZWNyZXQ7XG4gICAgfVxuXG4gICAgZ2V0T3BlblZpZHVTZXJ2ZXJVUkwoKSB7XG4gICAgICAgIHJldHVybiAnaHR0cHM6Ly8nICsgdGhpcy53c1VyaS5zcGxpdChcIndzczovL1wiKVsxXS5zcGxpdChcIi9yb29tXCIpWzBdO1xuICAgIH1cblxuICAgIGdldFJvb20oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnNlc3Npb247XG4gICAgfVxuXG4gICAgY29ubmVjdChjYWxsYmFjazogQ2FsbGJhY2s8T3BlblZpZHVJbnRlcm5hbD4pOiB2b2lkIHtcblxuICAgICAgICB0aGlzLmNhbGxiYWNrID0gY2FsbGJhY2s7XG5cbiAgICAgICAgdGhpcy5pbml0SnNvblJwY0NsaWVudCh0aGlzLndzVXJpKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGluaXRKc29uUnBjQ2xpZW50KHdzVXJpOiBzdHJpbmcpOiB2b2lkIHtcblxuICAgICAgICBsZXQgY29uZmlnID0ge1xuICAgICAgICAgICAgaGVhcnRiZWF0OiAzMDAwLFxuICAgICAgICAgICAgc2VuZENsb3NlTWVzc2FnZTogZmFsc2UsXG4gICAgICAgICAgICB3czoge1xuICAgICAgICAgICAgICAgIHVyaTogd3NVcmksXG4gICAgICAgICAgICAgICAgdXNlU29ja0pTOiBmYWxzZSxcbiAgICAgICAgICAgICAgICBvbmNvbm5lY3RlZDogdGhpcy5jb25uZWN0Q2FsbGJhY2suYmluZCh0aGlzKSxcbiAgICAgICAgICAgICAgICBvbmRpc2Nvbm5lY3Q6IHRoaXMuZGlzY29ubmVjdENhbGxiYWNrLmJpbmQodGhpcyksXG4gICAgICAgICAgICAgICAgb25yZWNvbm5lY3Rpbmc6IHRoaXMucmVjb25uZWN0aW5nQ2FsbGJhY2suYmluZCh0aGlzKSxcbiAgICAgICAgICAgICAgICBvbnJlY29ubmVjdGVkOiB0aGlzLnJlY29ubmVjdGVkQ2FsbGJhY2suYmluZCh0aGlzKVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHJwYzoge1xuICAgICAgICAgICAgICAgIHJlcXVlc3RUaW1lb3V0OiAxNTAwMCxcbiAgICAgICAgICAgICAgICAvL25vdGlmaWNhdGlvbnNcbiAgICAgICAgICAgICAgICBwYXJ0aWNpcGFudEpvaW5lZDogdGhpcy5vblBhcnRpY2lwYW50Sm9pbmVkLmJpbmQodGhpcyksXG4gICAgICAgICAgICAgICAgcGFydGljaXBhbnRQdWJsaXNoZWQ6IHRoaXMub25QYXJ0aWNpcGFudFB1Ymxpc2hlZC5iaW5kKHRoaXMpLFxuICAgICAgICAgICAgICAgIHBhcnRpY2lwYW50VW5wdWJsaXNoZWQ6IHRoaXMub25QYXJ0aWNpcGFudExlZnQuYmluZCh0aGlzKSxcbiAgICAgICAgICAgICAgICBwYXJ0aWNpcGFudExlZnQ6IHRoaXMub25QYXJ0aWNpcGFudExlZnQuYmluZCh0aGlzKSxcbiAgICAgICAgICAgICAgICBwYXJ0aWNpcGFudEV2aWN0ZWQ6IHRoaXMub25QYXJ0aWNpcGFudEV2aWN0ZWQuYmluZCh0aGlzKSxcbiAgICAgICAgICAgICAgICBzZW5kTWVzc2FnZTogdGhpcy5vbk5ld01lc3NhZ2UuYmluZCh0aGlzKSxcbiAgICAgICAgICAgICAgICBpY2VDYW5kaWRhdGU6IHRoaXMuaWNlQ2FuZGlkYXRlRXZlbnQuYmluZCh0aGlzKSxcbiAgICAgICAgICAgICAgICBtZWRpYUVycm9yOiB0aGlzLm9uTWVkaWFFcnJvci5iaW5kKHRoaXMpLFxuICAgICAgICAgICAgICAgIGN1c3Rvbk5vdGlmaWNhdGlvbjogdGhpcy5jdXN0b21Ob3RpZmljYXRpb24uYmluZCh0aGlzKVxuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuXG4gICAgICAgIHRoaXMuanNvblJwY0NsaWVudCA9IG5ldyBScGNCdWlsZGVyLmNsaWVudHMuSnNvblJwY0NsaWVudChjb25maWcpO1xuICAgIH1cblxuXG4gICAgcHJpdmF0ZSBjdXN0b21Ob3RpZmljYXRpb24ocGFyYW1zKSB7XG4gICAgICAgIGlmICh0aGlzLmlzUm9vbUF2YWlsYWJsZSgpKSB7XG4gICAgICAgICAgICB0aGlzLnNlc3Npb24uZW1pdEV2ZW50KFwiY3VzdG9tLW1lc3NhZ2UtcmVjZWl2ZWRcIiwgW3sgcGFyYW1zOiBwYXJhbXMgfV0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBjb25uZWN0Q2FsbGJhY2soZXJyb3IpIHtcbiAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICB0aGlzLmNhbGxiYWNrKGVycm9yKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuY2FsbGJhY2sobnVsbCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGlzUm9vbUF2YWlsYWJsZSgpIHtcbiAgICAgICAgaWYgKHRoaXMuc2Vzc2lvbiAhPT0gdW5kZWZpbmVkICYmIHRoaXMuc2Vzc2lvbiBpbnN0YW5jZW9mIFNlc3Npb25JbnRlcm5hbCkge1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zb2xlLndhcm4oJ1Jvb20gaW5zdGFuY2Ugbm90IGZvdW5kJyk7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGRpc2Nvbm5lY3RDYWxsYmFjaygpIHtcbiAgICAgICAgY29uc29sZS53YXJuKCdXZWJzb2NrZXQgY29ubmVjdGlvbiBsb3N0Jyk7XG4gICAgICAgIGlmICh0aGlzLmlzUm9vbUF2YWlsYWJsZSgpKSB7XG4gICAgICAgICAgICB0aGlzLnNlc3Npb24ub25Mb3N0Q29ubmVjdGlvbigpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgYWxlcnQoJ0Nvbm5lY3Rpb24gZXJyb3IuIFBsZWFzZSByZWxvYWQgcGFnZS4nKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgcmVjb25uZWN0aW5nQ2FsbGJhY2soKSB7XG4gICAgICAgIGNvbnNvbGUud2FybignV2Vic29ja2V0IGNvbm5lY3Rpb24gbG9zdCAocmVjb25uZWN0aW5nKScpO1xuICAgICAgICBpZiAodGhpcy5pc1Jvb21BdmFpbGFibGUoKSkge1xuICAgICAgICAgICAgdGhpcy5zZXNzaW9uLm9uTG9zdENvbm5lY3Rpb24oKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGFsZXJ0KCdDb25uZWN0aW9uIGVycm9yLiBQbGVhc2UgcmVsb2FkIHBhZ2UuJyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIHJlY29ubmVjdGVkQ2FsbGJhY2soKSB7XG4gICAgICAgIGNvbnNvbGUud2FybignV2Vic29ja2V0IHJlY29ubmVjdGVkJyk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBvblBhcnRpY2lwYW50Sm9pbmVkKHBhcmFtcykge1xuICAgICAgICBpZiAodGhpcy5pc1Jvb21BdmFpbGFibGUoKSkge1xuICAgICAgICAgICAgdGhpcy5zZXNzaW9uLm9uUGFydGljaXBhbnRKb2luZWQocGFyYW1zKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgb25QYXJ0aWNpcGFudFB1Ymxpc2hlZChwYXJhbXMpIHtcbiAgICAgICAgaWYgKHRoaXMuaXNSb29tQXZhaWxhYmxlKCkpIHtcbiAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5vblBhcnRpY2lwYW50UHVibGlzaGVkKHBhcmFtcyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIG9uUGFydGljaXBhbnRMZWZ0KHBhcmFtcykge1xuICAgICAgICBpZiAodGhpcy5pc1Jvb21BdmFpbGFibGUoKSkge1xuICAgICAgICAgICAgdGhpcy5zZXNzaW9uLm9uUGFydGljaXBhbnRMZWZ0KHBhcmFtcyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIG9uUGFydGljaXBhbnRFdmljdGVkKHBhcmFtcykge1xuICAgICAgICBpZiAodGhpcy5pc1Jvb21BdmFpbGFibGUoKSkge1xuICAgICAgICAgICAgdGhpcy5zZXNzaW9uLm9uUGFydGljaXBhbnRFdmljdGVkKHBhcmFtcyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIG9uTmV3TWVzc2FnZShwYXJhbXMpIHtcbiAgICAgICAgaWYgKHRoaXMuaXNSb29tQXZhaWxhYmxlKCkpIHtcbiAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5vbk5ld01lc3NhZ2UocGFyYW1zKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgaWNlQ2FuZGlkYXRlRXZlbnQocGFyYW1zKSB7XG4gICAgICAgIGlmICh0aGlzLmlzUm9vbUF2YWlsYWJsZSgpKSB7XG4gICAgICAgICAgICB0aGlzLnNlc3Npb24ucmVjdkljZUNhbmRpZGF0ZShwYXJhbXMpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBvblJvb21DbG9zZWQocGFyYW1zKSB7XG4gICAgICAgIGlmICh0aGlzLmlzUm9vbUF2YWlsYWJsZSgpKSB7XG4gICAgICAgICAgICB0aGlzLnNlc3Npb24ub25Sb29tQ2xvc2VkKHBhcmFtcyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIG9uTWVkaWFFcnJvcihwYXJhbXMpIHtcbiAgICAgICAgaWYgKHRoaXMuaXNSb29tQXZhaWxhYmxlKCkpIHtcbiAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5vbk1lZGlhRXJyb3IocGFyYW1zKTtcbiAgICAgICAgfVxuICAgIH1cblxuXG4gICAgc2V0UnBjUGFyYW1zKHBhcmFtczogYW55KSB7XG4gICAgICAgIHRoaXMucnBjUGFyYW1zID0gcGFyYW1zO1xuICAgIH1cblxuICAgIHNlbmRSZXF1ZXN0KG1ldGhvZCwgcGFyYW1zLCBjYWxsYmFjaz8pIHtcblxuICAgICAgICBpZiAocGFyYW1zICYmIHBhcmFtcyBpbnN0YW5jZW9mIEZ1bmN0aW9uKSB7XG4gICAgICAgICAgICBjYWxsYmFjayA9IHBhcmFtcztcbiAgICAgICAgICAgIHBhcmFtcyA9IHVuZGVmaW5lZDtcbiAgICAgICAgfVxuXG4gICAgICAgIHBhcmFtcyA9IHBhcmFtcyB8fCB7fTtcblxuICAgICAgICBpZiAodGhpcy5ycGNQYXJhbXMgJiYgdGhpcy5ycGNQYXJhbXMgIT09IG51bGwgJiYgdGhpcy5ycGNQYXJhbXMgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgZm9yIChsZXQgaW5kZXggaW4gdGhpcy5ycGNQYXJhbXMpIHtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5ycGNQYXJhbXMuaGFzT3duUHJvcGVydHkoaW5kZXgpKSB7XG4gICAgICAgICAgICAgICAgICAgIHBhcmFtc1tpbmRleF0gPSB0aGlzLnJwY1BhcmFtc1tpbmRleF07XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZGVidWcoJ1JQQyBwYXJhbSBhZGRlZCB0byByZXF1ZXN0IHsnICsgaW5kZXggKyAnOiAnICsgdGhpcy5ycGNQYXJhbXNbaW5kZXhdICsgJ30nKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBjb25zb2xlLmRlYnVnKCdTZW5kaW5nIHJlcXVlc3Q6IHttZXRob2Q6XCInICsgbWV0aG9kICsgJ1wiLCBwYXJhbXM6ICcgKyBKU09OLnN0cmluZ2lmeShwYXJhbXMpICsgJ30nKTtcblxuICAgICAgICB0aGlzLmpzb25ScGNDbGllbnQuc2VuZChtZXRob2QsIHBhcmFtcywgY2FsbGJhY2spO1xuICAgIH1cblxuICAgIGNsb3NlKGZvcmNlZCkge1xuICAgICAgICBpZiAodGhpcy5pc1Jvb21BdmFpbGFibGUoKSkge1xuICAgICAgICAgICAgdGhpcy5zZXNzaW9uLmxlYXZlKGZvcmNlZCwgdGhpcy5qc29uUnBjQ2xpZW50KTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICBkaXNjb25uZWN0UGFydGljaXBhbnQoc3RyZWFtKSB7XG4gICAgICAgIGlmICh0aGlzLmlzUm9vbUF2YWlsYWJsZSgpKSB7XG4gICAgICAgICAgICB0aGlzLnNlc3Npb24uZGlzY29ubmVjdChzdHJlYW0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZ2V0Q2FtZXJhKG9wdGlvbnM/KSB7XG5cbiAgICAgICAgaWYgKHRoaXMuY2FtZXJhKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5jYW1lcmE7XG4gICAgICAgIH1cblxuICAgICAgICBvcHRpb25zID0gb3B0aW9ucyB8fCB7XG4gICAgICAgICAgICBzZW5kQXVkaW86IHRydWUsXG4gICAgICAgICAgICBzZW5kVmlkZW86IHRydWUsXG4gICAgICAgICAgICBhY3RpdmVBdWRpbzogdHJ1ZSxcbiAgICAgICAgICAgIGFjdGl2ZVZpZGVvOiB0cnVlLFxuICAgICAgICAgICAgZGF0YTogdHJ1ZSxcbiAgICAgICAgICAgIG1lZGlhQ29uc3RyYWludHM6IHtcbiAgICAgICAgICAgICAgICBhdWRpbzogdHJ1ZSxcbiAgICAgICAgICAgICAgICB2aWRlbzogeyB3aWR0aDogeyBpZGVhbDogMTI4MCB9IH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBvcHRpb25zLmNvbm5lY3Rpb24gPSB0aGlzLnNlc3Npb24uZ2V0TG9jYWxQYXJ0aWNpcGFudCgpO1xuXG4gICAgICAgIHRoaXMuY2FtZXJhID0gbmV3IFN0cmVhbSh0aGlzLCB0cnVlLCB0aGlzLnNlc3Npb24sIG9wdGlvbnMpO1xuICAgICAgICByZXR1cm4gdGhpcy5jYW1lcmE7XG4gICAgfTtcblxuICAgIC8vQ0hBVFxuICAgIHNlbmRNZXNzYWdlKHJvb20sIHVzZXIsIG1lc3NhZ2UpIHtcbiAgICAgICAgdGhpcy5zZW5kUmVxdWVzdCgnc2VuZE1lc3NhZ2UnLCB7XG4gICAgICAgICAgICBtZXNzYWdlOiBtZXNzYWdlLFxuICAgICAgICAgICAgdXNlck1lc3NhZ2U6IHVzZXIsXG4gICAgICAgICAgICByb29tTWVzc2FnZTogcm9vbVxuICAgICAgICB9LCBmdW5jdGlvbiAoZXJyb3IsIHJlc3BvbnNlKSB7XG4gICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKGVycm9yKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfTtcblxuICAgIHNlbmRDdXN0b21SZXF1ZXN0KHBhcmFtcywgY2FsbGJhY2spIHtcbiAgICAgICAgdGhpcy5zZW5kUmVxdWVzdCgnY3VzdG9tUmVxdWVzdCcsIHBhcmFtcywgY2FsbGJhY2spO1xuICAgIH07XG5cblxuXG5cbiAgICB0b2dnbGVMb2NhbFZpZGVvVHJhY2soYWN0aXZhdGU6IGJvb2xlYW4pIHtcbiAgICAgICAgdGhpcy5nZXRDYW1lcmEoKS5nZXRXZWJSdGNQZWVyKCkudmlkZW9FbmFibGVkID0gYWN0aXZhdGU7XG4gICAgfVxuXG4gICAgdG9nZ2xlTG9jYWxBdWRpb1RyYWNrKGFjdGl2YXRlOiBib29sZWFuKSB7XG4gICAgICAgIHRoaXMuZ2V0Q2FtZXJhKCkuZ2V0V2ViUnRjUGVlcigpLmF1ZGlvRW5hYmxlZCA9IGFjdGl2YXRlO1xuICAgIH1cblxuICAgIHB1Ymxpc2hMb2NhbFZpZGVvQXVkaW8oKSB7XG4gICAgICAgIHRoaXMudG9nZ2xlTG9jYWxWaWRlb1RyYWNrKHRydWUpO1xuICAgICAgICB0aGlzLnRvZ2dsZUxvY2FsQXVkaW9UcmFjayh0cnVlKTtcbiAgICB9XG5cbiAgICB1bnB1Ymxpc2hMb2NhbFZpZGVvQXVkaW8oKSB7XG4gICAgICAgIHRoaXMudG9nZ2xlTG9jYWxWaWRlb1RyYWNrKGZhbHNlKTtcbiAgICAgICAgdGhpcy50b2dnbGVMb2NhbEF1ZGlvVHJhY2soZmFsc2UpO1xuICAgIH1cblxuICAgIGdlbmVyYXRlTWVkaWFDb25zdHJhaW50cyhjYW1lcmFPcHRpb25zOiBhbnkpIHtcbiAgICAgICAgbGV0IG1lZGlhQ29uc3RyYWludHMgPSB7XG4gICAgICAgICAgICBhdWRpbzogY2FtZXJhT3B0aW9ucy5hdWRpbyxcbiAgICAgICAgICAgIHZpZGVvOiB7fVxuICAgICAgICB9XG4gICAgICAgIGlmICghY2FtZXJhT3B0aW9ucy52aWRlbykge1xuICAgICAgICAgICAgbWVkaWFDb25zdHJhaW50cy52aWRlbyA9IGZhbHNlXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBsZXQgdywgaDtcbiAgICAgICAgICAgIHN3aXRjaCAoY2FtZXJhT3B0aW9ucy5xdWFsaXR5KSB7XG4gICAgICAgICAgICAgICAgY2FzZSAnTE9XJzpcbiAgICAgICAgICAgICAgICAgICAgdyA9IDMyMDtcbiAgICAgICAgICAgICAgICAgICAgaCA9IDI0MDtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSAnTUVESVVNJzpcbiAgICAgICAgICAgICAgICAgICAgdyA9IDY0MDtcbiAgICAgICAgICAgICAgICAgICAgaCA9IDQ4MDtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSAnSElHSCc6XG4gICAgICAgICAgICAgICAgICAgIHcgPSAxMjgwO1xuICAgICAgICAgICAgICAgICAgICBoID0gNzIwO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgICAgICB3ID0gNjQwO1xuICAgICAgICAgICAgICAgICAgICBoID0gNDgwO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbWVkaWFDb25zdHJhaW50cy52aWRlb1snd2lkdGgnXSA9IHsgZXhhY3Q6IHcgfTtcbiAgICAgICAgICAgIG1lZGlhQ29uc3RyYWludHMudmlkZW9bJ2hlaWdodCddID0geyBleGFjdDogaCB9O1xuICAgICAgICAgICAgLy9tZWRpYUNvbnN0cmFpbnRzLnZpZGVvWydmcmFtZVJhdGUnXSA9IHsgaWRlYWw6IE51bWJlcigoPEhUTUxJbnB1dEVsZW1lbnQ+ZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2ZyYW1lUmF0ZScpKS52YWx1ZSkgfTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbWVkaWFDb25zdHJhaW50cztcbiAgICB9XG5cbn1cbiIsImltcG9ydCB7IFN0cmVhbSB9IGZyb20gJy4vU3RyZWFtJztcbmltcG9ydCB7IE9wZW5WaWR1SW50ZXJuYWwgfSBmcm9tICcuL09wZW5WaWR1SW50ZXJuYWwnO1xuaW1wb3J0IHsgQ29ubmVjdGlvbiwgQ29ubmVjdGlvbk9wdGlvbnMgfSBmcm9tICcuL0Nvbm5lY3Rpb24nO1xuaW1wb3J0IEV2ZW50RW1pdHRlciA9IHJlcXVpcmUoJ3dvbGZ5ODctZXZlbnRlbWl0dGVyJyk7XG5cbmNvbnN0IFNFQ1JFVF9QQVJBTSA9ICc/c2VjcmV0PSc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgU2Vzc2lvbk9wdGlvbnMge1xuICAgIHNlc3Npb25JZDogc3RyaW5nO1xuICAgIHBhcnRpY2lwYW50SWQ6IHN0cmluZztcbiAgICBtZXRhZGF0YTogc3RyaW5nO1xuICAgIHN1YnNjcmliZVRvU3RyZWFtcz86IGJvb2xlYW47XG4gICAgdXBkYXRlU3BlYWtlckludGVydmFsPzogbnVtYmVyO1xuICAgIHRocmVzaG9sZFNwZWFrZXI/OiBudW1iZXI7XG59XG5cbmV4cG9ydCBjbGFzcyBTZXNzaW9uSW50ZXJuYWwge1xuXG4gICAgcHJpdmF0ZSBpZDogc3RyaW5nO1xuICAgIHByaXZhdGUgc2Vzc2lvbklkOiBzdHJpbmc7XG4gICAgcHJpdmF0ZSBlZSA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcbiAgICBwcml2YXRlIHN0cmVhbXMgPSB7fTtcbiAgICBwcml2YXRlIHBhcnRpY2lwYW50cyA9IHt9O1xuICAgIHByaXZhdGUgcGFydGljaXBhbnRzU3BlYWtpbmc6IENvbm5lY3Rpb25bXSA9IFtdO1xuICAgIHByaXZhdGUgY29ubmVjdGVkID0gZmFsc2U7XG4gICAgcHVibGljIGxvY2FsUGFydGljaXBhbnQ6IENvbm5lY3Rpb247XG4gICAgcHJpdmF0ZSBzdWJzY3JpYmVUb1N0cmVhbXM6IGJvb2xlYW47XG4gICAgcHJpdmF0ZSB1cGRhdGVTcGVha2VySW50ZXJ2YWw6IG51bWJlcjtcbiAgICBwdWJsaWMgdGhyZXNob2xkU3BlYWtlcjogbnVtYmVyO1xuICAgIHByaXZhdGUgb3B0aW9uczogU2Vzc2lvbk9wdGlvbnM7XG5cbiAgICBjb25zdHJ1Y3Rvcihwcml2YXRlIG9wZW5WaWR1OiBPcGVuVmlkdUludGVybmFsLCBzZXNzaW9uSWQ6IHN0cmluZykge1xuICAgICAgICB0aGlzLnNlc3Npb25JZCA9IHRoaXMuZ2V0VXJsV2l0aG91dFNlY3JldChzZXNzaW9uSWQpO1xuICAgICAgICB0aGlzLmxvY2FsUGFydGljaXBhbnQgPSBuZXcgQ29ubmVjdGlvbih0aGlzLm9wZW5WaWR1LCB0cnVlLCB0aGlzKTtcbiAgICAgICAgaWYgKCF0aGlzLm9wZW5WaWR1LmdldFdzVXJpKCkpIHtcbiAgICAgICAgICAgIHRoaXMucHJvY2Vzc09wZW5WaWR1VXJsKHNlc3Npb25JZCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIHByb2Nlc3NPcGVuVmlkdVVybCh1cmw6IHN0cmluZykge1xuICAgICAgICB0aGlzLm9wZW5WaWR1LnNldFNlY3JldCh0aGlzLmdldFNlY3JldEZyb21VcmwodXJsKSk7XG4gICAgICAgIHRoaXMub3BlblZpZHUuc2V0V3NVcmkodGhpcy5nZXRGaW5hbFVybCh1cmwpKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGdldFNlY3JldEZyb21VcmwodXJsOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgICAgICBsZXQgc2VjcmV0ID0gJyc7XG4gICAgICAgIGlmICh1cmwuaW5kZXhPZihTRUNSRVRfUEFSQU0pICE9PSAtMSkge1xuICAgICAgICAgICAgc2VjcmV0ID0gdXJsLnN1YnN0cmluZyh1cmwubGFzdEluZGV4T2YoU0VDUkVUX1BBUkFNKSArIFNFQ1JFVF9QQVJBTS5sZW5ndGgsIHVybC5sZW5ndGgpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBzZWNyZXQ7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnZXRVcmxXaXRob3V0U2VjcmV0KHVybDogc3RyaW5nKTogc3RyaW5nIHtcbiAgICAgICAgaWYgKHVybC5pbmRleE9mKFNFQ1JFVF9QQVJBTSkgIT09IC0xKSB7XG4gICAgICAgICAgICB1cmwgPSB1cmwuc3Vic3RyaW5nKDAsIHVybC5sYXN0SW5kZXhPZihTRUNSRVRfUEFSQU0pKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdXJsO1xuICAgIH1cblxuICAgIHByaXZhdGUgZ2V0RmluYWxVcmwodXJsOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgICAgICB1cmwgPSB0aGlzLmdldFVybFdpdGhvdXRTZWNyZXQodXJsKS5zdWJzdHJpbmcoMCwgdXJsLmxhc3RJbmRleE9mKCcvJykpICsgJy9yb29tJztcbiAgICAgICAgaWYgKHVybC5pbmRleE9mKFwiLm5ncm9rLmlvXCIpICE9PSAtMSkge1xuICAgICAgICAgICAgLy8gT3BlblZpZHUgc2VydmVyIFVSTCByZWZlcmVzIHRvIGEgbmdyb2sgSVA6IHNlY3VyZSB3c3MgcHJvdG9jb2wgYW5kIGRlbGV0ZSBwb3J0IG9mIFVSTFxuICAgICAgICAgICAgdXJsID0gdXJsLnJlcGxhY2UoXCJ3czovL1wiLCBcIndzczovL1wiKTtcbiAgICAgICAgICAgIGxldCByZWdleCA9IC9cXC5uZ3Jva1xcLmlvOlxcZCsvO1xuICAgICAgICAgICAgdXJsID0gdXJsLnJlcGxhY2UocmVnZXgsIFwiLm5ncm9rLmlvXCIpO1xuICAgICAgICB9IGVsc2UgaWYgKCh1cmwuaW5kZXhPZihcImxvY2FsaG9zdFwiKSAhPT0gLTEpIHx8ICh1cmwuaW5kZXhPZihcIjEyNy4wLjAuMVwiKSAhPSAtMSkpIHtcbiAgICAgICAgICAgIC8vIE9wZW5WaWR1IHNlcnZlciBVUkwgcmVmZXJlcyB0byBsb2NhbGhvc3QgSVBcblxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB1cmw7XG4gICAgfVxuXG5cblxuICAgIC8qIE5FVyBNRVRIT0RTICovXG4gICAgY29ubmVjdCh0b2tlbiwgY2FsbGJhY2spIHtcblxuICAgICAgICB0aGlzLm9wZW5WaWR1LmNvbm5lY3QoKGVycm9yKSA9PiB7XG4gICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICBjYWxsYmFjaygnRVJST1IgQ09OTkVDVElORyBUTyBPUEVOVklEVScpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG5cbiAgICAgICAgICAgICAgICBpZiAoIXRva2VuKSB7XG4gICAgICAgICAgICAgICAgICAgIHRva2VuID0gdGhpcy5yYW5kb21Ub2tlbigpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGxldCBqb2luUGFyYW1zID0ge1xuICAgICAgICAgICAgICAgICAgICB0b2tlbjogdG9rZW4sXG4gICAgICAgICAgICAgICAgICAgIHNlc3Npb246IHRoaXMuc2Vzc2lvbklkLFxuICAgICAgICAgICAgICAgICAgICBtZXRhZGF0YTogdGhpcy5vcHRpb25zLm1ldGFkYXRhLFxuICAgICAgICAgICAgICAgICAgICBzZWNyZXQ6IHRoaXMub3BlblZpZHUuZ2V0U2VjcmV0KCksXG4gICAgICAgICAgICAgICAgICAgIGRhdGFDaGFubmVsczogZmFsc2VcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBpZiAodGhpcy5sb2NhbFBhcnRpY2lwYW50KSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChPYmplY3Qua2V5cyh0aGlzLmxvY2FsUGFydGljaXBhbnQuZ2V0U3RyZWFtcygpKS5zb21lKHN0cmVhbUlkID0+XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbXNbc3RyZWFtSWRdLmlzRGF0YUNoYW5uZWxFbmFibGVkKCkpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBqb2luUGFyYW1zLmRhdGFDaGFubmVscyA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICB0aGlzLm9wZW5WaWR1LnNlbmRSZXF1ZXN0KCdqb2luUm9vbScsIGpvaW5QYXJhbXMsIChlcnJvciwgcmVzcG9uc2UpID0+IHtcblxuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrKGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcblxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jb25uZWN0ZWQgPSB0cnVlO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQgZXhQYXJ0aWNpcGFudHMgPSByZXNwb25zZS52YWx1ZTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gSU1QT1JUQU5UOiBVcGRhdGUgY29ubmVjdGlvbklkIHdpdGggdmFsdWUgc2VuZCBieSBzZXJ2ZXJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubG9jYWxQYXJ0aWNpcGFudC5jb25uZWN0aW9uSWQgPSByZXNwb25zZS5pZDtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucGFydGljaXBhbnRzW3Jlc3BvbnNlLmlkXSA9IHRoaXMubG9jYWxQYXJ0aWNpcGFudDtcblxuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IHJvb21FdmVudCA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJ0aWNpcGFudHM6IG5ldyBBcnJheTxDb25uZWN0aW9uPigpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmVhbXM6IG5ldyBBcnJheTxTdHJlYW0+KClcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGxlbmd0aCA9IGV4UGFydGljaXBhbnRzLmxlbmd0aDtcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBjb25uZWN0aW9uID0gbmV3IENvbm5lY3Rpb24odGhpcy5vcGVuVmlkdSwgZmFsc2UsIHRoaXMsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4UGFydGljaXBhbnRzW2ldKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25uZWN0aW9uLmNyZWF0aW9uVGltZSA9IG5ldyBEYXRlKCkuZ2V0VGltZSgpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5wYXJ0aWNpcGFudHNbY29ubmVjdGlvbi5jb25uZWN0aW9uSWRdID0gY29ubmVjdGlvbjtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJvb21FdmVudC5wYXJ0aWNpcGFudHMucHVzaChjb25uZWN0aW9uKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBzdHJlYW1zID0gY29ubmVjdGlvbi5nZXRTdHJlYW1zKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQga2V5IGluIHN0cmVhbXMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcm9vbUV2ZW50LnN0cmVhbXMucHVzaChzdHJlYW1zW2tleV0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5zdWJzY3JpYmVUb1N0cmVhbXMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmVhbXNba2V5XS5zdWJzY3JpYmUoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gVXBkYXRlIGxvY2FsIENvbm5lY3Rpb24gb2JqZWN0IHByb3BlcnRpZXMgd2l0aCB2YWx1ZXMgcmV0dXJuZWQgYnkgc2VydmVyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmxvY2FsUGFydGljaXBhbnQuZGF0YSA9IHJlc3BvbnNlLm1ldGFkYXRhO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5sb2NhbFBhcnRpY2lwYW50LmNyZWF0aW9uVGltZSA9IG5ldyBEYXRlKCkuZ2V0VGltZSgpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBVcGRhdGVzIHRoZSB2YWx1ZSBvZiBwcm9wZXJ0eSAnY29ubmVjdGlvbicgaW4gU2Vzc2lvbiBvYmplY3RcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCd1cGRhdGUtY29ubmVjdGlvbi1vYmplY3QnLCBbeyBjb25uZWN0aW9uOiB0aGlzLmxvY2FsUGFydGljaXBhbnQgfV0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gT3duIGNvbm5lY3Rpb24gY3JlYXRlZCBldmVudFxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ2Nvbm5lY3Rpb25DcmVhdGVkJywgW3sgY29ubmVjdGlvbjogdGhpcy5sb2NhbFBhcnRpY2lwYW50IH1dKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gT25lIGNvbm5lY3Rpb24gY3JlYXRlZCBldmVudCBmb3IgZWFjaCBleGlzdGluZyBjb25uZWN0aW9uIGluIHRoZSBzZXNzaW9uXG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBwYXJ0IG9mIHJvb21FdmVudC5wYXJ0aWNpcGFudHMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgnY29ubmVjdGlvbkNyZWF0ZWQnLCBbeyBjb25uZWN0aW9uOiBwYXJ0IH1dKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgLy9pZiAodGhpcy5zdWJzY3JpYmVUb1N0cmVhbXMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAobGV0IHN0cmVhbSBvZiByb29tRXZlbnQuc3RyZWFtcykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdzdHJlYW1DcmVhdGVkJywgW3sgc3RyZWFtIH1dKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEFkZGluZyB0aGUgcmVtb3RlIHN0cmVhbSB0byB0aGUgT3BlblZpZHUgb2JqZWN0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5vcGVuVmlkdS5nZXRSZW1vdGVTdHJlYW1zKCkucHVzaChzdHJlYW0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICBjYWxsYmFjayh1bmRlZmluZWQpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHB1Ymxpc2goKSB7XG4gICAgICAgIHRoaXMub3BlblZpZHUuZ2V0Q2FtZXJhKCkucHVibGlzaCgpO1xuICAgIH1cbiAgICAvKiBORVcgTUVUSE9EUyAqL1xuXG5cblxuXG5cbiAgICBjb25maWd1cmUob3B0aW9uczogU2Vzc2lvbk9wdGlvbnMpIHtcbiAgICAgICAgdGhpcy5vcHRpb25zID0gb3B0aW9ucztcbiAgICAgICAgdGhpcy5pZCA9IG9wdGlvbnMuc2Vzc2lvbklkO1xuICAgICAgICB0aGlzLnN1YnNjcmliZVRvU3RyZWFtcyA9IG9wdGlvbnMuc3Vic2NyaWJlVG9TdHJlYW1zID09IG51bGwgPyB0cnVlIDogb3B0aW9ucy5zdWJzY3JpYmVUb1N0cmVhbXM7XG4gICAgICAgIHRoaXMudXBkYXRlU3BlYWtlckludGVydmFsID0gb3B0aW9ucy51cGRhdGVTcGVha2VySW50ZXJ2YWwgfHwgMTUwMDtcbiAgICAgICAgdGhpcy50aHJlc2hvbGRTcGVha2VyID0gb3B0aW9ucy50aHJlc2hvbGRTcGVha2VyIHx8IC01MDtcbiAgICAgICAgdGhpcy5hY3RpdmF0ZVVwZGF0ZU1haW5TcGVha2VyKCk7XG4gICAgfVxuXG4gICAgZ2V0SWQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmlkO1xuICAgIH1cblxuICAgIGdldFNlc3Npb25JZCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuc2Vzc2lvbklkO1xuICAgIH1cblxuICAgIHByaXZhdGUgYWN0aXZhdGVVcGRhdGVNYWluU3BlYWtlcigpIHtcblxuICAgICAgICBzZXRJbnRlcnZhbCgoKSA9PiB7XG4gICAgICAgICAgICBpZiAodGhpcy5wYXJ0aWNpcGFudHNTcGVha2luZy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3VwZGF0ZS1tYWluLXNwZWFrZXInLCBbe1xuICAgICAgICAgICAgICAgICAgICBwYXJ0aWNpcGFudElkOiB0aGlzLnBhcnRpY2lwYW50c1NwZWFraW5nW3RoaXMucGFydGljaXBhbnRzU3BlYWtpbmcubGVuZ3RoIC0gMV1cbiAgICAgICAgICAgICAgICB9XSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sIHRoaXMudXBkYXRlU3BlYWtlckludGVydmFsKTtcbiAgICB9XG5cbiAgICBnZXRMb2NhbFBhcnRpY2lwYW50KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5sb2NhbFBhcnRpY2lwYW50O1xuICAgIH1cblxuICAgIGFkZEV2ZW50TGlzdGVuZXIoZXZlbnROYW1lLCBsaXN0ZW5lcikge1xuICAgICAgICB0aGlzLmVlLm9uKGV2ZW50TmFtZSwgbGlzdGVuZXIpO1xuICAgIH1cblxuICAgIGFkZE9uY2VFdmVudExpc3RlbmVyKGV2ZW50TmFtZSwgbGlzdGVuZXIpIHtcbiAgICAgICAgdGhpcy5lZS5vbmNlKGV2ZW50TmFtZSwgbGlzdGVuZXIpO1xuICAgIH1cblxuICAgIHJlbW92ZUxpc3RlbmVyKGV2ZW50TmFtZSwgbGlzdGVuZXIpIHtcbiAgICAgICAgdGhpcy5lZS5vZmYoZXZlbnROYW1lLCBsaXN0ZW5lcik7XG4gICAgfVxuXG4gICAgcmVtb3ZlRXZlbnQoZXZlbnROYW1lKSB7XG4gICAgICAgIHRoaXMuZWUucmVtb3ZlRXZlbnQoZXZlbnROYW1lKTtcbiAgICB9XG5cbiAgICBlbWl0RXZlbnQoZXZlbnROYW1lLCBldmVudHNBcnJheSkge1xuICAgICAgICB0aGlzLmVlLmVtaXRFdmVudChldmVudE5hbWUsIGV2ZW50c0FycmF5KTtcbiAgICB9XG5cblxuICAgIHN1YnNjcmliZShzdHJlYW06IFN0cmVhbSkge1xuICAgICAgICBzdHJlYW0uc3Vic2NyaWJlKCk7XG4gICAgfVxuXG4gICAgdW5zdXNjcmliZShzdHJlYW0pIHtcbiAgICAgICAgY29uc29sZS5pbmZvKFwiVW5zdWJzY3JpYmluZyBmcm9tIFwiICsgc3RyZWFtLmdldElkKCkpO1xuICAgICAgICB0aGlzLm9wZW5WaWR1LnNlbmRSZXF1ZXN0KCd1bnN1YnNjcmliZUZyb21WaWRlbycsIHtcbiAgICAgICAgICAgIHNlbmRlcjogc3RyZWFtLmdldElkKClcbiAgICAgICAgfSxcbiAgICAgICAgICAgIGZ1bmN0aW9uIChlcnJvciwgcmVzcG9uc2UpIHtcbiAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihcIkVycm9yIHVuc3Vic2NyaWJpbmcgZnJvbSBTdWJzY3JpYmVyXCIsIGVycm9yKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJVbnN1YnNjcmliZWQgY29ycmVjdGx5IGZyb20gXCIgKyBzdHJlYW0uZ2V0SWQoKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgb25QYXJ0aWNpcGFudFB1Ymxpc2hlZChvcHRpb25zKSB7XG5cbiAgICAgICAgLy8gR2V0IHRoZSBleGlzdGluZyBDb25uZWN0aW9uIGNyZWF0ZWQgb24gJ29uUGFydGljaXBhbnRKb2luZWQnIGZvclxuICAgICAgICAvLyBleGlzdGluZyBwYXJ0aWNpcGFudHMgb3IgY3JlYXRlIGEgbmV3IG9uZSBmb3IgbmV3IHBhcnRpY2lwYW50c1xuICAgICAgICBsZXQgY29ubmVjdGlvbiA9IHRoaXMucGFydGljaXBhbnRzW29wdGlvbnMuaWRdO1xuICAgICAgICBpZiAoY29ubmVjdGlvbikge1xuICAgICAgICAgICAgLy8gVXBkYXRlIGV4aXN0aW5nIENvbm5lY3Rpb25cbiAgICAgICAgICAgIG9wdGlvbnMubWV0YWRhdGEgPSBjb25uZWN0aW9uLmRhdGE7XG4gICAgICAgICAgICBjb25uZWN0aW9uLm9wdGlvbnMgPSBvcHRpb25zO1xuICAgICAgICAgICAgY29ubmVjdGlvbi5pbml0U3RyZWFtcyhvcHRpb25zKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIENyZWF0ZSBuZXcgQ29ubmVjdGlvblxuICAgICAgICAgICAgY29ubmVjdGlvbiA9IG5ldyBDb25uZWN0aW9uKHRoaXMub3BlblZpZHUsIGZhbHNlLCB0aGlzLCBvcHRpb25zKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGxldCBwaWQgPSBjb25uZWN0aW9uLmNvbm5lY3Rpb25JZDtcbiAgICAgICAgaWYgKCEocGlkIGluIHRoaXMucGFydGljaXBhbnRzKSkge1xuICAgICAgICAgICAgY29uc29sZS5kZWJ1ZyhcIlJlbW90ZSBDb25uZWN0aW9uIG5vdCBmb3VuZCBpbiBjb25uZWN0aW9ucyBsaXN0IGJ5IGl0cyBpZCBbXCIgKyBwaWQgKyBcIl1cIik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zb2xlLmRlYnVnKFwiUmVtb3RlIENvbm5lY3Rpb24gZm91bmQgaW4gY29ubmVjdGlvbnMgbGlzdCBieSBpdHMgaWQgW1wiICsgcGlkICsgXCJdXCIpO1xuICAgICAgICB9XG5cbiAgICAgICAgXG4gICAgICAgIHRoaXMucGFydGljaXBhbnRzW3BpZF0gPSBjb25uZWN0aW9uO1xuXG4gICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdwYXJ0aWNpcGFudC1wdWJsaXNoZWQnLCBbeyBjb25uZWN0aW9uIH1dKTtcblxuICAgICAgICBsZXQgc3RyZWFtcyA9IGNvbm5lY3Rpb24uZ2V0U3RyZWFtcygpO1xuICAgICAgICBmb3IgKGxldCBrZXkgaW4gc3RyZWFtcykge1xuXG4gICAgICAgICAgICBjb25zb2xlLmxvZygnJyk7XG5cbiAgICAgICAgICAgIGxldCBzdHJlYW0gPSBzdHJlYW1zW2tleV07XG4gICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgnc3RyZWFtQ3JlYXRlZCcsIFt7IHN0cmVhbSB9XSk7XG5cbiAgICAgICAgICAgIGlmICh0aGlzLnN1YnNjcmliZVRvU3RyZWFtcykge1xuICAgICAgICAgICAgICAgIHN0cmVhbS5zdWJzY3JpYmUoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIFxuICAgICAgICAgICAgLy8gQWRkaW5nIHRoZSByZW1vdGUgc3RyZWFtIHRvIHRoZSBPcGVuVmlkdSBvYmplY3RcbiAgICAgICAgICAgIHRoaXMub3BlblZpZHUuZ2V0UmVtb3RlU3RyZWFtcygpLnB1c2goc3RyZWFtKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIG9uUGFydGljaXBhbnRKb2luZWQobXNnKSB7XG5cbiAgICAgICAgbGV0IGNvbm5lY3Rpb24gPSBuZXcgQ29ubmVjdGlvbih0aGlzLm9wZW5WaWR1LCBmYWxzZSwgdGhpcywgbXNnKTtcbiAgICAgICAgY29ubmVjdGlvbi5jcmVhdGlvblRpbWUgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcblxuICAgICAgICBsZXQgcGlkID0gY29ubmVjdGlvbi5jb25uZWN0aW9uSWQ7XG4gICAgICAgIGlmICghKHBpZCBpbiB0aGlzLnBhcnRpY2lwYW50cykpIHtcbiAgICAgICAgICAgIHRoaXMucGFydGljaXBhbnRzW3BpZF0gPSBjb25uZWN0aW9uO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy91c2UgZXhpc3Rpbmcgc28gdGhhdCB3ZSBkb24ndCBsb3NlIHN0cmVhbXMgaW5mb1xuICAgICAgICAgICAgY29uc29sZS53YXJuKFwiQ29ubmVjdGlvbiBhbHJlYWR5IGV4aXN0cyBpbiBjb25uZWN0aW9ucyBsaXN0IHdpdGggXCIgK1xuICAgICAgICAgICAgICAgIFwidGhlIHNhbWUgY29ubmVjdGlvbklkLCBvbGQ6XCIsIHRoaXMucGFydGljaXBhbnRzW3BpZF0sIFwiLCBqb2luZWQgbm93OlwiLCBjb25uZWN0aW9uKTtcbiAgICAgICAgICAgIGNvbm5lY3Rpb24gPSB0aGlzLnBhcnRpY2lwYW50c1twaWRdO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3BhcnRpY2lwYW50LWpvaW5lZCcsIFt7XG4gICAgICAgICAgICBjb25uZWN0aW9uOiBjb25uZWN0aW9uXG4gICAgICAgIH1dKTtcblxuICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgnY29ubmVjdGlvbkNyZWF0ZWQnLCBbe1xuICAgICAgICAgICAgY29ubmVjdGlvbjogY29ubmVjdGlvblxuICAgICAgICB9XSk7XG5cbiAgICB9XG5cbiAgICBvblBhcnRpY2lwYW50TGVmdChtc2cpIHtcblxuICAgICAgICBsZXQgY29ubmVjdGlvbiA9IHRoaXMucGFydGljaXBhbnRzW21zZy5uYW1lXTtcblxuICAgICAgICBpZiAoY29ubmVjdGlvbiAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBkZWxldGUgdGhpcy5wYXJ0aWNpcGFudHNbbXNnLm5hbWVdO1xuXG4gICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgncGFydGljaXBhbnQtbGVmdCcsIFt7XG4gICAgICAgICAgICAgICAgY29ubmVjdGlvbjogY29ubmVjdGlvblxuICAgICAgICAgICAgfV0pO1xuXG4gICAgICAgICAgICBsZXQgc3RyZWFtcyA9IGNvbm5lY3Rpb24uZ2V0U3RyZWFtcygpO1xuICAgICAgICAgICAgZm9yIChsZXQga2V5IGluIHN0cmVhbXMpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgnc3RyZWFtRGVzdHJveWVkJywgW3tcbiAgICAgICAgICAgICAgICAgICAgc3RyZWFtOiBzdHJlYW1zW2tleV0sXG4gICAgICAgICAgICAgICAgICAgIHByZXZlbnREZWZhdWx0OiAoKSA9PiB7IHRoaXMuZWUucmVtb3ZlRXZlbnQoJ3N0cmVhbS1kZXN0cm95ZWQtZGVmYXVsdCcpOyB9XG4gICAgICAgICAgICAgICAgfV0pO1xuICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdzdHJlYW0tZGVzdHJveWVkLWRlZmF1bHQnLCBbe1xuICAgICAgICAgICAgICAgICAgICBzdHJlYW06IHN0cmVhbXNba2V5XVxuICAgICAgICAgICAgICAgIH1dKTtcblxuICAgICAgICAgICAgICAgIC8vIERlbGV0aW5nIHRoZSByZW1vdmVkIHN0cmVhbSBmcm9tIHRoZSBPcGVuVmlkdSBvYmplY3RcbiAgICAgICAgICAgICAgICBsZXQgaW5kZXggPSB0aGlzLm9wZW5WaWR1LmdldFJlbW90ZVN0cmVhbXMoKS5pbmRleE9mKHN0cmVhbXNba2V5XSk7XG4gICAgICAgICAgICAgICAgdGhpcy5vcGVuVmlkdS5nZXRSZW1vdGVTdHJlYW1zKCkuc3BsaWNlKGluZGV4LCAxKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29ubmVjdGlvbi5kaXNwb3NlKCk7XG5cbiAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdjb25uZWN0aW9uRGVzdHJveWVkJywgW3tcbiAgICAgICAgICAgICAgICBjb25uZWN0aW9uOiBjb25uZWN0aW9uXG4gICAgICAgICAgICB9XSk7XG5cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbnNvbGUud2FybihcIlBhcnRpY2lwYW50IFwiICsgbXNnLm5hbWVcbiAgICAgICAgICAgICAgICArIFwiIHVua25vd24uIFBhcnRpY2lwYW50czogXCJcbiAgICAgICAgICAgICAgICArIEpTT04uc3RyaW5naWZ5KHRoaXMucGFydGljaXBhbnRzKSk7XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgb25QYXJ0aWNpcGFudEV2aWN0ZWQobXNnKSB7XG4gICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdwYXJ0aWNpcGFudC1ldmljdGVkJywgW3tcbiAgICAgICAgICAgIGxvY2FsUGFydGljaXBhbnQ6IHRoaXMubG9jYWxQYXJ0aWNpcGFudFxuICAgICAgICB9XSk7XG4gICAgfTtcblxuICAgIG9uTmV3TWVzc2FnZShtc2cpIHtcblxuICAgICAgICBjb25zb2xlLmluZm8oXCJOZXcgbWVzc2FnZTogXCIgKyBKU09OLnN0cmluZ2lmeShtc2cpKTtcbiAgICAgICAgbGV0IHJvb20gPSBtc2cucm9vbTtcbiAgICAgICAgbGV0IHVzZXIgPSBtc2cudXNlcjtcbiAgICAgICAgbGV0IG1lc3NhZ2UgPSBtc2cubWVzc2FnZTtcblxuICAgICAgICBpZiAodXNlciAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgnbmV3TWVzc2FnZScsIFt7XG4gICAgICAgICAgICAgICAgcm9vbTogcm9vbSxcbiAgICAgICAgICAgICAgICB1c2VyOiB1c2VyLFxuICAgICAgICAgICAgICAgIG1lc3NhZ2U6IG1lc3NhZ2VcbiAgICAgICAgICAgIH1dKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbnNvbGUud2FybihcIlVzZXIgdW5kZWZpbmVkIGluIG5ldyBtZXNzYWdlOlwiLCBtc2cpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmVjdkljZUNhbmRpZGF0ZShtc2cpIHtcblxuICAgICAgICBsZXQgY2FuZGlkYXRlID0ge1xuICAgICAgICAgICAgY2FuZGlkYXRlOiBtc2cuY2FuZGlkYXRlLFxuICAgICAgICAgICAgc2RwTWlkOiBtc2cuc2RwTWlkLFxuICAgICAgICAgICAgc2RwTUxpbmVJbmRleDogbXNnLnNkcE1MaW5lSW5kZXhcbiAgICAgICAgfVxuXG4gICAgICAgIGxldCBjb25uZWN0aW9uID0gdGhpcy5wYXJ0aWNpcGFudHNbbXNnLmVuZHBvaW50TmFtZV07XG4gICAgICAgIGlmICghY29ubmVjdGlvbikge1xuICAgICAgICAgICAgY29uc29sZS5lcnJvcihcIlBhcnRpY2lwYW50IG5vdCBmb3VuZCBmb3IgZW5kcG9pbnQgXCIgK1xuICAgICAgICAgICAgICAgIG1zZy5lbmRwb2ludE5hbWUgKyBcIi4gSWNlIGNhbmRpZGF0ZSB3aWxsIGJlIGlnbm9yZWQuXCIsXG4gICAgICAgICAgICAgICAgY2FuZGlkYXRlKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGxldCBzdHJlYW1zID0gY29ubmVjdGlvbi5nZXRTdHJlYW1zKCk7XG4gICAgICAgIGZvciAobGV0IGtleSBpbiBzdHJlYW1zKSB7XG4gICAgICAgICAgICBsZXQgc3RyZWFtID0gc3RyZWFtc1trZXldO1xuICAgICAgICAgICAgc3RyZWFtLmdldFdlYlJ0Y1BlZXIoKS5hZGRJY2VDYW5kaWRhdGUoY2FuZGlkYXRlLCBmdW5jdGlvbiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihcIkVycm9yIGFkZGluZyBjYW5kaWRhdGUgZm9yIFwiICsga2V5XG4gICAgICAgICAgICAgICAgICAgICAgICArIFwiIHN0cmVhbSBvZiBlbmRwb2ludCBcIiArIG1zZy5lbmRwb2ludE5hbWVcbiAgICAgICAgICAgICAgICAgICAgICAgICsgXCI6IFwiICsgZXJyb3IpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgb25Sb29tQ2xvc2VkKG1zZykge1xuXG4gICAgICAgIGNvbnNvbGUuaW5mbyhcIlJvb20gY2xvc2VkOiBcIiArIEpTT04uc3RyaW5naWZ5KG1zZykpO1xuICAgICAgICBsZXQgcm9vbSA9IG1zZy5yb29tO1xuICAgICAgICBpZiAocm9vbSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgncm9vbS1jbG9zZWQnLCBbe1xuICAgICAgICAgICAgICAgIHJvb206IHJvb21cbiAgICAgICAgICAgIH1dKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbnNvbGUud2FybihcIlJvb20gdW5kZWZpbmVkIGluIG9uIHJvb20gY2xvc2VkXCIsIG1zZyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBvbkxvc3RDb25uZWN0aW9uKCkge1xuXG4gICAgICAgIGlmICghdGhpcy5jb25uZWN0ZWQpIHtcbiAgICAgICAgICAgIGNvbnNvbGUud2FybignTm90IGNvbm5lY3RlZCB0byByb29tOiBpZiB5b3UgYXJlIG5vdCBkZWJ1Z2dpbmcsIHRoaXMgaXMgcHJvYmFibHkgYSBjZXJ0aWZpY2F0ZSBlcnJvcicpO1xuICAgICAgICAgICAgaWYgKHdpbmRvdy5jb25maXJtKCdJZiB5b3UgYXJlIG5vdCBkZWJ1Z2dpbmcsIHRoaXMgaXMgcHJvYmFibHkgYSBjZXJ0aWZpY2F0ZSBlcnJvciBhdCBcXFwiJyArIHRoaXMub3BlblZpZHUuZ2V0T3BlblZpZHVTZXJ2ZXJVUkwoKSArICdcXFwiXFxuXFxuQ2xpY2sgT0sgdG8gbmF2aWdhdGUgYW5kIGFjY2VwdCBpdCcpKSB7XG4gICAgICAgICAgICAgICAgbG9jYXRpb24uYXNzaWduKHRoaXMub3BlblZpZHUuZ2V0T3BlblZpZHVTZXJ2ZXJVUkwoKSArICcvYWNjZXB0LWNlcnRpZmljYXRlJyk7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc29sZS53YXJuKCdMb3N0IGNvbm5lY3Rpb24gaW4gU2Vzc2lvbiAnICsgdGhpcy5pZCk7XG4gICAgICAgIGxldCByb29tID0gdGhpcy5pZDtcbiAgICAgICAgaWYgKHJvb20gIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ2xvc3QtY29ubmVjdGlvbicsIFt7IHJvb20gfV0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29uc29sZS53YXJuKCdSb29tIHVuZGVmaW5lZCB3aGVuIGxvc3QgY29ubmVjdGlvbicpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgb25NZWRpYUVycm9yKHBhcmFtcykge1xuXG4gICAgICAgIGNvbnNvbGUuZXJyb3IoXCJNZWRpYSBlcnJvcjogXCIgKyBKU09OLnN0cmluZ2lmeShwYXJhbXMpKTtcbiAgICAgICAgbGV0IGVycm9yID0gcGFyYW1zLmVycm9yO1xuICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdlcnJvci1tZWRpYScsIFt7XG4gICAgICAgICAgICAgICAgZXJyb3I6IGVycm9yXG4gICAgICAgICAgICB9XSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zb2xlLndhcm4oXCJSZWNlaXZlZCB1bmRlZmluZWQgbWVkaWEgZXJyb3IuIFBhcmFtczpcIiwgcGFyYW1zKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qXG4gICAgICogZm9yY2VkIG1lYW5zIHRoZSB1c2VyIHdhcyBldmljdGVkLCBubyBuZWVkIHRvIHNlbmQgdGhlICdsZWF2ZVJvb20nIHJlcXVlc3RcbiAgICAgKi9cbiAgICBsZWF2ZShmb3JjZWQsIGpzb25ScGNDbGllbnQpIHtcblxuICAgICAgICBmb3JjZWQgPSAhIWZvcmNlZDtcblxuICAgICAgICBjb25zb2xlLmluZm8oXCJMZWF2aW5nIFNlc3Npb24gKGZvcmNlZD1cIiArIGZvcmNlZCArIFwiKVwiKTtcblxuICAgICAgICBpZiAodGhpcy5jb25uZWN0ZWQgJiYgIWZvcmNlZCkge1xuICAgICAgICAgICAgdGhpcy5vcGVuVmlkdS5zZW5kUmVxdWVzdCgnbGVhdmVSb29tJywgZnVuY3Rpb24gKGVycm9yLCByZXNwb25zZSkge1xuICAgICAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKGVycm9yKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAganNvblJwY0NsaWVudC5jbG9zZSgpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBqc29uUnBjQ2xpZW50LmNsb3NlKCk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5jb25uZWN0ZWQgPSBmYWxzZTtcbiAgICAgICAgaWYgKHRoaXMucGFydGljaXBhbnRzKSB7XG4gICAgICAgICAgICBmb3IgKGxldCBwaWQgaW4gdGhpcy5wYXJ0aWNpcGFudHMpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnBhcnRpY2lwYW50c1twaWRdLmRpc3Bvc2UoKTtcbiAgICAgICAgICAgICAgICBkZWxldGUgdGhpcy5wYXJ0aWNpcGFudHNbcGlkXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIGRpc2Nvbm5lY3Qoc3RyZWFtOiBTdHJlYW0pIHtcblxuICAgICAgICBsZXQgY29ubmVjdGlvbiA9IHN0cmVhbS5nZXRQYXJ0aWNpcGFudCgpO1xuICAgICAgICBpZiAoIWNvbm5lY3Rpb24pIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoXCJTdHJlYW0gdG8gZGlzY29ubmVjdCBoYXMgbm8gcGFydGljaXBhbnRcIiwgc3RyZWFtKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGRlbGV0ZSB0aGlzLnBhcnRpY2lwYW50c1tjb25uZWN0aW9uLmNvbm5lY3Rpb25JZF07XG4gICAgICAgIGNvbm5lY3Rpb24uZGlzcG9zZSgpO1xuXG4gICAgICAgIGlmIChjb25uZWN0aW9uID09PSB0aGlzLmxvY2FsUGFydGljaXBhbnQpIHtcblxuICAgICAgICAgICAgY29uc29sZS5pbmZvKFwiVW5wdWJsaXNoaW5nIG15IG1lZGlhIChJJ20gXCIgKyBjb25uZWN0aW9uLmNvbm5lY3Rpb25JZCArIFwiKVwiKTtcbiAgICAgICAgICAgIGRlbGV0ZSB0aGlzLmxvY2FsUGFydGljaXBhbnQ7XG4gICAgICAgICAgICB0aGlzLm9wZW5WaWR1LnNlbmRSZXF1ZXN0KCd1bnB1Ymxpc2hWaWRlbycsIGZ1bmN0aW9uIChlcnJvciwgcmVzcG9uc2UpIHtcbiAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKFwiTWVkaWEgdW5wdWJsaXNoZWQgY29ycmVjdGx5XCIpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnVuc3VzY3JpYmUoc3RyZWFtKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHVucHVibGlzaChzdHJlYW06IFN0cmVhbSkge1xuXG4gICAgICAgIGxldCBjb25uZWN0aW9uID0gc3RyZWFtLmdldFBhcnRpY2lwYW50KCk7XG4gICAgICAgIGlmICghY29ubmVjdGlvbikge1xuICAgICAgICAgICAgY29uc29sZS5lcnJvcihcIlN0cmVhbSB0byBkaXNjb25uZWN0IGhhcyBubyBwYXJ0aWNpcGFudFwiLCBzdHJlYW0pO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGNvbm5lY3Rpb24gPT09IHRoaXMubG9jYWxQYXJ0aWNpcGFudCkge1xuXG4gICAgICAgICAgICBkZWxldGUgdGhpcy5wYXJ0aWNpcGFudHNbY29ubmVjdGlvbi5jb25uZWN0aW9uSWRdO1xuICAgICAgICAgICAgY29ubmVjdGlvbi5kaXNwb3NlKCk7XG5cbiAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIlVucHVibGlzaGluZyBteSBtZWRpYSAoSSdtIFwiICsgY29ubmVjdGlvbi5jb25uZWN0aW9uSWQgKyBcIilcIik7XG4gICAgICAgICAgICBkZWxldGUgdGhpcy5sb2NhbFBhcnRpY2lwYW50O1xuICAgICAgICAgICAgdGhpcy5vcGVuVmlkdS5zZW5kUmVxdWVzdCgndW5wdWJsaXNoVmlkZW8nLCBmdW5jdGlvbiAoZXJyb3IsIHJlc3BvbnNlKSB7XG4gICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIk1lZGlhIHVucHVibGlzaGVkIGNvcnJlY3RseVwiKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGdldFN0cmVhbXMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnN0cmVhbXM7XG4gICAgfVxuXG4gICAgYWRkUGFydGljaXBhbnRTcGVha2luZyhwYXJ0aWNpcGFudElkKSB7XG4gICAgICAgIHRoaXMucGFydGljaXBhbnRzU3BlYWtpbmcucHVzaChwYXJ0aWNpcGFudElkKTtcbiAgICB9XG5cbiAgICByZW1vdmVQYXJ0aWNpcGFudFNwZWFraW5nKHBhcnRpY2lwYW50SWQpIHtcbiAgICAgICAgbGV0IHBvcyA9IC0xO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMucGFydGljaXBhbnRzU3BlYWtpbmcubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGlmICh0aGlzLnBhcnRpY2lwYW50c1NwZWFraW5nW2ldID09IHBhcnRpY2lwYW50SWQpIHtcbiAgICAgICAgICAgICAgICBwb3MgPSBpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChwb3MgIT0gLTEpIHtcbiAgICAgICAgICAgIHRoaXMucGFydGljaXBhbnRzU3BlYWtpbmcuc3BsaWNlKHBvcywgMSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBzdHJpbmdDbGllbnRNZXRhZGF0YShtZXRhZGF0YSk6IHN0cmluZyB7XG4gICAgICAgIGlmICghKHR5cGVvZiBtZXRhZGF0YSA9PT0gJ3N0cmluZycpKSB7XG4gICAgICAgICAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkobWV0YWRhdGEpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIG1ldGFkYXRhO1xuICAgICAgICB9XG4gICAgfVxuICAgIFxuICAgIHByaXZhdGUgcmFuZG9tVG9rZW4oKTogc3RyaW5nIHtcbiAgICAgICAgcmV0dXJuIE1hdGgucmFuZG9tKCkudG9TdHJpbmcoMzYpLnNsaWNlKDIpICsgTWF0aC5yYW5kb20oKS50b1N0cmluZygzNikuc2xpY2UoMik7XG4gICAgfVxuXG59XG4iLCIvKlxuICogb3B0aW9uczogbmFtZTogWFhYIGRhdGE6IHRydWUgKE1heWJlIHRoaXMgaXMgYmFzZWQgb24gd2VicnRjKSBhdWRpbzogdHJ1ZSxcbiAqIHZpZGVvOiB0cnVlLCB1cmw6IFwiZmlsZTovLy8uLi5cIiA+IFBsYXllciBzY3JlZW46IHRydWUgPiBEZXNrdG9wIChpbXBsaWNpdFxuICogdmlkZW86dHJ1ZSwgYXVkaW86ZmFsc2UpIGF1ZGlvOiB0cnVlLCB2aWRlbzogdHJ1ZSA+IFdlYmNhbVxuICpcbiAqIHN0cmVhbS5oYXNBdWRpbygpOyBzdHJlYW0uaGFzVmlkZW8oKTsgc3RyZWFtLmhhc0RhdGEoKTtcbiAqL1xuaW1wb3J0IHsgQ29ubmVjdGlvbiB9IGZyb20gJy4vQ29ubmVjdGlvbic7XG5pbXBvcnQgeyBTZXNzaW9uSW50ZXJuYWwgfSBmcm9tICcuL1Nlc3Npb25JbnRlcm5hbCc7XG5pbXBvcnQgeyBPcGVuVmlkdUludGVybmFsLCBDYWxsYmFjayB9IGZyb20gJy4vT3BlblZpZHVJbnRlcm5hbCc7XG5pbXBvcnQgRXZlbnRFbWl0dGVyID0gcmVxdWlyZSgnd29sZnk4Ny1ldmVudGVtaXR0ZXInKTtcbmltcG9ydCAqIGFzIGt1cmVudG9VdGlscyBmcm9tICcuLi9LdXJlbnRvVXRpbHMva3VyZW50by11dGlscy1qcyc7XG5cbmltcG9ydCAqIGFzIGFkYXB0ZXIgZnJvbSAnd2VicnRjLWFkYXB0ZXInO1xuZGVjbGFyZSB2YXIgbmF2aWdhdG9yOiBhbnk7XG5kZWNsYXJlIHZhciBSVENTZXNzaW9uRGVzY3JpcHRpb246IGFueTtcblxuaWYgKHdpbmRvdykge1xuICAgIHdpbmRvd1tcImFkYXB0ZXJcIl0gPSBhZGFwdGVyO1xufVxuXG5mdW5jdGlvbiBqcShpZDogc3RyaW5nKTogc3RyaW5nIHtcbiAgICByZXR1cm4gaWQucmVwbGFjZSgvKEB8OnxcXC58XFxbfFxcXXwsKS9nLCBcIlxcXFwkMVwiKTtcbn1cblxuZnVuY3Rpb24gc2hvdyhpZDogc3RyaW5nKSB7XG4gICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoanEoaWQpKSEuc3R5bGUuZGlzcGxheSA9ICdibG9jayc7XG59XG5cbmZ1bmN0aW9uIGhpZGUoaWQ6IHN0cmluZykge1xuICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGpxKGlkKSkhLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgU3RyZWFtT3B0aW9ucyB7XG4gICAgaWQ6IHN0cmluZztcbiAgICBjb25uZWN0aW9uOiBDb25uZWN0aW9uO1xuICAgIHJlY3ZWaWRlbzogYm9vbGVhbjtcbiAgICByZWN2QXVkaW86IGJvb2xlYW47XG4gICAgc2VuZFZpZGVvOiBib29sZWFuO1xuICAgIHNlbmRBdWRpbzogYm9vbGVhbjtcbiAgICBhY3RpdmVBdWRpbzogYm9vbGVhbjtcbiAgICBhY3RpdmVWaWRlbzogYm9vbGVhbjtcbiAgICBkYXRhOiBib29sZWFuO1xuICAgIG1lZGlhQ29uc3RyYWludHM6IGFueTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBWaWRlb09wdGlvbnMge1xuICAgIHRodW1iOiBzdHJpbmc7XG4gICAgdmlkZW86IEhUTUxWaWRlb0VsZW1lbnQ7XG59XG5cbmV4cG9ydCBjbGFzcyBTdHJlYW0ge1xuXG4gICAgcHVibGljIGNvbm5lY3Rpb246IENvbm5lY3Rpb247XG5cbiAgICBwcml2YXRlIGVlID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuICAgIHByaXZhdGUgd3JTdHJlYW06IE1lZGlhU3RyZWFtO1xuICAgIHByaXZhdGUgd3A6IGFueTtcbiAgICBwcml2YXRlIGlkOiBzdHJpbmc7XG4gICAgcHJpdmF0ZSB2aWRlbzogSFRNTFZpZGVvRWxlbWVudDtcbiAgICBwcml2YXRlIHZpZGVvRWxlbWVudHM6IFZpZGVvT3B0aW9uc1tdID0gW107XG4gICAgcHJpdmF0ZSBlbGVtZW50czogSFRNTERpdkVsZW1lbnRbXSA9IFtdO1xuICAgIHByaXZhdGUgc3BlZWNoRXZlbnQ6IGFueTtcbiAgICBwcml2YXRlIHJlY3ZWaWRlbzogYm9vbGVhbjtcbiAgICBwcml2YXRlIHJlY3ZBdWRpbzogYm9vbGVhbjtcbiAgICBwcml2YXRlIHNlbmRWaWRlbzogYm9vbGVhbjtcbiAgICBwcml2YXRlIHNlbmRBdWRpbzogYm9vbGVhbjtcbiAgICBwcml2YXRlIG1lZGlhQ29uc3RyYWludHM6IGFueTtcbiAgICBwcml2YXRlIHNob3dNeVJlbW90ZSA9IGZhbHNlO1xuICAgIHByaXZhdGUgbG9jYWxNaXJyb3JlZCA9IGZhbHNlO1xuICAgIHByaXZhdGUgY2hhbklkID0gMDtcbiAgICBwcml2YXRlIGRhdGFDaGFubmVsOiBib29sZWFuO1xuICAgIHByaXZhdGUgZGF0YUNoYW5uZWxPcGVuZWQgPSBmYWxzZTtcblxuICAgIHByaXZhdGUgYWN0aXZlQXVkaW8gPSB0cnVlO1xuICAgIHByaXZhdGUgYWN0aXZlVmlkZW8gPSB0cnVlO1xuXG4gICAgcHJpdmF0ZSB2aWRlb1NyY09iamVjdDogTWVkaWFTdHJlYW0gfCBudWxsO1xuICAgIHByaXZhdGUgcGFyZW50SWQ6IHN0cmluZztcbiAgICBwdWJsaWMgaXNSZWFkeTogYm9vbGVhbiA9IGZhbHNlO1xuICAgIHB1YmxpYyBpc1ZpZGVvRUxlbWVudENyZWF0ZWQ6IGJvb2xlYW4gPSBmYWxzZTtcbiAgICBwdWJsaWMgYWNjZXNzSXNBbGxvd2VkOiBib29sZWFuID0gZmFsc2U7XG4gICAgcHVibGljIGFjY2Vzc0lzRGVuaWVkOiBib29sZWFuID0gZmFsc2U7XG5cbiAgICBjb25zdHJ1Y3Rvcihwcml2YXRlIG9wZW5WaWR1OiBPcGVuVmlkdUludGVybmFsLCBwcml2YXRlIGxvY2FsOiBib29sZWFuLCBwcml2YXRlIHJvb206IFNlc3Npb25JbnRlcm5hbCwgb3B0aW9uczogU3RyZWFtT3B0aW9ucykge1xuXG4gICAgICAgIGlmIChvcHRpb25zLmlkKSB7XG4gICAgICAgICAgICB0aGlzLmlkID0gb3B0aW9ucy5pZDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuaWQgPSBcIndlYmNhbVwiO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5jb25uZWN0aW9uID0gb3B0aW9ucy5jb25uZWN0aW9uO1xuICAgICAgICB0aGlzLnJlY3ZWaWRlbyA9IG9wdGlvbnMucmVjdlZpZGVvIHx8IGZhbHNlO1xuICAgICAgICB0aGlzLnJlY3ZBdWRpbyA9IG9wdGlvbnMucmVjdkF1ZGlvIHx8IGZhbHNlO1xuICAgICAgICB0aGlzLnNlbmRWaWRlbyA9IG9wdGlvbnMuc2VuZFZpZGVvO1xuICAgICAgICB0aGlzLnNlbmRBdWRpbyA9IG9wdGlvbnMuc2VuZEF1ZGlvO1xuICAgICAgICB0aGlzLmFjdGl2ZUF1ZGlvID0gb3B0aW9ucy5hY3RpdmVBdWRpbztcbiAgICAgICAgdGhpcy5hY3RpdmVWaWRlbyA9IG9wdGlvbnMuYWN0aXZlVmlkZW87XG4gICAgICAgIHRoaXMuZGF0YUNoYW5uZWwgPSBvcHRpb25zLmRhdGEgfHwgZmFsc2U7XG4gICAgICAgIHRoaXMubWVkaWFDb25zdHJhaW50cyA9IG9wdGlvbnMubWVkaWFDb25zdHJhaW50cztcblxuICAgICAgICB0aGlzLmFkZEV2ZW50TGlzdGVuZXIoJ3NyYy1hZGRlZCcsIChzcmNFdmVudCkgPT4ge1xuICAgICAgICAgICAgdGhpcy52aWRlb1NyY09iamVjdCA9IHNyY0V2ZW50LnNyY09iamVjdDtcbiAgICAgICAgICAgIGlmICh0aGlzLnZpZGVvKSB0aGlzLnZpZGVvLnNyY09iamVjdCA9IHNyY0V2ZW50LnNyY09iamVjdDtcbiAgICAgICAgICAgIGNvbnNvbGUuZGVidWcoXCJWaWRlbyBzcmNPYmplY3QgW1wiICsgc3JjRXZlbnQuc3JjT2JqZWN0ICsgXCJdIGFkZGVkIHRvIHN0cmVhbSBbXCIgKyB0aGlzLmdldElkKCkgKyBcIl1cIik7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIGVtaXRTcmNFdmVudCh3cnN0cmVhbSkge1xuICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgnc3JjLWFkZGVkJywgW3tcbiAgICAgICAgICAgIHNyY09iamVjdDogd3JzdHJlYW1cbiAgICAgICAgfV0pO1xuICAgIH1cblxuICAgIGVtaXRTdHJlYW1SZWFkeUV2ZW50KCkge1xuICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgnc3RyZWFtLXJlYWR5JyksIFt7fV07XG4gICAgfVxuXG4gICAgZ2V0VmlkZW9TcmNPYmplY3QoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnZpZGVvU3JjT2JqZWN0O1xuICAgIH1cblxuICAgIHJlbW92ZVZpZGVvKHBhcmVudEVsZW1lbnQ6IHN0cmluZyk7XG4gICAgcmVtb3ZlVmlkZW8ocGFyZW50RWxlbWVudDogRWxlbWVudCk7XG4gICAgcmVtb3ZlVmlkZW8oKTtcblxuICAgIHJlbW92ZVZpZGVvKHBhcmVudEVsZW1lbnQ/KSB7XG4gICAgICAgIGlmICh0eXBlb2YgcGFyZW50RWxlbWVudCA9PT0gXCJzdHJpbmdcIikge1xuICAgICAgICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQocGFyZW50RWxlbWVudCkhLnJlbW92ZUNoaWxkKHRoaXMudmlkZW8pO1xuICAgICAgICB9IGVsc2UgaWYgKHBhcmVudEVsZW1lbnQgaW5zdGFuY2VvZiBFbGVtZW50KSB7XG4gICAgICAgICAgICBwYXJlbnRFbGVtZW50LnJlbW92ZUNoaWxkKHRoaXMudmlkZW8pO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKCFwYXJlbnRFbGVtZW50KSB7XG4gICAgICAgICAgICBpZiAoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQodGhpcy5wYXJlbnRJZCkpIHtcbiAgICAgICAgICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCh0aGlzLnBhcmVudElkKSEucmVtb3ZlQ2hpbGQodGhpcy52aWRlbyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBnZXRWaWRlb0VsZW1lbnQoKTogSFRNTFZpZGVvRWxlbWVudCB7XG4gICAgICAgIHJldHVybiB0aGlzLnZpZGVvO1xuICAgIH1cblxuICAgIHNldFZpZGVvRWxlbWVudCh2aWRlbzogSFRNTFZpZGVvRWxlbWVudCkge1xuICAgICAgICB0aGlzLnZpZGVvID0gdmlkZW87XG4gICAgfVxuXG5cblxuXG5cblxuICAgIGdldFJlY3ZWaWRlbygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucmVjdlZpZGVvO1xuICAgIH1cblxuICAgIGdldFJlY3ZBdWRpbygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucmVjdkF1ZGlvO1xuICAgIH1cblxuXG4gICAgc3Vic2NyaWJlVG9NeVJlbW90ZSgpIHtcbiAgICAgICAgdGhpcy5zaG93TXlSZW1vdGUgPSB0cnVlO1xuICAgIH1cblxuICAgIGRpc3BsYXlNeVJlbW90ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuc2hvd015UmVtb3RlO1xuICAgIH1cblxuICAgIG1pcnJvckxvY2FsU3RyZWFtKHdyKSB7XG4gICAgICAgIHRoaXMuc2hvd015UmVtb3RlID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5sb2NhbE1pcnJvcmVkID0gdHJ1ZTtcbiAgICAgICAgaWYgKHdyKSB7XG4gICAgICAgICAgICB0aGlzLndyU3RyZWFtID0gd3I7XG4gICAgICAgICAgICB0aGlzLmVtaXRTcmNFdmVudCh0aGlzLndyU3RyZWFtKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGlzTG9jYWxNaXJyb3JlZCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubG9jYWxNaXJyb3JlZDtcbiAgICB9XG5cbiAgICBnZXRDaGFubmVsTmFtZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0SWQoKSArICdfJyArIHRoaXMuY2hhbklkKys7XG4gICAgfVxuXG5cbiAgICBpc0RhdGFDaGFubmVsRW5hYmxlZCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZGF0YUNoYW5uZWw7XG4gICAgfVxuXG5cbiAgICBpc0RhdGFDaGFubmVsT3BlbmVkKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5kYXRhQ2hhbm5lbE9wZW5lZDtcbiAgICB9XG5cbiAgICBvbkRhdGFDaGFubmVsT3BlbihldmVudCkge1xuICAgICAgICBjb25zb2xlLmRlYnVnKCdEYXRhIGNoYW5uZWwgaXMgb3BlbmVkJyk7XG4gICAgICAgIHRoaXMuZGF0YUNoYW5uZWxPcGVuZWQgPSB0cnVlO1xuICAgIH1cblxuICAgIG9uRGF0YUNoYW5uZWxDbG9zZWQoZXZlbnQpIHtcbiAgICAgICAgY29uc29sZS5kZWJ1ZygnRGF0YSBjaGFubmVsIGlzIGNsb3NlZCcpO1xuICAgICAgICB0aGlzLmRhdGFDaGFubmVsT3BlbmVkID0gZmFsc2U7XG4gICAgfVxuXG4gICAgc2VuZERhdGEoZGF0YSkge1xuICAgICAgICBpZiAodGhpcy53cCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1dlYlJUQyBwZWVyIGhhcyBub3QgYmVlbiBjcmVhdGVkIHlldCcpO1xuICAgICAgICB9XG4gICAgICAgIGlmICghdGhpcy5kYXRhQ2hhbm5lbE9wZW5lZCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdEYXRhIGNoYW5uZWwgaXMgbm90IG9wZW5lZCcpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnNvbGUuaW5mbyhcIlNlbmRpbmcgdGhyb3VnaCBkYXRhIGNoYW5uZWw6IFwiICsgZGF0YSk7XG4gICAgICAgIHRoaXMud3Auc2VuZChkYXRhKTtcbiAgICB9XG5cbiAgICBnZXRXclN0cmVhbSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMud3JTdHJlYW07XG4gICAgfVxuXG4gICAgZ2V0V2ViUnRjUGVlcigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMud3A7XG4gICAgfVxuXG4gICAgYWRkRXZlbnRMaXN0ZW5lcihldmVudE5hbWU6IHN0cmluZywgbGlzdGVuZXI6IGFueSkge1xuICAgICAgICB0aGlzLmVlLmFkZExpc3RlbmVyKGV2ZW50TmFtZSwgbGlzdGVuZXIpO1xuICAgIH1cblxuICAgIGFkZE9uY2VFdmVudExpc3RlbmVyKGV2ZW50TmFtZTogc3RyaW5nLCBsaXN0ZW5lcjogYW55KSB7XG4gICAgICAgIHRoaXMuZWUuYWRkT25jZUxpc3RlbmVyKGV2ZW50TmFtZSwgbGlzdGVuZXIpO1xuICAgIH1cblxuICAgIHJlbW92ZUxpc3RlbmVyKGV2ZW50TmFtZSkge1xuICAgICAgICB0aGlzLmVlLnJlbW92ZUFsbExpc3RlbmVycyhldmVudE5hbWUpO1xuICAgIH1cblxuICAgIHNob3dTcGlubmVyKHNwaW5uZXJQYXJlbnRJZDogc3RyaW5nKSB7XG4gICAgICAgIGxldCBwcm9ncmVzcyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgICBwcm9ncmVzcy5pZCA9ICdwcm9ncmVzcy0nICsgdGhpcy5nZXRJZCgpO1xuICAgICAgICBwcm9ncmVzcy5zdHlsZS5iYWNrZ3JvdW5kID0gXCJjZW50ZXIgdHJhbnNwYXJlbnQgdXJsKCdpbWcvc3Bpbm5lci5naWYnKSBuby1yZXBlYXRcIjtcbiAgICAgICAgbGV0IHNwaW5uZXJQYXJlbnQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChzcGlubmVyUGFyZW50SWQpO1xuICAgICAgICBpZiAoc3Bpbm5lclBhcmVudCkge1xuICAgICAgICAgICAgc3Bpbm5lclBhcmVudC5hcHBlbmRDaGlsZChwcm9ncmVzcyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBoaWRlU3Bpbm5lcihzcGlubmVySWQ/OiBzdHJpbmcpIHtcbiAgICAgICAgc3Bpbm5lcklkID0gKHNwaW5uZXJJZCA9PT0gdW5kZWZpbmVkKSA/IHRoaXMuZ2V0SWQoKSA6IHNwaW5uZXJJZDtcbiAgICAgICAgaGlkZSgncHJvZ3Jlc3MtJyArIHNwaW5uZXJJZCk7XG4gICAgfVxuXG4gICAgcGxheU9ubHlWaWRlbyhwYXJlbnRFbGVtZW50LCB0aHVtYm5haWxJZCkge1xuXG4gICAgICAgIC8vIFRPLURPOiBjaGVjayBzb21laG93IGlmIHRoZSBzdHJlYW0gaXMgYXVkaW8gb25seSwgc28gdGhlIGVsZW1lbnQgY3JlYXRlZCBpcyA8YXVkaW8+IGluc3RlYWQgb2YgPHZpZGVvPlxuXG4gICAgICAgIHRoaXMudmlkZW8gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCd2aWRlbycpO1xuXG4gICAgICAgIHRoaXMudmlkZW8uaWQgPSAodGhpcy5sb2NhbCA/ICdsb2NhbC0nIDogJ3JlbW90ZS0nKSArICd2aWRlby0nICsgdGhpcy5nZXRJZCgpO1xuICAgICAgICB0aGlzLnZpZGVvLmF1dG9wbGF5ID0gdHJ1ZTtcbiAgICAgICAgdGhpcy52aWRlby5jb250cm9scyA9IGZhbHNlO1xuICAgICAgICB0aGlzLnZpZGVvLnNyY09iamVjdCA9IHRoaXMudmlkZW9TcmNPYmplY3Q7XG5cbiAgICAgICAgdGhpcy52aWRlb0VsZW1lbnRzLnB1c2goe1xuICAgICAgICAgICAgdGh1bWI6IHRodW1ibmFpbElkLFxuICAgICAgICAgICAgdmlkZW86IHRoaXMudmlkZW9cbiAgICAgICAgfSk7XG5cbiAgICAgICAgaWYgKHRoaXMubG9jYWwgJiYgIXRoaXMuZGlzcGxheU15UmVtb3RlKCkpIHtcbiAgICAgICAgICAgIHRoaXMudmlkZW8ubXV0ZWQgPSB0cnVlO1xuICAgICAgICAgICAgdGhpcy52aWRlby5vbnBsYXlpbmcgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKFwiTG9jYWwgJ1N0cmVhbScgd2l0aCBpZCBbXCIgKyB0aGlzLmdldElkKCkgKyBcIl0gdmlkZW8gaXMgbm93IHBsYXlpbmdcIik7XG4gICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3ZpZGVvLWlzLXBsYXlpbmcnLCBbe1xuICAgICAgICAgICAgICAgICAgICBlbGVtZW50OiB0aGlzLnZpZGVvXG4gICAgICAgICAgICAgICAgfV0pO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMudmlkZW8udGl0bGUgPSB0aGlzLmdldElkKCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodHlwZW9mIHBhcmVudEVsZW1lbnQgPT09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgICAgIHRoaXMucGFyZW50SWQgPSBwYXJlbnRFbGVtZW50O1xuXG4gICAgICAgICAgICBsZXQgcGFyZW50RWxlbWVudERvbSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKHBhcmVudEVsZW1lbnQpO1xuICAgICAgICAgICAgaWYgKHBhcmVudEVsZW1lbnREb20pIHtcbiAgICAgICAgICAgICAgICB0aGlzLnZpZGVvID0gcGFyZW50RWxlbWVudERvbS5hcHBlbmRDaGlsZCh0aGlzLnZpZGVvKTtcbiAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgndmlkZW8tZWxlbWVudC1jcmVhdGVkLWJ5LXN0cmVhbScsIFt7XG4gICAgICAgICAgICAgICAgICAgIGVsZW1lbnQ6IHRoaXMudmlkZW9cbiAgICAgICAgICAgICAgICB9XSk7XG4gICAgICAgICAgICAgICAgdGhpcy5pc1ZpZGVvRUxlbWVudENyZWF0ZWQgPSB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5wYXJlbnRJZCA9IHBhcmVudEVsZW1lbnQuaWQ7XG4gICAgICAgICAgICB0aGlzLnZpZGVvID0gcGFyZW50RWxlbWVudC5hcHBlbmRDaGlsZCh0aGlzLnZpZGVvKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuaXNSZWFkeSA9IHRydWU7XG5cbiAgICAgICAgcmV0dXJuIHRoaXMudmlkZW87XG4gICAgfVxuXG4gICAgcGxheVRodW1ibmFpbCh0aHVtYm5haWxJZCkge1xuXG4gICAgICAgIGxldCBjb250YWluZXIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgICAgY29udGFpbmVyLmNsYXNzTmFtZSA9IFwicGFydGljaXBhbnRcIjtcbiAgICAgICAgY29udGFpbmVyLmlkID0gdGhpcy5nZXRJZCgpO1xuICAgICAgICBsZXQgdGh1bWJuYWlsID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQodGh1bWJuYWlsSWQpO1xuICAgICAgICBpZiAodGh1bWJuYWlsKSB7XG4gICAgICAgICAgICB0aHVtYm5haWwuYXBwZW5kQ2hpbGQoY29udGFpbmVyKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuZWxlbWVudHMucHVzaChjb250YWluZXIpO1xuXG4gICAgICAgIGxldCBuYW1lID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICAgIGNvbnRhaW5lci5hcHBlbmRDaGlsZChuYW1lKTtcbiAgICAgICAgbGV0IHVzZXJOYW1lID0gdGhpcy5nZXRJZCgpLnJlcGxhY2UoJ193ZWJjYW0nLCAnJyk7XG4gICAgICAgIGlmICh1c2VyTmFtZS5sZW5ndGggPj0gMTYpIHtcbiAgICAgICAgICAgIHVzZXJOYW1lID0gdXNlck5hbWUuc3Vic3RyaW5nKDAsIDE2KSArIFwiLi4uXCI7XG4gICAgICAgIH1cbiAgICAgICAgbmFtZS5hcHBlbmRDaGlsZChkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZSh1c2VyTmFtZSkpO1xuICAgICAgICBuYW1lLmlkID0gXCJuYW1lLVwiICsgdGhpcy5nZXRJZCgpO1xuICAgICAgICBuYW1lLmNsYXNzTmFtZSA9IFwibmFtZVwiO1xuICAgICAgICBuYW1lLnRpdGxlID0gdGhpcy5nZXRJZCgpO1xuXG4gICAgICAgIHRoaXMuc2hvd1NwaW5uZXIodGh1bWJuYWlsSWQpO1xuXG4gICAgICAgIHJldHVybiB0aGlzLnBsYXlPbmx5VmlkZW8oY29udGFpbmVyLCB0aHVtYm5haWxJZCk7XG4gICAgfVxuXG4gICAgZ2V0SWRJblBhcnRpY2lwYW50KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5pZDtcbiAgICB9XG5cbiAgICBnZXRQYXJ0aWNpcGFudCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY29ubmVjdGlvbjtcbiAgICB9XG5cbiAgICBnZXRJZCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY29ubmVjdGlvbi5jb25uZWN0aW9uSWQgKyBcIl9cIiArIHRoaXMuaWQ7XG4gICAgfVxuXG4gICAgZ2V0UlRDUGVlckNvbm5lY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFdlYlJ0Y1BlZXIoKS5wZWVyQ29ubmVjdGlvbjtcbiAgICB9XG5cbiAgICByZXF1ZXN0Q2FtZXJhQWNjZXNzKGNhbGxiYWNrOiBDYWxsYmFjazxTdHJlYW0+KSB7XG5cbiAgICAgICAgdGhpcy5jb25uZWN0aW9uLmFkZFN0cmVhbSh0aGlzKTtcblxuICAgICAgICBsZXQgY29uc3RyYWludHMgPSB0aGlzLm1lZGlhQ29uc3RyYWludHM7XG5cbiAgICAgICAgLypsZXQgY29uc3RyYWludHMyID0ge1xuICAgICAgICAgICAgYXVkaW86IHRydWUsXG4gICAgICAgICAgICB2aWRlbzoge1xuICAgICAgICAgICAgICAgIHdpZHRoOiB7XG4gICAgICAgICAgICAgICAgICAgIGlkZWFsOiAxMjgwXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBmcmFtZVJhdGU6IHtcbiAgICAgICAgICAgICAgICAgICAgaWRlYWw6IDE1XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9OyovXG5cbiAgICAgICAgdGhpcy51c2VyTWVkaWFIYXNWaWRlbygoaGFzVmlkZW8pID0+IHtcbiAgICAgICAgICAgIGlmICghaGFzVmlkZW8pIHtcbiAgICAgICAgICAgICAgICBjb25zdHJhaW50cy52aWRlbyA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIHRoaXMuc2VuZFZpZGVvID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgdGhpcy5yZXF1ZXN0Q2FtZXJhQWNjZXNBdXgoY29uc3RyYWludHMsIGNhbGxiYWNrKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5yZXF1ZXN0Q2FtZXJhQWNjZXNBdXgoY29uc3RyYWludHMsIGNhbGxiYWNrKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSByZXF1ZXN0Q2FtZXJhQWNjZXNBdXgoY29uc3RyYWludHMsIGNhbGxiYWNrKSB7XG4gICAgICAgIG5hdmlnYXRvci5tZWRpYURldmljZXMuZ2V0VXNlck1lZGlhKGNvbnN0cmFpbnRzKVxuICAgICAgICAgICAgLnRoZW4odXNlclN0cmVhbSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5jYW1lcmFBY2Nlc3NTdWNjZXNzKHVzZXJTdHJlYW0sIGNhbGxiYWNrKTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgIC8qLy8gIFRyeSB0byBhc2sgZm9yIG1pY3JvcGhvbmUgb25seVxuICAgICAgICAgICAgICAgIG5hdmlnYXRvci5tZWRpYURldmljZXMuZ2V0VXNlck1lZGlhKHsgYXVkaW86IHRydWUsIHZpZGVvOiBmYWxzZSB9KVxuICAgICAgICAgICAgICAgICAgICAudGhlbih1c2VyU3RyZWFtID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0cmFpbnRzLnZpZGVvID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNlbmRWaWRlbyA9IGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zZW5kQXVkaW8gPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jYW1lcmFBY2Nlc3NTdWNjZXNzKHVzZXJTdHJlYW0sIGNhbGxiYWNrKTtcbiAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgLmNhdGNoKGVycm9yID0+IHsqL1xuICAgICAgICAgICAgICAgIHRoaXMuYWNjZXNzSXNEZW5pZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgIHRoaXMuYWNjZXNzSXNBbGxvd2VkID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ2FjY2Vzcy1kZW5pZWQtYnktcHVibGlzaGVyJyk7XG5cbiAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKFwiQWNjZXNzIGRlbmllZFwiLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgY2FsbGJhY2soZXJyb3IsIHRoaXMpO1xuICAgICAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBjYW1lcmFBY2Nlc3NTdWNjZXNzKHVzZXJTdHJlYW0sIGNhbGxiYWNrKSB7XG4gICAgICAgIHRoaXMuYWNjZXNzSXNBbGxvd2VkID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5hY2Nlc3NJc0RlbmllZCA9IGZhbHNlO1xuICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgnYWNjZXNzLWFsbG93ZWQtYnktcHVibGlzaGVyJyk7XG5cbiAgICAgICAgaWYgKHVzZXJTdHJlYW0uZ2V0QXVkaW9UcmFja3MoKVswXSAhPSBudWxsKSB7XG4gICAgICAgICAgICB1c2VyU3RyZWFtLmdldEF1ZGlvVHJhY2tzKClbMF0uZW5hYmxlZCA9IHRoaXMuYWN0aXZlQXVkaW87XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHVzZXJTdHJlYW0uZ2V0VmlkZW9UcmFja3MoKVswXSAhPSBudWxsKSB7XG4gICAgICAgICAgICB1c2VyU3RyZWFtLmdldFZpZGVvVHJhY2tzKClbMF0uZW5hYmxlZCA9IHRoaXMuYWN0aXZlVmlkZW87XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLndyU3RyZWFtID0gdXNlclN0cmVhbTtcbiAgICAgICAgdGhpcy5lbWl0U3JjRXZlbnQodGhpcy53clN0cmVhbSk7XG5cbiAgICAgICAgY2FsbGJhY2sodW5kZWZpbmVkLCB0aGlzKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHVzZXJNZWRpYUhhc1ZpZGVvKGNhbGxiYWNrKSB7XG4gICAgICAgIG5hdmlnYXRvci5tZWRpYURldmljZXMuZW51bWVyYXRlRGV2aWNlcygpLnRoZW4oZnVuY3Rpb24gKG1lZGlhRGV2aWNlcykge1xuICAgICAgICAgICAgdmFyIHZpZGVvSW5wdXQgPSBtZWRpYURldmljZXMuZmlsdGVyKGZ1bmN0aW9uIChkZXZpY2VJbmZvKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGRldmljZUluZm8ua2luZCA9PT0gJ3ZpZGVvaW5wdXQnO1xuICAgICAgICAgICAgfSlbMF07XG4gICAgICAgICAgICBjYWxsYmFjayh2aWRlb0lucHV0ICE9IG51bGwpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwdWJsaXNoVmlkZW9DYWxsYmFjayhlcnJvciwgc2RwT2ZmZXJQYXJhbSwgd3ApIHtcblxuICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgIHJldHVybiBjb25zb2xlLmVycm9yKFwiKHB1Ymxpc2gpIFNEUCBvZmZlciBlcnJvcjogXCJcbiAgICAgICAgICAgICAgICArIEpTT04uc3RyaW5naWZ5KGVycm9yKSk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zb2xlLmRlYnVnKFwiU2VuZGluZyBTRFAgb2ZmZXIgdG8gcHVibGlzaCBhcyBcIlxuICAgICAgICAgICAgKyB0aGlzLmdldElkKCksIHNkcE9mZmVyUGFyYW0pO1xuXG4gICAgICAgIHRoaXMub3BlblZpZHUuc2VuZFJlcXVlc3QoXCJwdWJsaXNoVmlkZW9cIiwge1xuICAgICAgICAgICAgc2RwT2ZmZXI6IHNkcE9mZmVyUGFyYW0sXG4gICAgICAgICAgICBkb0xvb3BiYWNrOiB0aGlzLmRpc3BsYXlNeVJlbW90ZSgpIHx8IGZhbHNlLFxuICAgICAgICAgICAgYXVkaW9BY3RpdmU6IHRoaXMuc2VuZEF1ZGlvLFxuICAgICAgICAgICAgdmlkZW9BY3RpdmU6IHRoaXMuc2VuZFZpZGVvXG4gICAgICAgIH0sIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoXCJFcnJvciBvbiBwdWJsaXNoVmlkZW86IFwiICsgSlNPTi5zdHJpbmdpZnkoZXJyb3IpKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5wcm9jZXNzU2RwQW5zd2VyKHJlc3BvbnNlLnNkcEFuc3dlcik7XG4gICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKFwiJ1B1Ymxpc2hlcicgc3VjY2VzZnVsbHkgcHVibGlzaGVkIHRvIHNlc3Npb25cIik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHN0YXJ0VmlkZW9DYWxsYmFjayhlcnJvciwgc2RwT2ZmZXJQYXJhbSwgd3ApIHtcbiAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICByZXR1cm4gY29uc29sZS5lcnJvcihcIihzdWJzY3JpYmUpIFNEUCBvZmZlciBlcnJvcjogXCJcbiAgICAgICAgICAgICAgICArIEpTT04uc3RyaW5naWZ5KGVycm9yKSk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc29sZS5kZWJ1ZyhcIlNlbmRpbmcgU0RQIG9mZmVyIHRvIHN1YnNjcmliZSB0byBcIlxuICAgICAgICAgICAgKyB0aGlzLmdldElkKCksIHNkcE9mZmVyUGFyYW0pO1xuICAgICAgICB0aGlzLm9wZW5WaWR1LnNlbmRSZXF1ZXN0KFwicmVjZWl2ZVZpZGVvRnJvbVwiLCB7XG4gICAgICAgICAgICBzZW5kZXI6IHRoaXMuZ2V0SWQoKSxcbiAgICAgICAgICAgIHNkcE9mZmVyOiBzZHBPZmZlclBhcmFtXG4gICAgICAgIH0sIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoXCJFcnJvciBvbiByZWN2VmlkZW9Gcm9tOiBcIiArIEpTT04uc3RyaW5naWZ5KGVycm9yKSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMucHJvY2Vzc1NkcEFuc3dlcihyZXNwb25zZS5zZHBBbnN3ZXIpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGluaXRXZWJSdGNQZWVyKHNkcE9mZmVyQ2FsbGJhY2spIHtcbiAgICAgICAgaWYgKHRoaXMubG9jYWwpIHtcblxuICAgICAgICAgICAgbGV0IHVzZXJNZWRpYUNvbnN0cmFpbnRzID0ge1xuICAgICAgICAgICAgICAgIGF1ZGlvOiB0aGlzLnNlbmRBdWRpbyxcbiAgICAgICAgICAgICAgICB2aWRlbzogdGhpcy5zZW5kVmlkZW9cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgbGV0IG9wdGlvbnM6IGFueSA9IHtcbiAgICAgICAgICAgICAgICB2aWRlb1N0cmVhbTogdGhpcy53clN0cmVhbSxcbiAgICAgICAgICAgICAgICBtZWRpYUNvbnN0cmFpbnRzOiB1c2VyTWVkaWFDb25zdHJhaW50cyxcbiAgICAgICAgICAgICAgICBvbmljZWNhbmRpZGF0ZTogdGhpcy5jb25uZWN0aW9uLnNlbmRJY2VDYW5kaWRhdGUuYmluZCh0aGlzLmNvbm5lY3Rpb24pLFxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAodGhpcy5kYXRhQ2hhbm5lbCkge1xuICAgICAgICAgICAgICAgIG9wdGlvbnMuZGF0YUNoYW5uZWxDb25maWcgPSB7XG4gICAgICAgICAgICAgICAgICAgIGlkOiB0aGlzLmdldENoYW5uZWxOYW1lKCksXG4gICAgICAgICAgICAgICAgICAgIG9ub3BlbjogdGhpcy5vbkRhdGFDaGFubmVsT3BlbixcbiAgICAgICAgICAgICAgICAgICAgb25jbG9zZTogdGhpcy5vbkRhdGFDaGFubmVsQ2xvc2VkXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICBvcHRpb25zLmRhdGFDaGFubmVscyA9IHRydWU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmICh0aGlzLmRpc3BsYXlNeVJlbW90ZSgpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy53cCA9IGt1cmVudG9VdGlscy5XZWJSdGNQZWVyLldlYlJ0Y1BlZXJTZW5kcmVjdihvcHRpb25zLCBlcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHRoaXMud3AuZ2VuZXJhdGVPZmZlcihzZHBPZmZlckNhbGxiYWNrLmJpbmQodGhpcykpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLndwID0ga3VyZW50b1V0aWxzLldlYlJ0Y1BlZXIuV2ViUnRjUGVlclNlbmRvbmx5KG9wdGlvbnMsIGVycm9yID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgdGhpcy53cC5nZW5lcmF0ZU9mZmVyKHNkcE9mZmVyQ2FsbGJhY2suYmluZCh0aGlzKSk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBsZXQgb2ZmZXJDb25zdHJhaW50cyA9IHtcbiAgICAgICAgICAgICAgICBhdWRpbzogdGhpcy5yZWN2QXVkaW8sXG4gICAgICAgICAgICAgICAgdmlkZW86IHRoaXMucmVjdlZpZGVvXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgY29uc29sZS5kZWJ1ZyhcIidTZXNzaW9uLnN1YnNjcmliZShTdHJlYW0pJyBjYWxsZWQuIENvbnN0cmFpbnRzIG9mIGdlbmVyYXRlIFNEUCBvZmZlclwiLFxuICAgICAgICAgICAgICAgIG9mZmVyQ29uc3RyYWludHMpO1xuICAgICAgICAgICAgbGV0IG9wdGlvbnMgPSB7XG4gICAgICAgICAgICAgICAgb25pY2VjYW5kaWRhdGU6IHRoaXMuY29ubmVjdGlvbi5zZW5kSWNlQ2FuZGlkYXRlLmJpbmQodGhpcy5jb25uZWN0aW9uKSxcbiAgICAgICAgICAgICAgICBtZWRpYUNvbnN0cmFpbnRzOiBvZmZlckNvbnN0cmFpbnRzXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLndwID0ga3VyZW50b1V0aWxzLldlYlJ0Y1BlZXIuV2ViUnRjUGVlclJlY3Zvbmx5KG9wdGlvbnMsIGVycm9yID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aGlzLndwLmdlbmVyYXRlT2ZmZXIoc2RwT2ZmZXJDYWxsYmFjay5iaW5kKHRoaXMpKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGNvbnNvbGUuZGVidWcoXCJXYWl0aW5nIGZvciBTRFAgb2ZmZXIgdG8gYmUgZ2VuZXJhdGVkIChcIlxuICAgICAgICAgICAgKyAodGhpcy5sb2NhbCA/IFwibG9jYWxcIiA6IFwicmVtb3RlXCIpICsgXCIgJ1N0cmVhbSc6IFwiICsgdGhpcy5nZXRJZCgpICsgXCIpXCIpO1xuICAgIH1cblxuICAgIHB1Ymxpc2goKSB7XG5cbiAgICAgICAgLy8gRklYTUU6IFRocm93IGVycm9yIHdoZW4gc3RyZWFtIGlzIG5vdCBsb2NhbFxuICAgICAgICBpZiAodGhpcy5pc1JlYWR5KSB7XG4gICAgICAgICAgICB0aGlzLmluaXRXZWJSdGNQZWVyKHRoaXMucHVibGlzaFZpZGVvQ2FsbGJhY2spO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5lZS5vbmNlKCdzdHJlYW0tcmVhZHknLCBzdHJlYW1FdmVudCA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5wdWJsaXNoKCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEZJWE1FOiBOb3cgd2UgaGF2ZSBjb3VwbGVkIGNvbm5lY3RpbmcgdG8gYSByb29tIGFuZCBhZGRpbmcgYVxuICAgICAgICAvLyBzdHJlYW0gdG8gdGhpcyByb29tLiBCdXQgaW4gdGhlIG5ldyBBUEksIHRoZXJlIGFyZSB0d28gc3RlcHMuXG4gICAgICAgIC8vIFRoaXMgaXMgdGhlIHNlY29uZCBzdGVwLiBGb3Igbm93LCBpdCBkbyBub3RoaW5nLlxuXG4gICAgfVxuXG4gICAgc3Vic2NyaWJlKCkge1xuXG4gICAgICAgIC8vIEZJWE1FOiBJbiB0aGUgY3VycmVudCBpbXBsZW1lbnRhdGlvbiBhbGwgcGFydGljaXBhbnRzIGFyZSBzdWJzY3JpYmVkXG4gICAgICAgIC8vIGF1dG9tYXRpY2FsbHkgdG8gYWxsIG90aGVyIHBhcnRpY2lwYW50cy4gV2UgdXNlIHRoaXMgbWV0aG9kIG9ubHkgdG9cbiAgICAgICAgLy8gbmVnb3RpYXRlIFNEUFxuXG4gICAgICAgIHRoaXMuaW5pdFdlYlJ0Y1BlZXIodGhpcy5zdGFydFZpZGVvQ2FsbGJhY2spO1xuICAgIH1cblxuICAgIHByb2Nlc3NTZHBBbnN3ZXIoc2RwQW5zd2VyKSB7XG5cbiAgICAgICAgbGV0IGFuc3dlciA9IG5ldyBSVENTZXNzaW9uRGVzY3JpcHRpb24oe1xuICAgICAgICAgICAgdHlwZTogJ2Fuc3dlcicsXG4gICAgICAgICAgICBzZHA6IHNkcEFuc3dlcixcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnNvbGUuZGVidWcodGhpcy5nZXRJZCgpICsgXCI6IHNldCBwZWVyIGNvbm5lY3Rpb24gd2l0aCByZWN2ZCBTRFAgYW5zd2VyXCIsXG4gICAgICAgICAgICBzZHBBbnN3ZXIpO1xuICAgICAgICBsZXQgcGFydGljaXBhbnRJZCA9IHRoaXMuZ2V0SWQoKTtcbiAgICAgICAgbGV0IHBjID0gdGhpcy53cC5wZWVyQ29ubmVjdGlvbjtcbiAgICAgICAgcGMuc2V0UmVtb3RlRGVzY3JpcHRpb24oYW5zd2VyLCAoKSA9PiB7XG4gICAgICAgICAgICAvLyBBdm9pZHMgdG8gc3Vic2NyaWJlIHRvIHlvdXIgb3duIHN0cmVhbSByZW1vdGVseSBcbiAgICAgICAgICAgIC8vIGV4Y2VwdCB3aGVuIHNob3dNeVJlbW90ZSBpcyB0cnVlXG4gICAgICAgICAgICBpZiAoIXRoaXMubG9jYWwgfHwgdGhpcy5kaXNwbGF5TXlSZW1vdGUoKSkge1xuICAgICAgICAgICAgICAgIHRoaXMud3JTdHJlYW0gPSBwYy5nZXRSZW1vdGVTdHJlYW1zKClbMF07XG4gICAgICAgICAgICAgICAgY29uc29sZS5kZWJ1ZyhcIlBlZXIgcmVtb3RlIHN0cmVhbVwiLCB0aGlzLndyU3RyZWFtKTtcblxuICAgICAgICAgICAgICAgIGlmICh0aGlzLndyU3RyZWFtICE9IHVuZGVmaW5lZCkge1xuXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZW1pdFNyY0V2ZW50KHRoaXMud3JTdHJlYW0pO1xuXG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLndyU3RyZWFtLmdldEF1ZGlvVHJhY2tzKClbMF0gIT0gbnVsbCkge1xuXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNwZWVjaEV2ZW50ID0ga3VyZW50b1V0aWxzLldlYlJ0Y1BlZXIuaGFyayh0aGlzLndyU3RyZWFtLCB7IHRocmVzaG9sZDogdGhpcy5yb29tLnRocmVzaG9sZFNwZWFrZXIgfSk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQub24oJ3NwZWFraW5nJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucm9vbS5hZGRQYXJ0aWNpcGFudFNwZWFraW5nKHBhcnRpY2lwYW50SWQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucm9vbS5lbWl0RXZlbnQoJ3N0cmVhbS1zcGVha2luZycsIFt7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcnRpY2lwYW50SWQ6IHBhcnRpY2lwYW50SWRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zcGVlY2hFdmVudC5vbignc3RvcHBlZF9zcGVha2luZycsICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnJvb20ucmVtb3ZlUGFydGljaXBhbnRTcGVha2luZyhwYXJ0aWNpcGFudElkKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnJvb20uZW1pdEV2ZW50KCdzdHJlYW0tc3RvcHBlZC1zcGVha2luZycsIFt7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcnRpY2lwYW50SWQ6IHBhcnRpY2lwYW50SWRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGZvciAobGV0IHZpZGVvRWxlbWVudCBvZiB0aGlzLnZpZGVvRWxlbWVudHMpIHtcbiAgICAgICAgICAgICAgICAgICAgbGV0IHRodW1ibmFpbElkID0gdmlkZW9FbGVtZW50LnRodW1iO1xuICAgICAgICAgICAgICAgICAgICBsZXQgdmlkZW8gPSB2aWRlb0VsZW1lbnQudmlkZW87XG4gICAgICAgICAgICAgICAgICAgIHZpZGVvLnNyY09iamVjdCA9IHRoaXMud3JTdHJlYW07XG4gICAgICAgICAgICAgICAgICAgIHZpZGVvLm9ucGxheWluZyA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLmxvY2FsICYmIHRoaXMuZGlzcGxheU15UmVtb3RlKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJZb3VyIG93biByZW1vdGUgJ1N0cmVhbScgd2l0aCBpZCBbXCIgKyB0aGlzLmdldElkKCkgKyBcIl0gdmlkZW8gaXMgbm93IHBsYXlpbmdcIik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3JlbW90ZS12aWRlby1pcy1wbGF5aW5nJywgW3tcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxlbWVudDogdGhpcy52aWRlb1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1dKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoIXRoaXMubG9jYWwgJiYgIXRoaXMuZGlzcGxheU15UmVtb3RlKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmluZm8oXCJSZW1vdGUgJ1N0cmVhbScgd2l0aCBpZCBbXCIgKyB0aGlzLmdldElkKCkgKyBcIl0gdmlkZW8gaXMgbm93IHBsYXlpbmdcIik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3ZpZGVvLWlzLXBsYXlpbmcnLCBbe1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbGVtZW50OiB0aGlzLnZpZGVvXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfV0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgLy9zaG93KHRodW1ibmFpbElkKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vdGhpcy5oaWRlU3Bpbm5lcih0aGlzLmdldElkKCkpO1xuICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aGlzLnJvb20uZW1pdEV2ZW50KCdzdHJlYW0tc3Vic2NyaWJlZCcsIFt7XG4gICAgICAgICAgICAgICAgICAgIHN0cmVhbTogdGhpc1xuICAgICAgICAgICAgICAgIH1dKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSwgZXJyb3IgPT4ge1xuICAgICAgICAgICAgY29uc29sZS5lcnJvcih0aGlzLmdldElkKCkgKyBcIjogRXJyb3Igc2V0dGluZyBTRFAgdG8gdGhlIHBlZXIgY29ubmVjdGlvbjogXCJcbiAgICAgICAgICAgICAgICArIEpTT04uc3RyaW5naWZ5KGVycm9yKSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHVucHVibGlzaCgpIHtcbiAgICAgICAgaWYgKHRoaXMud3ApIHtcbiAgICAgICAgICAgIHRoaXMud3AuZGlzcG9zZSgpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaWYgKHRoaXMud3JTdHJlYW0pIHtcbiAgICAgICAgICAgICAgICB0aGlzLndyU3RyZWFtLmdldEF1ZGlvVHJhY2tzKCkuZm9yRWFjaChmdW5jdGlvbiAodHJhY2spIHtcbiAgICAgICAgICAgICAgICAgICAgdHJhY2suc3RvcCAmJiB0cmFjay5zdG9wKClcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIHRoaXMud3JTdHJlYW0uZ2V0VmlkZW9UcmFja3MoKS5mb3JFYWNoKGZ1bmN0aW9uICh0cmFjaykge1xuICAgICAgICAgICAgICAgICAgICB0cmFjay5zdG9wICYmIHRyYWNrLnN0b3AoKVxuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5zcGVlY2hFdmVudCkge1xuICAgICAgICAgICAgdGhpcy5zcGVlY2hFdmVudC5zdG9wKCk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zb2xlLmluZm8odGhpcy5nZXRJZCgpICsgXCI6IFN0cmVhbSAnXCIgKyB0aGlzLmlkICsgXCInIHVucHVibGlzaGVkXCIpO1xuICAgIH1cblxuICAgIGRpc3Bvc2UoKSB7XG5cbiAgICAgICAgZnVuY3Rpb24gZGlzcG9zZUVsZW1lbnQoZWxlbWVudCkge1xuICAgICAgICAgICAgaWYgKGVsZW1lbnQgJiYgZWxlbWVudC5wYXJlbnROb2RlKSB7XG4gICAgICAgICAgICAgICAgZWxlbWVudC5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKGVsZW1lbnQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5lbGVtZW50cy5mb3JFYWNoKGUgPT4gZGlzcG9zZUVsZW1lbnQoZSkpO1xuXG4gICAgICAgIC8vdGhpcy52aWRlb0VsZW1lbnRzLmZvckVhY2godmUgPT4gZGlzcG9zZUVsZW1lbnQodmUudmlkZW8pKTtcblxuICAgICAgICBkaXNwb3NlRWxlbWVudChcInByb2dyZXNzLVwiICsgdGhpcy5nZXRJZCgpKTtcblxuICAgICAgICBpZiAodGhpcy53cCkge1xuICAgICAgICAgICAgdGhpcy53cC5kaXNwb3NlKCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpZiAodGhpcy53clN0cmVhbSkge1xuICAgICAgICAgICAgICAgIHRoaXMud3JTdHJlYW0uZ2V0QXVkaW9UcmFja3MoKS5mb3JFYWNoKGZ1bmN0aW9uICh0cmFjaykge1xuICAgICAgICAgICAgICAgICAgICB0cmFjay5zdG9wICYmIHRyYWNrLnN0b3AoKVxuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgdGhpcy53clN0cmVhbS5nZXRWaWRlb1RyYWNrcygpLmZvckVhY2goZnVuY3Rpb24gKHRyYWNrKSB7XG4gICAgICAgICAgICAgICAgICAgIHRyYWNrLnN0b3AgJiYgdHJhY2suc3RvcCgpXG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLnNwZWVjaEV2ZW50KSB7XG4gICAgICAgICAgICB0aGlzLnNwZWVjaEV2ZW50LnN0b3AoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnNvbGUuaW5mbygodGhpcy5sb2NhbCA/IFwiTG9jYWwgXCIgOiBcIlJlbW90ZSBcIikgKyBcIidTdHJlYW0nIHdpdGggaWQgW1wiICsgdGhpcy5nZXRJZCgpICsgXCJdJyBoYXMgYmVlbiBzdWNjZXNmdWxseSBkaXNwb3NlZFwiKTtcbiAgICB9XG59XG4iXX0= diff --git a/openvidu-browser/static/js/openvidu-browser-1.1.1-dev.min.js b/openvidu-browser/static/js/openvidu-browser-1.1.1-dev.min.js index 55ee209d..d40e58eb 100644 --- a/openvidu-browser/static/js/openvidu-browser-1.1.1-dev.min.js +++ b/openvidu-browser/static/js/openvidu-browser-1.1.1-dev.min.js @@ -1 +1 @@ -(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o0&&this._events[type].length>m){this._events[type].warned=true;console.error("(node) warning: possible EventEmitter memory "+"leak detected. %d listeners added. "+"Use emitter.setMaxListeners() to increase limit.",this._events[type].length);if(typeof console.trace==="function"){console.trace()}}}return this};EventEmitter.prototype.on=EventEmitter.prototype.addListener;EventEmitter.prototype.once=function(type,listener){if(!isFunction(listener))throw TypeError("listener must be a function");var fired=false;function g(){this.removeListener(type,g);if(!fired){fired=true;listener.apply(this,arguments)}}g.listener=listener;this.on(type,g);return this};EventEmitter.prototype.removeListener=function(type,listener){var list,position,length,i;if(!isFunction(listener))throw TypeError("listener must be a function");if(!this._events||!this._events[type])return this;list=this._events[type];length=list.length;position=-1;if(list===listener||isFunction(list.listener)&&list.listener===listener){delete this._events[type];if(this._events.removeListener)this.emit("removeListener",type,listener)}else if(isObject(list)){for(i=length;i-- >0;){if(list[i]===listener||list[i].listener&&list[i].listener===listener){position=i;break}}if(position<0)return this;if(list.length===1){list.length=0;delete this._events[type]}else{list.splice(position,1)}if(this._events.removeListener)this.emit("removeListener",type,listener)}return this};EventEmitter.prototype.removeAllListeners=function(type){var key,listeners;if(!this._events)return this;if(!this._events.removeListener){if(arguments.length===0)this._events={};else if(this._events[type])delete this._events[type];return this}if(arguments.length===0){for(key in this._events){if(key==="removeListener")continue;this.removeAllListeners(key)}this.removeAllListeners("removeListener");this._events={};return this}listeners=this._events[type];if(isFunction(listeners)){this.removeListener(type,listeners)}else if(listeners){while(listeners.length)this.removeListener(type,listeners[listeners.length-1])}delete this._events[type];return this};EventEmitter.prototype.listeners=function(type){var ret;if(!this._events||!this._events[type])ret=[];else if(isFunction(this._events[type]))ret=[this._events[type]];else ret=this._events[type].slice();return ret};EventEmitter.prototype.listenerCount=function(type){if(this._events){var evlistener=this._events[type];if(isFunction(evlistener))return 1;else if(evlistener)return evlistener.length}return 0};EventEmitter.listenerCount=function(emitter,type){return emitter.listenerCount(type)};function isFunction(arg){return typeof arg==="function"}function isNumber(arg){return typeof arg==="number"}function isObject(arg){return typeof arg==="object"&&arg!==null}function isUndefined(arg){return arg===void 0}},{}],2:[function(require,module,exports){"use strict";var normalice=require("normalice");var freeice=module.exports=function(opts){var servers={stun:(opts||{}).stun||require("./stun.json"),turn:(opts||{}).turn||require("./turn.json")};var stunCount=(opts||{}).stunCount||2;var turnCount=(opts||{}).turnCount||0;var selected;function getServers(type,count){var out=[];var input=[].concat(servers[type]);var idx;while(input.length&&out.lengthmaxVolume&&fftBins[i]<0){maxVolume=fftBins[i]}}return maxVolume}var audioContextType=window.AudioContext||window.webkitAudioContext;var audioContext=null;module.exports=function(stream,options){var harker=new WildEmitter;if(!audioContextType)return harker;var options=options||{},smoothing=options.smoothing||.1,interval=options.interval||50,threshold=options.threshold,play=options.play,history=options.history||10,running=true;if(!audioContext){audioContext=new audioContextType}var sourceNode,fftBins,analyser;analyser=audioContext.createAnalyser();analyser.fftSize=512;analyser.smoothingTimeConstant=smoothing;fftBins=new Float32Array(analyser.fftSize);if(stream.jquery)stream=stream[0];if(stream instanceof HTMLAudioElement||stream instanceof HTMLVideoElement){sourceNode=audioContext.createMediaElementSource(stream);if(typeof play==="undefined")play=true;threshold=threshold||-50}else{sourceNode=audioContext.createMediaStreamSource(stream);threshold=threshold||-50}sourceNode.connect(analyser);if(play)analyser.connect(audioContext.destination);harker.speaking=false;harker.setThreshold=function(t){threshold=t};harker.setInterval=function(i){interval=i};harker.stop=function(){running=false;harker.emit("volume_change",-100,threshold);if(harker.speaking){harker.speaking=false;harker.emit("stopped_speaking")}};harker.speakingHistory=[];for(var i=0;ithreshold&&!harker.speaking){for(var i=harker.speakingHistory.length-3;i=2){harker.speaking=true;harker.emit("speaking")}}else if(currentVolumethreshold));looper()},interval)};looper();return harker}},{wildemitter:33}],6:[function(require,module,exports){if(typeof Object.create==="function"){module.exports=function inherits(ctor,superCtor){ctor.super_=superCtor;ctor.prototype=Object.create(superCtor.prototype,{constructor:{value:ctor,enumerable:false,writable:true,configurable:true}})}}else{module.exports=function inherits(ctor,superCtor){ctor.super_=superCtor;var TempCtor=function(){};TempCtor.prototype=superCtor.prototype;ctor.prototype=new TempCtor;ctor.prototype.constructor=ctor}}},{}],7:[function(require,module,exports){(function(isNode){var Public=function(clone){return merge(clone===true,false,arguments)},publicName="merge";Public.recursive=function(clone){return merge(clone===true,true,arguments)};Public.clone=function(input){var output=input,type=typeOf(input),index,size;if(type==="array"){output=[];size=input.length;for(index=0;index1){url=parts[1];parts=parts[0].split(":");output.username=parts[0];output.credential=(input||{}).credential||parts[1]||""}output.url=protocol+url;output.urls=[output.url];return output}},{}],9:[function(require,module,exports){"use strict";var SDPUtils=require("sdp");function writeMediaSection(transceiver,caps,type,stream,dtlsRole){var sdp=SDPUtils.writeRtpDescription(transceiver.kind,caps);sdp+=SDPUtils.writeIceParameters(transceiver.iceGatherer.getLocalParameters());sdp+=SDPUtils.writeDtlsParameters(transceiver.dtlsTransport.getLocalParameters(),type==="offer"?"actpass":dtlsRole||"active");sdp+="a=mid:"+transceiver.mid+"\r\n";if(transceiver.direction){sdp+="a="+transceiver.direction+"\r\n"}else if(transceiver.rtpSender&&transceiver.rtpReceiver){sdp+="a=sendrecv\r\n"}else if(transceiver.rtpSender){sdp+="a=sendonly\r\n"}else if(transceiver.rtpReceiver){sdp+="a=recvonly\r\n"}else{sdp+="a=inactive\r\n"}if(transceiver.rtpSender){var msid="msid:"+stream.id+" "+transceiver.rtpSender.track.id+"\r\n";sdp+="a="+msid;sdp+="a=ssrc:"+transceiver.sendEncodingParameters[0].ssrc+" "+msid;if(transceiver.sendEncodingParameters[0].rtx){sdp+="a=ssrc:"+transceiver.sendEncodingParameters[0].rtx.ssrc+" "+msid;sdp+="a=ssrc-group:FID "+transceiver.sendEncodingParameters[0].ssrc+" "+transceiver.sendEncodingParameters[0].rtx.ssrc+"\r\n"}}sdp+="a=ssrc:"+transceiver.sendEncodingParameters[0].ssrc+" cname:"+SDPUtils.localCName+"\r\n";if(transceiver.rtpSender&&transceiver.sendEncodingParameters[0].rtx){sdp+="a=ssrc:"+transceiver.sendEncodingParameters[0].rtx.ssrc+" cname:"+SDPUtils.localCName+"\r\n"}return sdp}function filterIceServers(iceServers,edgeVersion){var hasTurn=false;iceServers=JSON.parse(JSON.stringify(iceServers));return iceServers.filter(function(server){if(server&&(server.urls||server.url)){var urls=server.urls||server.url;if(server.url&&!server.urls){console.warn("RTCIceServer.url is deprecated! Use urls instead.")}var isString=typeof urls==="string";if(isString){urls=[urls]}urls=urls.filter(function(url){var validTurn=url.indexOf("turn:")===0&&url.indexOf("transport=udp")!==-1&&url.indexOf("turn:[")===-1&&!hasTurn;if(validTurn){hasTurn=true;return true}return url.indexOf("stun:")===0&&edgeVersion>=14393&&url.indexOf("?transport=udp")===-1});delete server.url;server.urls=isString?urls[0]:urls;return!!urls.length}return false})}function getCommonCapabilities(localCapabilities,remoteCapabilities){var commonCapabilities={codecs:[],headerExtensions:[],fecMechanisms:[]};var findCodecByPayloadType=function(pt,codecs){pt=parseInt(pt,10);for(var i=0;i0;i--){this._iceGatherers=new window.RTCIceGatherer({iceServers:config.iceServers,gatherPolicy:config.iceTransportPolicy})}}else{config.iceCandidatePoolSize=0}this._config=config;this.transceivers=[];this._sdpSessionId=SDPUtils.generateSessionId();this._sdpSessionVersion=0;this._dtlsRole=undefined};RTCPeerConnection.prototype._emitGatheringStateChange=function(){var event=new Event("icegatheringstatechange");this.dispatchEvent(event);if(typeof this.onicegatheringstatechange==="function"){this.onicegatheringstatechange(event)}};RTCPeerConnection.prototype.getConfiguration=function(){return this._config};RTCPeerConnection.prototype.getLocalStreams=function(){return this.localStreams};RTCPeerConnection.prototype.getRemoteStreams=function(){return this.remoteStreams};RTCPeerConnection.prototype._createTransceiver=function(kind){var hasBundleTransport=this.transceivers.length>0;var transceiver={track:null,iceGatherer:null,iceTransport:null,dtlsTransport:null,localCapabilities:null,remoteCapabilities:null,rtpSender:null,rtpReceiver:null,kind:kind,mid:null,sendEncodingParameters:null,recvEncodingParameters:null,stream:null,wantReceive:true};if(this.usingBundle&&hasBundleTransport){transceiver.iceTransport=this.transceivers[0].iceTransport;transceiver.dtlsTransport=this.transceivers[0].dtlsTransport}else{var transports=this._createIceAndDtlsTransports();transceiver.iceTransport=transports.iceTransport;transceiver.dtlsTransport=transports.dtlsTransport}this.transceivers.push(transceiver);return transceiver};RTCPeerConnection.prototype.addTrack=function(track,stream){var transceiver;for(var i=0;i=15025){stream.getTracks().forEach(function(track){self.addTrack(track,stream)})}else{var clonedStream=stream.clone();stream.getTracks().forEach(function(track,idx){var clonedTrack=clonedStream.getTracks()[idx];track.addEventListener("enabled",function(event){clonedTrack.enabled=event.enabled})});clonedStream.getTracks().forEach(function(track){self.addTrack(track,clonedStream)})}};RTCPeerConnection.prototype.removeStream=function(stream){var idx=this.localStreams.indexOf(stream);if(idx>-1){this.localStreams.splice(idx,1);this._maybeFireNegotiationNeeded()}};RTCPeerConnection.prototype.getSenders=function(){return this.transceivers.filter(function(transceiver){return!!transceiver.rtpSender}).map(function(transceiver){return transceiver.rtpSender})};RTCPeerConnection.prototype.getReceivers=function(){return this.transceivers.filter(function(transceiver){return!!transceiver.rtpReceiver}).map(function(transceiver){return transceiver.rtpReceiver})};RTCPeerConnection.prototype._createIceGatherer=function(sdpMLineIndex,usingBundle){var self=this;if(usingBundle&&sdpMLineIndex>0){return this.transceivers[0].iceGatherer}else if(this._iceGatherers.length){return this._iceGatherers.shift()}var iceGatherer=new window.RTCIceGatherer({iceServers:this._config.iceServers,gatherPolicy:this._config.iceTransportPolicy});Object.defineProperty(iceGatherer,"state",{value:"new",writable:true});this.transceivers[sdpMLineIndex].candidates=[];this.transceivers[sdpMLineIndex].bufferCandidates=function(event){var end=!event.candidate||Object.keys(event.candidate).length===0;iceGatherer.state=end?"completed":"gathering";if(self.transceivers[sdpMLineIndex].candidates!==null){self.transceivers[sdpMLineIndex].candidates.push(event.candidate)}};iceGatherer.addEventListener("localcandidate",this.transceivers[sdpMLineIndex].bufferCandidates);return iceGatherer};RTCPeerConnection.prototype._gather=function(mid,sdpMLineIndex){var self=this;var iceGatherer=this.transceivers[sdpMLineIndex].iceGatherer;if(iceGatherer.onlocalcandidate){return}var candidates=this.transceivers[sdpMLineIndex].candidates;this.transceivers[sdpMLineIndex].candidates=null;iceGatherer.removeEventListener("localcandidate",this.transceivers[sdpMLineIndex].bufferCandidates);iceGatherer.onlocalcandidate=function(evt){if(self.usingBundle&&sdpMLineIndex>0){return}var event=new Event("icecandidate");event.candidate={sdpMid:mid,sdpMLineIndex:sdpMLineIndex};var cand=evt.candidate;var end=!cand||Object.keys(cand).length===0;if(end){if(iceGatherer.state==="new"||iceGatherer.state==="gathering"){iceGatherer.state="completed"}}else{if(iceGatherer.state==="new"){iceGatherer.state="gathering"}cand.component=1;event.candidate.candidate=SDPUtils.writeCandidate(cand)}var sections=SDPUtils.splitSections(self.localDescription.sdp);if(!end){sections[event.candidate.sdpMLineIndex+1]+="a="+event.candidate.candidate+"\r\n"}else{sections[event.candidate.sdpMLineIndex+1]+="a=end-of-candidates\r\n"}self.localDescription.sdp=sections.join("");var complete=self.transceivers.every(function(transceiver){return transceiver.iceGatherer&&transceiver.iceGatherer.state==="completed"});if(self.iceGatheringState!=="gathering"){self.iceGatheringState="gathering";self._emitGatheringStateChange()}if(!end){self.dispatchEvent(event);if(typeof self.onicecandidate==="function"){self.onicecandidate(event)}}if(complete){self.dispatchEvent(new Event("icecandidate"));if(typeof self.onicecandidate==="function"){self.onicecandidate(new Event("icecandidate"))}self.iceGatheringState="complete";self._emitGatheringStateChange()}};window.setTimeout(function(){candidates.forEach(function(candidate){var e=new Event("RTCIceGatherEvent");e.candidate=candidate;iceGatherer.onlocalcandidate(e)})},0)};RTCPeerConnection.prototype._createIceAndDtlsTransports=function(){var self=this;var iceTransport=new window.RTCIceTransport(null);iceTransport.onicestatechange=function(){self._updateConnectionState()};var dtlsTransport=new window.RTCDtlsTransport(iceTransport);dtlsTransport.ondtlsstatechange=function(){self._updateConnectionState()};dtlsTransport.onerror=function(){Object.defineProperty(dtlsTransport,"state",{value:"failed",writable:true});self._updateConnectionState()};return{iceTransport:iceTransport,dtlsTransport:dtlsTransport}};RTCPeerConnection.prototype._disposeIceAndDtlsTransports=function(sdpMLineIndex){var iceGatherer=this.transceivers[sdpMLineIndex].iceGatherer;if(iceGatherer){delete iceGatherer.onlocalcandidate;delete this.transceivers[sdpMLineIndex].iceGatherer}var iceTransport=this.transceivers[sdpMLineIndex].iceTransport;if(iceTransport){delete iceTransport.onicestatechange;delete this.transceivers[sdpMLineIndex].iceTransport}var dtlsTransport=this.transceivers[sdpMLineIndex].dtlsTransport;if(dtlsTransport){delete dtlsTransport.ondtlsstatechange;delete dtlsTransport.onerror;delete this.transceivers[sdpMLineIndex].dtlsTransport}};RTCPeerConnection.prototype._transceive=function(transceiver,send,recv){var params=getCommonCapabilities(transceiver.localCapabilities,transceiver.remoteCapabilities);if(send&&transceiver.rtpSender){params.encodings=transceiver.sendEncodingParameters;params.rtcp={cname:SDPUtils.localCName,compound:transceiver.rtcpParameters.compound};if(transceiver.recvEncodingParameters.length){params.rtcp.ssrc=transceiver.recvEncodingParameters[0].ssrc}transceiver.rtpSender.send(params)}if(recv&&transceiver.rtpReceiver&¶ms.codecs.length>0){if(transceiver.kind==="video"&&transceiver.recvEncodingParameters&&edgeVersion<15019){transceiver.recvEncodingParameters.forEach(function(p){delete p.rtx})}params.encodings=transceiver.recvEncodingParameters;params.rtcp={cname:transceiver.rtcpParameters.cname,compound:transceiver.rtcpParameters.compound};if(transceiver.sendEncodingParameters.length){params.rtcp.ssrc=transceiver.sendEncodingParameters[0].ssrc}transceiver.rtpReceiver.receive(params)}};RTCPeerConnection.prototype.setLocalDescription=function(description){var self=this;var args=arguments;if(!isActionAllowedInSignalingState("setLocalDescription",description.type,this.signalingState)){return new Promise(function(resolve,reject){var e=new Error("Can not set local "+description.type+" in state "+self.signalingState);e.name="InvalidStateError";if(args.length>2&&typeof args[2]==="function"){args[2].apply(null,[e])}reject(e)})}var sections;var sessionpart;if(description.type==="offer"){sections=SDPUtils.splitSections(description.sdp);sessionpart=sections.shift();sections.forEach(function(mediaSection,sdpMLineIndex){var caps=SDPUtils.parseRtpParameters(mediaSection);self.transceivers[sdpMLineIndex].localCapabilities=caps});this.transceivers.forEach(function(transceiver,sdpMLineIndex){self._gather(transceiver.mid,sdpMLineIndex)})}else if(description.type==="answer"){sections=SDPUtils.splitSections(self.remoteDescription.sdp);sessionpart=sections.shift();var isIceLite=SDPUtils.matchPrefix(sessionpart,"a=ice-lite").length>0;sections.forEach(function(mediaSection,sdpMLineIndex){var transceiver=self.transceivers[sdpMLineIndex];var iceGatherer=transceiver.iceGatherer;var iceTransport=transceiver.iceTransport;var dtlsTransport=transceiver.dtlsTransport;var localCapabilities=transceiver.localCapabilities;var remoteCapabilities=transceiver.remoteCapabilities;var rejected=SDPUtils.isRejected(mediaSection)&&!SDPUtils.matchPrefix(mediaSection,"a=bundle-only").length===1;if(!rejected&&!transceiver.isDatachannel){var remoteIceParameters=SDPUtils.getIceParameters(mediaSection,sessionpart);var remoteDtlsParameters=SDPUtils.getDtlsParameters(mediaSection,sessionpart);if(isIceLite){remoteDtlsParameters.role="server"}if(!self.usingBundle||sdpMLineIndex===0){self._gather(transceiver.mid,sdpMLineIndex);if(iceTransport.state==="new"){iceTransport.start(iceGatherer,remoteIceParameters,isIceLite?"controlling":"controlled")}if(dtlsTransport.state==="new"){dtlsTransport.start(remoteDtlsParameters)}}var params=getCommonCapabilities(localCapabilities,remoteCapabilities);self._transceive(transceiver,params.codecs.length>0,false)}})}this.localDescription={type:description.type,sdp:description.sdp};switch(description.type){case"offer":this._updateSignalingState("have-local-offer");break;case"answer":this._updateSignalingState("stable");break;default:throw new TypeError('unsupported type "'+description.type+'"')}var cb=arguments.length>1&&typeof arguments[1]==="function"&&arguments[1];return new Promise(function(resolve){if(cb){cb.apply(null)}resolve()})};RTCPeerConnection.prototype.setRemoteDescription=function(description){var self=this;var args=arguments;if(!isActionAllowedInSignalingState("setRemoteDescription",description.type,this.signalingState)){return new Promise(function(resolve,reject){var e=new Error("Can not set remote "+description.type+" in state "+self.signalingState);e.name="InvalidStateError";if(args.length>2&&typeof args[2]==="function"){args[2].apply(null,[e])}reject(e)})}var streams={};this.remoteStreams.forEach(function(stream){streams[stream.id]=stream});var receiverList=[];var sections=SDPUtils.splitSections(description.sdp);var sessionpart=sections.shift();var isIceLite=SDPUtils.matchPrefix(sessionpart,"a=ice-lite").length>0;var usingBundle=SDPUtils.matchPrefix(sessionpart,"a=group:BUNDLE ").length>0;this.usingBundle=usingBundle;var iceOptions=SDPUtils.matchPrefix(sessionpart,"a=ice-options:")[0];if(iceOptions){this.canTrickleIceCandidates=iceOptions.substr(14).split(" ").indexOf("trickle")>=0}else{this.canTrickleIceCandidates=false}sections.forEach(function(mediaSection,sdpMLineIndex){var lines=SDPUtils.splitLines(mediaSection);var kind=SDPUtils.getKind(mediaSection);var rejected=SDPUtils.isRejected(mediaSection)&&!SDPUtils.matchPrefix(mediaSection,"a=bundle-only").length===1;var protocol=lines[0].substr(2).split(" ")[2];var direction=SDPUtils.getDirection(mediaSection,sessionpart);var remoteMsid=SDPUtils.parseMsid(mediaSection);var mid=SDPUtils.getMid(mediaSection)||SDPUtils.generateIdentifier();if(kind==="application"&&protocol==="DTLS/SCTP"){self.transceivers[sdpMLineIndex]={mid:mid,isDatachannel:true};return}var transceiver;var iceGatherer;var iceTransport;var dtlsTransport;var rtpReceiver;var sendEncodingParameters;var recvEncodingParameters;var localCapabilities;var track;var remoteCapabilities=SDPUtils.parseRtpParameters(mediaSection);var remoteIceParameters;var remoteDtlsParameters;if(!rejected){remoteIceParameters=SDPUtils.getIceParameters(mediaSection,sessionpart);remoteDtlsParameters=SDPUtils.getDtlsParameters(mediaSection,sessionpart);remoteDtlsParameters.role="client"}recvEncodingParameters=SDPUtils.parseRtpEncodingParameters(mediaSection);var rtcpParameters=SDPUtils.parseRtcpParameters(mediaSection);var isComplete=SDPUtils.matchPrefix(mediaSection,"a=end-of-candidates",sessionpart).length>0;var cands=SDPUtils.matchPrefix(mediaSection,"a=candidate:").map(function(cand){return SDPUtils.parseCandidate(cand)}).filter(function(cand){return cand.component===1});if((description.type==="offer"||description.type==="answer")&&!rejected&&usingBundle&&sdpMLineIndex>0&&self.transceivers[sdpMLineIndex]){self._disposeIceAndDtlsTransports(sdpMLineIndex);self.transceivers[sdpMLineIndex].iceGatherer=self.transceivers[0].iceGatherer;self.transceivers[sdpMLineIndex].iceTransport=self.transceivers[0].iceTransport;self.transceivers[sdpMLineIndex].dtlsTransport=self.transceivers[0].dtlsTransport;if(self.transceivers[sdpMLineIndex].rtpSender){self.transceivers[sdpMLineIndex].rtpSender.setTransport(self.transceivers[0].dtlsTransport)}if(self.transceivers[sdpMLineIndex].rtpReceiver){self.transceivers[sdpMLineIndex].rtpReceiver.setTransport(self.transceivers[0].dtlsTransport)}}if(description.type==="offer"&&!rejected){transceiver=self.transceivers[sdpMLineIndex]||self._createTransceiver(kind);transceiver.mid=mid;if(!transceiver.iceGatherer){transceiver.iceGatherer=self._createIceGatherer(sdpMLineIndex,usingBundle)}if(cands.length&&transceiver.iceTransport.state==="new"){if(isComplete&&(!usingBundle||sdpMLineIndex===0)){transceiver.iceTransport.setRemoteCandidates(cands)}else{cands.forEach(function(candidate){maybeAddCandidate(transceiver.iceTransport,candidate)})}}localCapabilities=window.RTCRtpReceiver.getCapabilities(kind);if(edgeVersion<15019){localCapabilities.codecs=localCapabilities.codecs.filter(function(codec){return codec.name!=="rtx"})}sendEncodingParameters=transceiver.sendEncodingParameters||[{ssrc:(2*sdpMLineIndex+2)*1001}];var isNewTrack=false;if(direction==="sendrecv"||direction==="sendonly"){isNewTrack=!transceiver.rtpReceiver;rtpReceiver=transceiver.rtpReceiver||new window.RTCRtpReceiver(transceiver.dtlsTransport,kind);if(isNewTrack){var stream;track=rtpReceiver.track;if(remoteMsid){if(!streams[remoteMsid.stream]){streams[remoteMsid.stream]=new window.MediaStream;Object.defineProperty(streams[remoteMsid.stream],"id",{get:function(){return remoteMsid.stream}})}Object.defineProperty(track,"id",{get:function(){return remoteMsid.track}});stream=streams[remoteMsid.stream]}else{if(!streams.default){streams.default=new window.MediaStream}stream=streams.default}stream.addTrack(track);receiverList.push([track,rtpReceiver,stream])}}transceiver.localCapabilities=localCapabilities;transceiver.remoteCapabilities=remoteCapabilities;transceiver.rtpReceiver=rtpReceiver;transceiver.rtcpParameters=rtcpParameters;transceiver.sendEncodingParameters=sendEncodingParameters;transceiver.recvEncodingParameters=recvEncodingParameters;self._transceive(self.transceivers[sdpMLineIndex],false,isNewTrack)}else if(description.type==="answer"&&!rejected){transceiver=self.transceivers[sdpMLineIndex];iceGatherer=transceiver.iceGatherer;iceTransport=transceiver.iceTransport;dtlsTransport=transceiver.dtlsTransport;rtpReceiver=transceiver.rtpReceiver;sendEncodingParameters=transceiver.sendEncodingParameters;localCapabilities=transceiver.localCapabilities;self.transceivers[sdpMLineIndex].recvEncodingParameters=recvEncodingParameters;self.transceivers[sdpMLineIndex].remoteCapabilities=remoteCapabilities;self.transceivers[sdpMLineIndex].rtcpParameters=rtcpParameters;if(cands.length&&iceTransport.state==="new"){if((isIceLite||isComplete)&&(!usingBundle||sdpMLineIndex===0)){iceTransport.setRemoteCandidates(cands)}else{cands.forEach(function(candidate){maybeAddCandidate(transceiver.iceTransport,candidate)})}}if(!usingBundle||sdpMLineIndex===0){if(iceTransport.state==="new"){iceTransport.start(iceGatherer,remoteIceParameters,"controlling")}if(dtlsTransport.state==="new"){dtlsTransport.start(remoteDtlsParameters)}}self._transceive(transceiver,direction==="sendrecv"||direction==="recvonly",direction==="sendrecv"||direction==="sendonly");if(rtpReceiver&&(direction==="sendrecv"||direction==="sendonly")){track=rtpReceiver.track;if(remoteMsid){if(!streams[remoteMsid.stream]){streams[remoteMsid.stream]=new window.MediaStream}streams[remoteMsid.stream].addTrack(track);receiverList.push([track,rtpReceiver,streams[remoteMsid.stream]])}else{if(!streams.default){streams.default=new window.MediaStream}streams.default.addTrack(track);receiverList.push([track,rtpReceiver,streams.default])}}else{delete transceiver.rtpReceiver}}});if(this._dtlsRole===undefined){this._dtlsRole=description.type==="offer"?"active":"passive"}this.remoteDescription={type:description.type,sdp:description.sdp};switch(description.type){case"offer":this._updateSignalingState("have-remote-offer");break;case"answer":this._updateSignalingState("stable");break;default:throw new TypeError('unsupported type "'+description.type+'"')}Object.keys(streams).forEach(function(sid){var stream=streams[sid];if(stream.getTracks().length){if(self.remoteStreams.indexOf(stream)===-1){self.remoteStreams.push(stream);var event=new Event("addstream");event.stream=stream;window.setTimeout(function(){self.dispatchEvent(event);if(typeof self.onaddstream==="function"){self.onaddstream(event)}})}receiverList.forEach(function(item){var track=item[0];var receiver=item[1];if(stream.id!==item[2].id){return}var trackEvent=new Event("track");trackEvent.track=track;trackEvent.receiver=receiver;trackEvent.transceiver={receiver:receiver};trackEvent.streams=[stream];window.setTimeout(function(){self.dispatchEvent(trackEvent);if(typeof self.ontrack==="function"){self.ontrack(trackEvent)}})})}});window.setTimeout(function(){if(!(self&&self.transceivers)){return}self.transceivers.forEach(function(transceiver){if(transceiver.iceTransport&&transceiver.iceTransport.state==="new"&&transceiver.iceTransport.getRemoteCandidates().length>0){console.warn("Timeout for addRemoteCandidate. Consider sending "+"an end-of-candidates notification");transceiver.iceTransport.addRemoteCandidate({})}})},4e3);return new Promise(function(resolve){if(args.length>1&&typeof args[1]==="function"){args[1].apply(null)}resolve()})};RTCPeerConnection.prototype.close=function(){this.transceivers.forEach(function(transceiver){if(transceiver.iceTransport){transceiver.iceTransport.stop()}if(transceiver.dtlsTransport){transceiver.dtlsTransport.stop()}if(transceiver.rtpSender){transceiver.rtpSender.stop()}if(transceiver.rtpReceiver){transceiver.rtpReceiver.stop()}});this._updateSignalingState("closed")};RTCPeerConnection.prototype._updateSignalingState=function(newState){this.signalingState=newState;var event=new Event("signalingstatechange");this.dispatchEvent(event);if(typeof this.onsignalingstatechange==="function"){this.onsignalingstatechange(event)}};RTCPeerConnection.prototype._maybeFireNegotiationNeeded=function(){var self=this;if(this.signalingState!=="stable"||this.needNegotiation===true){return}this.needNegotiation=true;window.setTimeout(function(){if(self.needNegotiation===false){return}self.needNegotiation=false;var event=new Event("negotiationneeded");self.dispatchEvent(event);if(typeof self.onnegotiationneeded==="function"){self.onnegotiationneeded(event)}},0)};RTCPeerConnection.prototype._updateConnectionState=function(){var newState;var states={new:0,closed:0,connecting:0,checking:0,connected:0,completed:0,disconnected:0,failed:0};this.transceivers.forEach(function(transceiver){states[transceiver.iceTransport.state]++;states[transceiver.dtlsTransport.state]++});states.connected+=states.completed;newState="new";if(states.failed>0){newState="failed"}else if(states.connecting>0||states.checking>0){newState="connecting"}else if(states.disconnected>0){newState="disconnected"}else if(states.new>0){newState="new"}else if(states.connected>0||states.completed>0){newState="connected"}if(newState!==this.iceConnectionState){this.iceConnectionState=newState;var event=new Event("iceconnectionstatechange");this.dispatchEvent(event);if(typeof this.oniceconnectionstatechange==="function"){this.oniceconnectionstatechange(event)}}};RTCPeerConnection.prototype.createOffer=function(){var self=this;var args=arguments;var offerOptions;if(arguments.length===1&&typeof arguments[0]!=="function"){offerOptions=arguments[0]}else if(arguments.length===3){offerOptions=arguments[2]}var numAudioTracks=this.transceivers.filter(function(t){return t.kind==="audio"}).length;var numVideoTracks=this.transceivers.filter(function(t){return t.kind==="video"}).length;if(offerOptions){if(offerOptions.mandatory||offerOptions.optional){throw new TypeError("Legacy mandatory/optional constraints not supported.")}if(offerOptions.offerToReceiveAudio!==undefined){if(offerOptions.offerToReceiveAudio===true){numAudioTracks=1}else if(offerOptions.offerToReceiveAudio===false){numAudioTracks=0}else{numAudioTracks=offerOptions.offerToReceiveAudio}}if(offerOptions.offerToReceiveVideo!==undefined){if(offerOptions.offerToReceiveVideo===true){numVideoTracks=1}else if(offerOptions.offerToReceiveVideo===false){numVideoTracks=0}else{numVideoTracks=offerOptions.offerToReceiveVideo}}}this.transceivers.forEach(function(transceiver){if(transceiver.kind==="audio"){numAudioTracks--;if(numAudioTracks<0){transceiver.wantReceive=false}}else if(transceiver.kind==="video"){numVideoTracks--;if(numVideoTracks<0){transceiver.wantReceive=false}}});while(numAudioTracks>0||numVideoTracks>0){if(numAudioTracks>0){this._createTransceiver("audio");numAudioTracks--}if(numVideoTracks>0){this._createTransceiver("video");numVideoTracks--}}var sdp=SDPUtils.writeSessionBoilerplate(this._sdpSessionId,this._sdpSessionVersion++);this.transceivers.forEach(function(transceiver,sdpMLineIndex){var track=transceiver.track;var kind=transceiver.kind;var mid=SDPUtils.generateIdentifier();transceiver.mid=mid;if(!transceiver.iceGatherer){transceiver.iceGatherer=self._createIceGatherer(sdpMLineIndex,self.usingBundle)}var localCapabilities=window.RTCRtpSender.getCapabilities(kind);if(edgeVersion<15019){localCapabilities.codecs=localCapabilities.codecs.filter(function(codec){return codec.name!=="rtx"})}localCapabilities.codecs.forEach(function(codec){if(codec.name==="H264"&&codec.parameters["level-asymmetry-allowed"]===undefined){codec.parameters["level-asymmetry-allowed"]="1"}});var sendEncodingParameters=transceiver.sendEncodingParameters||[{ssrc:(2*sdpMLineIndex+1)*1001}];if(track){if(edgeVersion>=15019&&kind==="video"&&!sendEncodingParameters[0].rtx){sendEncodingParameters[0].rtx={ssrc:sendEncodingParameters[0].ssrc+1}}}if(transceiver.wantReceive){transceiver.rtpReceiver=new window.RTCRtpReceiver(transceiver.dtlsTransport,kind)}transceiver.localCapabilities=localCapabilities;transceiver.sendEncodingParameters=sendEncodingParameters});if(this._config.bundlePolicy!=="max-compat"){sdp+="a=group:BUNDLE "+this.transceivers.map(function(t){return t.mid}).join(" ")+"\r\n"}sdp+="a=ice-options:trickle\r\n";this.transceivers.forEach(function(transceiver,sdpMLineIndex){sdp+=writeMediaSection(transceiver,transceiver.localCapabilities,"offer",transceiver.stream,self._dtlsRole);sdp+="a=rtcp-rsize\r\n";if(transceiver.iceGatherer&&self.iceGatheringState!=="new"&&(sdpMLineIndex===0||!self.usingBundle)){transceiver.iceGatherer.getLocalCandidates().forEach(function(cand){cand.component=1;sdp+="a="+SDPUtils.writeCandidate(cand)+"\r\n"});if(transceiver.iceGatherer.state==="completed"){sdp+="a=end-of-candidates\r\n"}}});var desc=new window.RTCSessionDescription({type:"offer",sdp:sdp});return new Promise(function(resolve){if(args.length>0&&typeof args[0]==="function"){args[0].apply(null,[desc]);resolve();return}resolve(desc)})};RTCPeerConnection.prototype.createAnswer=function(){var self=this;var args=arguments;var sdp=SDPUtils.writeSessionBoilerplate(this._sdpSessionId,this._sdpSessionVersion++);if(this.usingBundle){sdp+="a=group:BUNDLE "+this.transceivers.map(function(t){return t.mid}).join(" ")+"\r\n"}var mediaSectionsInOffer=SDPUtils.splitSections(this.remoteDescription.sdp).length-1;this.transceivers.forEach(function(transceiver,sdpMLineIndex){if(sdpMLineIndex+1>mediaSectionsInOffer){return}if(transceiver.isDatachannel){sdp+="m=application 0 DTLS/SCTP 5000\r\n"+"c=IN IP4 0.0.0.0\r\n"+"a=mid:"+transceiver.mid+"\r\n";return}if(transceiver.stream){var localTrack;if(transceiver.kind==="audio"){localTrack=transceiver.stream.getAudioTracks()[0]}else if(transceiver.kind==="video"){localTrack=transceiver.stream.getVideoTracks()[0]}if(localTrack){if(edgeVersion>=15019&&transceiver.kind==="video"&&!transceiver.sendEncodingParameters[0].rtx){transceiver.sendEncodingParameters[0].rtx={ssrc:transceiver.sendEncodingParameters[0].ssrc+1}}}}var commonCapabilities=getCommonCapabilities(transceiver.localCapabilities,transceiver.remoteCapabilities);var hasRtx=commonCapabilities.codecs.filter(function(c){return c.name.toLowerCase()==="rtx"}).length;if(!hasRtx&&transceiver.sendEncodingParameters[0].rtx){delete transceiver.sendEncodingParameters[0].rtx}sdp+=writeMediaSection(transceiver,commonCapabilities,"answer",transceiver.stream,self._dtlsRole);if(transceiver.rtcpParameters&&transceiver.rtcpParameters.reducedSize){sdp+="a=rtcp-rsize\r\n"}});var desc=new window.RTCSessionDescription({type:"answer",sdp:sdp});return new Promise(function(resolve){if(args.length>0&&typeof args[0]==="function"){args[0].apply(null,[desc]);resolve();return}resolve(desc)})};RTCPeerConnection.prototype.addIceCandidate=function(candidate){var err;var sections;if(!candidate||candidate.candidate===""){for(var j=0;j0?SDPUtils.parseCandidate(candidate.candidate):{};if(cand.protocol==="tcp"&&(cand.port===0||cand.port===9)){return Promise.resolve()}if(cand.component&&cand.component!==1){return Promise.resolve()}if(sdpMLineIndex===0||sdpMLineIndex>0&&transceiver.iceTransport!==this.transceivers[0].iceTransport){if(!maybeAddCandidate(transceiver.iceTransport,cand)){err=new Error("Can not add ICE candidate");err.name="OperationError"}}if(!err){var candidateString=candidate.candidate.trim();if(candidateString.indexOf("a=")===0){candidateString=candidateString.substr(2)}sections=SDPUtils.splitSections(this.remoteDescription.sdp);sections[sdpMLineIndex+1]+="a="+(cand.type?candidateString:"end-of-candidates")+"\r\n";this.remoteDescription.sdp=sections.join("")}}else{err=new Error("Can not add ICE candidate");err.name="OperationError"}}var args=arguments;return new Promise(function(resolve,reject){if(err){if(args.length>2&&typeof args[2]==="function"){args[2].apply(null,[err])}reject(err)}else{if(args.length>1&&typeof args[1]==="function"){args[1].apply(null)}resolve()}})};RTCPeerConnection.prototype.getStats=function(){var promises=[];this.transceivers.forEach(function(transceiver){["rtpSender","rtpReceiver","iceGatherer","iceTransport","dtlsTransport"].forEach(function(method){if(transceiver[method]){promises.push(transceiver[method].getStats())}})});var cb=arguments.length>1&&typeof arguments[1]==="function"&&arguments[1];var fixStatsType=function(stat){return{inboundrtp:"inbound-rtp",outboundrtp:"outbound-rtp",candidatepair:"candidate-pair",localcandidate:"local-candidate",remotecandidate:"remote-candidate"}[stat.type]||stat.type};return new Promise(function(resolve){var results=new Map;Promise.all(promises).then(function(res){res.forEach(function(result){Object.keys(result).forEach(function(id){result[id].type=fixStatsType(result[id]);results.set(id,result[id])})});if(cb){cb.apply(null,results)}resolve(results)})})};return RTCPeerConnection}},{sdp:18}],10:[function(require,module,exports){var grammar=module.exports={v:[{name:"version",reg:/^(\d*)$/}],o:[{name:"origin",reg:/^(\S*) (\d*) (\d*) (\S*) IP(\d) (\S*)/,names:["username","sessionId","sessionVersion","netType","ipVer","address"],format:"%s %s %d %s IP%d %s"}],s:[{name:"name"}],i:[{name:"description"}],u:[{name:"uri"}],e:[{name:"email"}],p:[{name:"phone"}],z:[{name:"timezones"}],r:[{name:"repeats"}],t:[{name:"timing",reg:/^(\d*) (\d*)/,names:["start","stop"],format:"%d %d"}],c:[{name:"connection",reg:/^IN IP(\d) (\S*)/,names:["version","ip"],format:"IN IP%d %s"}],b:[{push:"bandwidth",reg:/^(TIAS|AS|CT|RR|RS):(\d*)/,names:["type","limit"],format:"%s:%s"}],m:[{reg:/^(\w*) (\d*) ([\w\/]*)(?: (.*))?/,names:["type","port","protocol","payloads"],format:"%s %d %s %s"}],a:[{push:"rtp",reg:/^rtpmap:(\d*) ([\w\-]*)(?:\s*\/(\d*)(?:\s*\/(\S*))?)?/,names:["payload","codec","rate","encoding"],format:function(o){return o.encoding?"rtpmap:%d %s/%s/%s":o.rate?"rtpmap:%d %s/%s":"rtpmap:%d %s"}},{push:"fmtp",reg:/^fmtp:(\d*) ([\S| ]*)/,names:["payload","config"],format:"fmtp:%d %s"},{name:"control",reg:/^control:(.*)/,format:"control:%s"},{name:"rtcp",reg:/^rtcp:(\d*)(?: (\S*) IP(\d) (\S*))?/,names:["port","netType","ipVer","address"],format:function(o){return o.address!=null?"rtcp:%d %s IP%d %s":"rtcp:%d"}},{push:"rtcpFbTrrInt",reg:/^rtcp-fb:(\*|\d*) trr-int (\d*)/,names:["payload","value"],format:"rtcp-fb:%d trr-int %d"},{push:"rtcpFb",reg:/^rtcp-fb:(\*|\d*) ([\w-_]*)(?: ([\w-_]*))?/,names:["payload","type","subtype"],format:function(o){return o.subtype!=null?"rtcp-fb:%s %s %s":"rtcp-fb:%s %s"}},{push:"ext",reg:/^extmap:([\w_\/]*) (\S*)(?: (\S*))?/,names:["value","uri","config"],format:function(o){return o.config!=null?"extmap:%s %s %s":"extmap:%s %s"}},{push:"crypto",reg:/^crypto:(\d*) ([\w_]*) (\S*)(?: (\S*))?/,names:["id","suite","config","sessionConfig"],format:function(o){return o.sessionConfig!=null?"crypto:%d %s %s %s":"crypto:%d %s %s"}},{name:"setup",reg:/^setup:(\w*)/,format:"setup:%s"},{name:"mid",reg:/^mid:([^\s]*)/,format:"mid:%s"},{name:"msid",reg:/^msid:(.*)/,format:"msid:%s"},{name:"ptime",reg:/^ptime:(\d*)/,format:"ptime:%d"},{name:"maxptime",reg:/^maxptime:(\d*)/,format:"maxptime:%d"},{name:"direction",reg:/^(sendrecv|recvonly|sendonly|inactive)/},{name:"icelite",reg:/^(ice-lite)/},{name:"iceUfrag",reg:/^ice-ufrag:(\S*)/,format:"ice-ufrag:%s"},{name:"icePwd",reg:/^ice-pwd:(\S*)/,format:"ice-pwd:%s"},{name:"fingerprint",reg:/^fingerprint:(\S*) (\S*)/,names:["type","hash"],format:"fingerprint:%s %s"},{push:"candidates",reg:/^candidate:(\S*) (\d*) (\S*) (\d*) (\S*) (\d*) typ (\S*)(?: raddr (\S*) rport (\d*))?(?: tcptype (\S*))?(?: generation (\d*))?/,names:["foundation","component","transport","priority","ip","port","type","raddr","rport","tcptype","generation"],format:function(o){var str="candidate:%s %d %s %d %s %d typ %s";str+=o.raddr!=null?" raddr %s rport %d":"%v%v";str+=o.tcptype!=null?" tcptype %s":"%v";if(o.generation!=null){str+=" generation %d"}return str}},{name:"endOfCandidates",reg:/^(end-of-candidates)/},{name:"remoteCandidates",reg:/^remote-candidates:(.*)/,format:"remote-candidates:%s"},{name:"iceOptions",reg:/^ice-options:(\S*)/,format:"ice-options:%s"},{push:"ssrcs",reg:/^ssrc:(\d*) ([\w_]*):(.*)/,names:["id","attribute","value"],format:"ssrc:%d %s:%s"},{push:"ssrcGroups",reg:/^ssrc-group:(\w*) (.*)/,names:["semantics","ssrcs"],format:"ssrc-group:%s %s"},{name:"msidSemantic",reg:/^msid-semantic:\s?(\w*) (\S*)/,names:["semantic","token"],format:"msid-semantic: %s %s"},{push:"groups",reg:/^group:(\w*) (.*)/,names:["type","mids"],format:"group:%s %s"},{name:"rtcpMux",reg:/^(rtcp-mux)/},{name:"rtcpRsize",reg:/^(rtcp-rsize)/},{push:"invalid",names:["value"]}]};Object.keys(grammar).forEach(function(key){var objs=grammar[key];objs.forEach(function(obj){if(!obj.reg){obj.reg=/(.*)/}if(!obj.format){obj.format="%s"}})})},{}],11:[function(require,module,exports){var parser=require("./parser");var writer=require("./writer");exports.write=writer;exports.parse=parser.parse;exports.parseFmtpConfig=parser.parseFmtpConfig;exports.parsePayloads=parser.parsePayloads;exports.parseRemoteCandidates=parser.parseRemoteCandidates},{"./parser":12,"./writer":13}],12:[function(require,module,exports){var toIntIfInt=function(v){return String(Number(v))===v?Number(v):v};var attachProperties=function(match,location,names,rawName){if(rawName&&!names){location[rawName]=toIntIfInt(match[1])}else{for(var i=0;i=len){return x}var arg=args[i];i+=1;switch(x){case"%%":return"%";case"%s":return String(arg);case"%d":return Number(arg);case"%v":return""}})};var makeLine=function(type,obj,location){var str=obj.format instanceof Function?obj.format(obj.push?location:location[obj.name]):obj.format;var args=[type+"="+str];if(obj.names){for(var i=0;i3||!session.media.every(function(m){return["video","audio","data"].indexOf(m.mid)!==-1})){console.warn("This description does not look like Plan B.");return desc}var mids=[];session.media.forEach(function(m){mids.push(m.mid)});var hasBundle=false;if(typeof session.groups!=="undefined"&&Array.isArray(session.groups)){hasBundle=session.groups.every(function(g){return g.type!=="BUNDLE"||arrayEquals.apply(g.mids.sort(),[mids.sort()])})}if(!hasBundle){var mustBeBundle=false;session.media.forEach(function(m){if(m.direction!=="inactive"){mustBeBundle=true}});if(mustBeBundle){throw new Error("Cannot convert to Unified Plan because m-lines that"+" are not bundled were found.")}}var type;if(desc.type==="answer"){type="offer"}else if(desc.type==="offer"){type="answer"}else{throw new Error("Type '"+desc.type+"' not supported.")}var cached;if(typeof this.cache[type]!=="undefined"){cached=transform.parse(this.cache[type])}var recvonlySsrcs={audio:{},video:{}};var mid2ul={};var bIdx=0;var uIdx=0;var sources2ul={};var candidates;var iceUfrag;var icePwd;var fingerprint;var payloads={};var rtcpFb={};var rtp={};session.media.forEach(function(bLine){if((typeof bLine.rtcpMux!=="string"||bLine.rtcpMux!=="rtcp-mux")&&bLine.direction!=="inactive"){throw new Error("Cannot convert to Unified Plan because m-lines "+"without the rtcp-mux attribute were found.")}if(bLine.type==="application"){mid2ul[bLine.mid]=bLine;return}var sources=bLine.sources;var ssrcGroups=bLine.ssrcGroups;var port=bLine.port;if(typeof bLine.candidates!="undefined"){if(typeof candidates!="undefined"){candidates=candidates.concat(bLine.candidates)}else{candidates=bLine.candidates}}if(typeof iceUfrag!="undefined"&&typeof bLine.iceUfrag!="undefined"&&iceUfrag!=bLine.iceUfrag){throw new Error("Only BUNDLE supported, iceUfrag must be the same for all m-lines.\n"+"\tLast iceUfrag: "+iceUfrag+"\n"+"\tNew iceUfrag: "+bLine.iceUfrag)}if(typeof bLine.iceUfrag!="undefined"){iceUfrag=bLine.iceUfrag}if(typeof icePwd!="undefined"&&typeof bLine.icePwd!="undefined"&&icePwd!=bLine.icePwd){throw new Error("Only BUNDLE supported, icePwd must be the same for all m-lines.\n"+"\tLast icePwd: "+icePwd+"\n"+"\tNew icePwd: "+bLine.icePwd)}if(typeof bLine.icePwd!="undefined"){icePwd=bLine.icePwd}if(typeof fingerprint!="undefined"&&typeof bLine.fingerprint!="undefined"&&(fingerprint.type!=bLine.fingerprint.type||fingerprint.hash!=bLine.fingerprint.hash)){throw new Error("Only BUNDLE supported, fingerprint must be the same for all m-lines.\n"+"\tLast fingerprint: "+JSON.stringify(fingerprint)+"\n"+"\tNew fingerprint: "+JSON.stringify(bLine.fingerprint))}if(typeof bLine.fingerprint!="undefined"){fingerprint=bLine.fingerprint}payloads[bLine.type]=bLine.payloads;rtcpFb[bLine.type]=bLine.rtcpFb;rtp[bLine.type]=bLine.rtp;var ssrc2group={};if(typeof ssrcGroups!=="undefined"&&Array.isArray(ssrcGroups)){ssrcGroups.forEach(function(ssrcGroup){if(typeof ssrcGroup.ssrcs!=="undefined"&&Array.isArray(ssrcGroup.ssrcs)){ssrcGroup.ssrcs.forEach(function(ssrc){if(typeof ssrc2group[ssrc]==="undefined"){ssrc2group[ssrc]=[]}ssrc2group[ssrc].push(ssrcGroup)})}})}var ssrc2ml={};if(typeof sources==="object"){delete bLine.sources;delete bLine.ssrcGroups;delete bLine.candidates;delete bLine.iceUfrag;delete bLine.icePwd;delete bLine.fingerprint;delete bLine.port;delete bLine.mid;Object.keys(sources).forEach(function(ssrc){var uLine;if(desc.type==="offer"){if(!sources[ssrc].msid){recvonlySsrcs[bLine.type][ssrc]=sources[ssrc];return}}if(typeof ssrc2group[ssrc]!=="undefined"&&Array.isArray(ssrc2group[ssrc])){ssrc2group[ssrc].some(function(ssrcGroup){return ssrcGroup.ssrcs.some(function(related){if(typeof ssrc2ml[related]==="object"){uLine=ssrc2ml[related];return true}})})}if(typeof uLine==="object"){uLine.sources[ssrc]=sources[ssrc];delete sources[ssrc].msid}else{uLine=Object.create(bLine);ssrc2ml[ssrc]=uLine;if(typeof sources[ssrc].msid!=="undefined"){uLine.msid=sources[ssrc].msid;delete sources[ssrc].msid}uLine.sources={};uLine.sources[ssrc]=sources[ssrc];uLine.ssrcGroups=ssrc2group[ssrc];if(typeof cached!=="undefined"&&typeof cached.media!=="undefined"&&Array.isArray(cached.media)){cached.media.forEach(function(m){if(typeof m.sources==="object"){Object.keys(m.sources).forEach(function(s){if(s===ssrc){uLine.mid=m.mid}})}})}if(typeof uLine.mid==="undefined"){uLine.mid=[bLine.type,"-",ssrc].join("")}uLine.candidates=candidates;uLine.iceUfrag=iceUfrag;uLine.icePwd=icePwd;uLine.fingerprint=fingerprint;uLine.port=port;mid2ul[uLine.mid]=uLine;sources2ul[uIdx]=uLine.sources;self.cache.mlU2BMap[uIdx]=bIdx;if(typeof self.cache.mlB2UMap[bIdx]==="undefined"){self.cache.mlB2UMap[bIdx]=uIdx}uIdx++}})}else{var uLine=bLine;uLine.candidates=candidates;uLine.iceUfrag=iceUfrag;uLine.icePwd=icePwd;uLine.fingerprint=fingerprint;uLine.port=port;mid2ul[uLine.mid]=uLine;self.cache.mlU2BMap[uIdx]=bIdx;if(typeof self.cache.mlB2UMap[bIdx]==="undefined"){self.cache.mlB2UMap[bIdx]=uIdx}}bIdx++});session.media=[];mids=[];if(desc.type==="answer"){for(var i=0;i0){idx=self.getFirstSendingIndexFromAnswer(type);if(idx===null){for(var i=0;iidx){var mLine=session.media[idx];Object.keys(recvonlySsrcs[type]).forEach(function(ssrc){if(mLine.sources&&mLine.sources[ssrc]){console.warn("Replacing an existing SSRC.")}if(!mLine.sources){mLine.sources={}}mLine.sources[ssrc]=recvonlySsrcs[type][ssrc]})}});if(typeof session.groups!=="undefined"){session.groups.some(function(group){if(group.type==="BUNDLE"){group.mids=mids.join(" ");return true}})}session.msidSemantic={semantic:"WMS",token:"*"};var resStr=transform.write(session);this.cache[desc.type]=resStr;return new RTCSessionDescription({type:desc.type,sdp:resStr})}},{"./array-equals":14,"./transform":17}],17:[function(require,module,exports){var transform=require("sdp-transform");exports.write=function(session,opts){if(typeof session!=="undefined"&&typeof session.media!=="undefined"&&Array.isArray(session.media)){session.media.forEach(function(mLine){if(typeof mLine.sources!=="undefined"&&Object.keys(mLine.sources).length!==0){mLine.ssrcs=[];Object.keys(mLine.sources).forEach(function(ssrc){var source=mLine.sources[ssrc];Object.keys(source).forEach(function(attribute){mLine.ssrcs.push({id:ssrc,attribute:attribute,value:source[attribute]})})});delete mLine.sources}if(typeof mLine.ssrcGroups!=="undefined"&&Array.isArray(mLine.ssrcGroups)){mLine.ssrcGroups.forEach(function(ssrcGroup){if(typeof ssrcGroup.ssrcs!=="undefined"&&Array.isArray(ssrcGroup.ssrcs)){ssrcGroup.ssrcs=ssrcGroup.ssrcs.join(" ")}})}})}if(typeof session!=="undefined"&&typeof session.groups!=="undefined"&&Array.isArray(session.groups)){session.groups.forEach(function(g){if(typeof g.mids!=="undefined"&&Array.isArray(g.mids)){g.mids=g.mids.join(" ")}})}return transform.write(session,opts)};exports.parse=function(sdp){var session=transform.parse(sdp);if(typeof session!=="undefined"&&typeof session.media!=="undefined"&&Array.isArray(session.media)){session.media.forEach(function(mLine){if(typeof mLine.ssrcs!=="undefined"&&Array.isArray(mLine.ssrcs)){mLine.sources={};mLine.ssrcs.forEach(function(ssrc){if(!mLine.sources[ssrc.id])mLine.sources[ssrc.id]={};mLine.sources[ssrc.id][ssrc.attribute]=ssrc.value});delete mLine.ssrcs}if(typeof mLine.ssrcGroups!=="undefined"&&Array.isArray(mLine.ssrcGroups)){mLine.ssrcGroups.forEach(function(ssrcGroup){if(typeof ssrcGroup.ssrcs==="string"){ssrcGroup.ssrcs=ssrcGroup.ssrcs.split(" ")}})}})}if(typeof session!=="undefined"&&typeof session.groups!=="undefined"&&Array.isArray(session.groups)){session.groups.forEach(function(g){if(typeof g.mids==="string"){g.mids=g.mids.split(" ")}})}return session}},{"sdp-transform":11}],18:[function(require,module,exports){"use strict";var SDPUtils={};SDPUtils.generateIdentifier=function(){return Math.random().toString(36).substr(2,10)};SDPUtils.localCName=SDPUtils.generateIdentifier();SDPUtils.splitLines=function(blob){return blob.trim().split("\n").map(function(line){return line.trim()})};SDPUtils.splitSections=function(blob){var parts=blob.split("\nm=");return parts.map(function(part,index){return(index>0?"m="+part:part).trim()+"\r\n"})};SDPUtils.matchPrefix=function(blob,prefix){return SDPUtils.splitLines(blob).filter(function(line){return line.indexOf(prefix)===0})};SDPUtils.parseCandidate=function(line){var parts;if(line.indexOf("a=candidate:")===0){parts=line.substring(12).split(" ")}else{parts=line.substring(10).split(" ")}var candidate={foundation:parts[0],component:parseInt(parts[1],10),protocol:parts[2].toLowerCase(),priority:parseInt(parts[3],10),ip:parts[4],port:parseInt(parts[5],10),type:parts[7]};for(var i=8;i0?parts[0].split("/")[1]:"sendrecv",uri:parts[1]}};SDPUtils.writeExtmap=function(headerExtension){return"a=extmap:"+(headerExtension.id||headerExtension.preferredId)+(headerExtension.direction&&headerExtension.direction!=="sendrecv"?"/"+headerExtension.direction:"")+" "+headerExtension.uri+"\r\n"};SDPUtils.parseFmtp=function(line){var parsed={};var kv;var parts=line.substr(line.indexOf(" ")+1).split(";");for(var j=0;j-1){parts.attribute=line.substr(sp+1,colon-sp-1);parts.value=line.substr(colon+1)}else{parts.attribute=line.substr(sp+1)}return parts};SDPUtils.getMid=function(mediaSection){var mid=SDPUtils.matchPrefix(mediaSection,"a=mid:")[0];if(mid){return mid.substr(6)}};SDPUtils.parseFingerprint=function(line){var parts=line.substr(14).split(" ");return{algorithm:parts[0].toLowerCase(),value:parts[1]}};SDPUtils.getDtlsParameters=function(mediaSection,sessionpart){var lines=SDPUtils.matchPrefix(mediaSection+sessionpart,"a=fingerprint:");return{role:"auto",fingerprints:lines.map(SDPUtils.parseFingerprint)}};SDPUtils.writeDtlsParameters=function(params,setupType){var sdp="a=setup:"+setupType+"\r\n";params.fingerprints.forEach(function(fp){sdp+="a=fingerprint:"+fp.algorithm+" "+fp.value+"\r\n"});return sdp};SDPUtils.getIceParameters=function(mediaSection,sessionpart){var lines=SDPUtils.splitLines(mediaSection);lines=lines.concat(SDPUtils.splitLines(sessionpart));var iceParameters={usernameFragment:lines.filter(function(line){return line.indexOf("a=ice-ufrag:")===0})[0].substr(12),password:lines.filter(function(line){return line.indexOf("a=ice-pwd:")===0})[0].substr(10)};return iceParameters};SDPUtils.writeIceParameters=function(params){return"a=ice-ufrag:"+params.usernameFragment+"\r\n"+"a=ice-pwd:"+params.password+"\r\n"};SDPUtils.parseRtpParameters=function(mediaSection){var description={codecs:[],headerExtensions:[],fecMechanisms:[],rtcp:[]};var lines=SDPUtils.splitLines(mediaSection);var mline=lines[0].split(" ");for(var i=3;i0?"9":"0";sdp+=" UDP/TLS/RTP/SAVPF ";sdp+=caps.codecs.map(function(codec){if(codec.preferredPayloadType!==undefined){return codec.preferredPayloadType}return codec.payloadType}).join(" ")+"\r\n";sdp+="c=IN IP4 0.0.0.0\r\n";sdp+="a=rtcp:9 IN IP4 0.0.0.0\r\n";caps.codecs.forEach(function(codec){sdp+=SDPUtils.writeRtpMap(codec);sdp+=SDPUtils.writeFmtp(codec);sdp+=SDPUtils.writeRtcpFb(codec)});var maxptime=0;caps.codecs.forEach(function(codec){if(codec.maxptime>maxptime){maxptime=codec.maxptime}});if(maxptime>0){sdp+="a=maxptime:"+maxptime+"\r\n"}sdp+="a=rtcp-mux\r\n";caps.headerExtensions.forEach(function(extension){sdp+=SDPUtils.writeExtmap(extension)});return sdp};SDPUtils.parseRtpEncodingParameters=function(mediaSection){var encodingParameters=[];var description=SDPUtils.parseRtpParameters(mediaSection);var hasRed=description.fecMechanisms.indexOf("RED")!==-1;var hasUlpfec=description.fecMechanisms.indexOf("ULPFEC")!==-1;var ssrcs=SDPUtils.matchPrefix(mediaSection,"a=ssrc:").map(function(line){return SDPUtils.parseSsrcMedia(line)}).filter(function(parts){return parts.attribute==="cname"});var primarySsrc=ssrcs.length>0&&ssrcs[0].ssrc;var secondarySsrc;var flows=SDPUtils.matchPrefix(mediaSection,"a=ssrc-group:FID").map(function(line){var parts=line.split(" ");parts.shift();return parts.map(function(part){return parseInt(part,10)})});if(flows.length>0&&flows[0].length>1&&flows[0][0]===primarySsrc){secondarySsrc=flows[0][1]}description.codecs.forEach(function(codec){if(codec.name.toUpperCase()==="RTX"&&codec.parameters.apt){var encParam={ssrc:primarySsrc,codecPayloadType:parseInt(codec.parameters.apt,10),rtx:{ssrc:secondarySsrc}};encodingParameters.push(encParam);if(hasRed){encParam=JSON.parse(JSON.stringify(encParam));encParam.fec={ssrc:secondarySsrc,mechanism:hasUlpfec?"red+ulpfec":"red"};encodingParameters.push(encParam)}}});if(encodingParameters.length===0&&primarySsrc){encodingParameters.push({ssrc:primarySsrc})}var bandwidth=SDPUtils.matchPrefix(mediaSection,"b=");if(bandwidth.length){if(bandwidth[0].indexOf("b=TIAS:")===0){bandwidth=parseInt(bandwidth[0].substr(7),10)}else if(bandwidth[0].indexOf("b=AS:")===0){bandwidth=parseInt(bandwidth[0].substr(5),10)*1e3*.95-50*40*8}else{bandwidth=undefined}encodingParameters.forEach(function(params){params.maxBitrate=bandwidth})}return encodingParameters};SDPUtils.parseRtcpParameters=function(mediaSection){var rtcpParameters={};var cname;var remoteSsrc=SDPUtils.matchPrefix(mediaSection,"a=ssrc:").map(function(line){return SDPUtils.parseSsrcMedia(line)}).filter(function(obj){return obj.attribute==="cname"})[0];if(remoteSsrc){rtcpParameters.cname=remoteSsrc.value;rtcpParameters.ssrc=remoteSsrc.ssrc}var rsize=SDPUtils.matchPrefix(mediaSection,"a=rtcp-rsize");rtcpParameters.reducedSize=rsize.length>0;rtcpParameters.compound=rsize.length===0;var mux=SDPUtils.matchPrefix(mediaSection,"a=rtcp-mux");rtcpParameters.mux=mux.length>0;return rtcpParameters};SDPUtils.parseMsid=function(mediaSection){var parts;var spec=SDPUtils.matchPrefix(mediaSection,"a=msid:");if(spec.length===1){parts=spec[0].substr(7).split(" ");return{stream:parts[0],track:parts[1]}}var planB=SDPUtils.matchPrefix(mediaSection,"a=ssrc:").map(function(line){return SDPUtils.parseSsrcMedia(line)}).filter(function(parts){return parts.attribute==="msid"});if(planB.length>0){parts=planB[0].value.split(" ");return{stream:parts[0],track:parts[1]}}};SDPUtils.generateSessionId=function(){return Math.random().toString().substr(2,21)};SDPUtils.writeSessionBoilerplate=function(sessId,sessVer){var sessionId;var version=sessVer!==undefined?sessVer:2;if(sessId){sessionId=sessId}else{sessionId=SDPUtils.generateSessionId()}return"v=0\r\n"+"o=thisisadapterortc "+sessionId+" "+version+" IN IP4 127.0.0.1\r\n"+"s=-\r\n"+"t=0 0\r\n"};SDPUtils.writeMediaSection=function(transceiver,caps,type,stream){var sdp=SDPUtils.writeRtpDescription(transceiver.kind,caps);sdp+=SDPUtils.writeIceParameters(transceiver.iceGatherer.getLocalParameters());sdp+=SDPUtils.writeDtlsParameters(transceiver.dtlsTransport.getLocalParameters(),type==="offer"?"actpass":"active");sdp+="a=mid:"+transceiver.mid+"\r\n";if(transceiver.direction){sdp+="a="+transceiver.direction+"\r\n"}else if(transceiver.rtpSender&&transceiver.rtpReceiver){sdp+="a=sendrecv\r\n"}else if(transceiver.rtpSender){sdp+="a=sendonly\r\n"}else if(transceiver.rtpReceiver){sdp+="a=recvonly\r\n"}else{sdp+="a=inactive\r\n"}if(transceiver.rtpSender){var msid="msid:"+stream.id+" "+transceiver.rtpSender.track.id+"\r\n";sdp+="a="+msid;sdp+="a=ssrc:"+transceiver.sendEncodingParameters[0].ssrc+" "+msid;if(transceiver.sendEncodingParameters[0].rtx){sdp+="a=ssrc:"+transceiver.sendEncodingParameters[0].rtx.ssrc+" "+msid;sdp+="a=ssrc-group:FID "+transceiver.sendEncodingParameters[0].ssrc+" "+transceiver.sendEncodingParameters[0].rtx.ssrc+"\r\n"}}sdp+="a=ssrc:"+transceiver.sendEncodingParameters[0].ssrc+" cname:"+SDPUtils.localCName+"\r\n";if(transceiver.rtpSender&&transceiver.sendEncodingParameters[0].rtx){sdp+="a=ssrc:"+transceiver.sendEncodingParameters[0].rtx.ssrc+" cname:"+SDPUtils.localCName+"\r\n"}return sdp};SDPUtils.getDirection=function(mediaSection,sessionpart){var lines=SDPUtils.splitLines(mediaSection);for(var i=0;i0){if(q.length==2){if(typeof q[1]==FUNC_TYPE){this[q[0]]=q[1].call(this,match)}else{this[q[0]]=q[1]}}else if(q.length==3){if(typeof q[1]===FUNC_TYPE&&!(q[1].exec&&q[1].test)){this[q[0]]=match?q[1].call(this,match,q[2]):undefined}else{this[q[0]]=match?match.replace(q[1],q[2]):undefined}}else if(q.length==4){this[q[0]]=match?q[3].call(this,match.replace(q[1],q[2])):undefined}}else{this[q]=match?match:undefined}}}}i+=2}},str:function(str,map){for(var i in map){if(typeof map[i]===OBJ_TYPE&&map[i].length>0){for(var j=0;j>>((i&3)<<3)&255}return _rnds}}module.exports=rng}).call(this,typeof global!=="undefined"?global:typeof self!=="undefined"?self:typeof window!=="undefined"?window:{})},{}],21:[function(require,module,exports){var _rng=require("./rng");var _byteToHex=[];var _hexToByte={};for(var i=0;i<256;i++){_byteToHex[i]=(i+256).toString(16).substr(1);_hexToByte[_byteToHex[i]]=i}function parse(s,buf,offset){var i=buf&&offset||0,ii=0;buf=buf||[];s.toLowerCase().replace(/[0-9a-f]{2}/g,function(oct){if(ii<16){buf[i+ii++]=_hexToByte[oct]}});while(ii<16){buf[i+ii++]=0}return buf}function unparse(buf,offset){var i=offset||0,bth=_byteToHex;return bth[buf[i++]]+bth[buf[i++]]+bth[buf[i++]]+bth[buf[i++]]+"-"+bth[buf[i++]]+bth[buf[i++]]+"-"+bth[buf[i++]]+bth[buf[i++]]+"-"+bth[buf[i++]]+bth[buf[i++]]+"-"+bth[buf[i++]]+bth[buf[i++]]+bth[buf[i++]]+bth[buf[i++]]+bth[buf[i++]]+bth[buf[i++]]}var _seedBytes=_rng();var _nodeId=[_seedBytes[0]|1,_seedBytes[1],_seedBytes[2],_seedBytes[3],_seedBytes[4],_seedBytes[5]];var _clockseq=(_seedBytes[6]<<8|_seedBytes[7])&16383;var _lastMSecs=0,_lastNSecs=0;function v1(options,buf,offset){var i=buf&&offset||0;var b=buf||[];options=options||{};var clockseq=options.clockseq!==undefined?options.clockseq:_clockseq;var msecs=options.msecs!==undefined?options.msecs:(new Date).getTime();var nsecs=options.nsecs!==undefined?options.nsecs:_lastNSecs+1;var dt=msecs-_lastMSecs+(nsecs-_lastNSecs)/1e4;if(dt<0&&options.clockseq===undefined){clockseq=clockseq+1&16383}if((dt<0||msecs>_lastMSecs)&&options.nsecs===undefined){nsecs=0}if(nsecs>=1e4){throw new Error("uuid.v1(): Can't create more than 10M uuids/sec")}_lastMSecs=msecs;_lastNSecs=nsecs;_clockseq=clockseq;msecs+=122192928e5;var tl=((msecs&268435455)*1e4+nsecs)%4294967296;b[i++]=tl>>>24&255;b[i++]=tl>>>16&255;b[i++]=tl>>>8&255;b[i++]=tl&255;var tmh=msecs/4294967296*1e4&268435455;b[i++]=tmh>>>8&255;b[i++]=tmh&255;b[i++]=tmh>>>24&15|16;b[i++]=tmh>>>16&255;b[i++]=clockseq>>>8|128;b[i++]=clockseq&255;var node=options.node||_nodeId;for(var n=0;n<6;n++){b[i+n]=node[n]}return buf?buf:unparse(b)}function v4(options,buf,offset){var i=buf&&offset||0;if(typeof options=="string"){buf=options=="binary"?new Array(16):null;options=null}options=options||{};var rnds=options.random||(options.rng||_rng)();rnds[6]=rnds[6]&15|64;rnds[8]=rnds[8]&63|128;if(buf){for(var ii=0;ii<16;ii++){buf[i+ii]=rnds[ii]}}return buf||unparse(rnds)}var uuid=v4;uuid.v1=v1;uuid.v4=v4;uuid.parse=parse;uuid.unparse=unparse;module.exports=uuid},{"./rng":20}],22:[function(require,module,exports){(function(global){"use strict";var adapterFactory=require("./adapter_factory.js");module.exports=adapterFactory({window:global.window})}).call(this,typeof global!=="undefined"?global:typeof self!=="undefined"?self:typeof window!=="undefined"?window:{})},{"./adapter_factory.js":23}],23:[function(require,module,exports){"use strict";var utils=require("./utils");module.exports=function(dependencies,opts){var window=dependencies&&dependencies.window;var options={shimChrome:true,shimFirefox:true,shimEdge:true,shimSafari:true};for(var key in opts){if(hasOwnProperty.call(opts,key)){options[key]=opts[key]}}var logging=utils.log;var browserDetails=utils.detectBrowser(window);var adapter={browserDetails:browserDetails,extractVersion:utils.extractVersion,disableLog:utils.disableLog,disableWarnings:utils.disableWarnings};var chromeShim=require("./chrome/chrome_shim")||null;var edgeShim=require("./edge/edge_shim")||null;var firefoxShim=require("./firefox/firefox_shim")||null;var safariShim=require("./safari/safari_shim")||null;var commonShim=require("./common_shim")||null;switch(browserDetails.browser){case"chrome":if(!chromeShim||!chromeShim.shimPeerConnection||!options.shimChrome){logging("Chrome shim is not included in this adapter release.");return adapter}logging("adapter.js shimming chrome.");adapter.browserShim=chromeShim;commonShim.shimCreateObjectURL(window);chromeShim.shimGetUserMedia(window);chromeShim.shimMediaStream(window);chromeShim.shimSourceObject(window);chromeShim.shimPeerConnection(window);chromeShim.shimOnTrack(window);chromeShim.shimAddTrackRemoveTrack(window);chromeShim.shimGetSendersWithDtmf(window);commonShim.shimRTCIceCandidate(window);break;case"firefox":if(!firefoxShim||!firefoxShim.shimPeerConnection||!options.shimFirefox){logging("Firefox shim is not included in this adapter release.");return adapter}logging("adapter.js shimming firefox.");adapter.browserShim=firefoxShim;commonShim.shimCreateObjectURL(window);firefoxShim.shimGetUserMedia(window);firefoxShim.shimSourceObject(window);firefoxShim.shimPeerConnection(window);firefoxShim.shimOnTrack(window);commonShim.shimRTCIceCandidate(window);break;case"edge":if(!edgeShim||!edgeShim.shimPeerConnection||!options.shimEdge){logging("MS edge shim is not included in this adapter release.");return adapter}logging("adapter.js shimming edge.");adapter.browserShim=edgeShim;commonShim.shimCreateObjectURL(window);edgeShim.shimGetUserMedia(window);edgeShim.shimPeerConnection(window);edgeShim.shimReplaceTrack(window);break;case"safari":if(!safariShim||!options.shimSafari){logging("Safari shim is not included in this adapter release.");return adapter}logging("adapter.js shimming safari.");adapter.browserShim=safariShim;commonShim.shimCreateObjectURL(window);safariShim.shimRTCIceServerUrls(window);safariShim.shimCallbacksAPI(window);safariShim.shimLocalStreamsAPI(window);safariShim.shimRemoteStreamsAPI(window);safariShim.shimTrackEventTransceiver(window);safariShim.shimGetUserMedia(window);commonShim.shimRTCIceCandidate(window);break;default:logging("Unsupported browser!");break}return adapter}},{"./chrome/chrome_shim":24,"./common_shim":26,"./edge/edge_shim":27,"./firefox/firefox_shim":29,"./safari/safari_shim":31,"./utils":32}],24:[function(require,module,exports){"use strict";var utils=require("../utils.js");var logging=utils.log;var chromeShim={shimMediaStream:function(window){window.MediaStream=window.MediaStream||window.webkitMediaStream},shimOnTrack:function(window){if(typeof window==="object"&&window.RTCPeerConnection&&!("ontrack"in window.RTCPeerConnection.prototype)){Object.defineProperty(window.RTCPeerConnection.prototype,"ontrack",{get:function(){return this._ontrack},set:function(f){if(this._ontrack){this.removeEventListener("track",this._ontrack)}this.addEventListener("track",this._ontrack=f)}});var origSetRemoteDescription=window.RTCPeerConnection.prototype.setRemoteDescription;window.RTCPeerConnection.prototype.setRemoteDescription=function(){var pc=this;if(!pc._ontrackpoly){pc._ontrackpoly=function(e){e.stream.addEventListener("addtrack",function(te){var receiver;if(window.RTCPeerConnection.prototype.getReceivers){receiver=pc.getReceivers().find(function(r){return r.track&&r.track.id===te.track.id})}else{receiver={track:te.track}}var event=new Event("track");event.track=te.track;event.receiver=receiver;event.transceiver={receiver:receiver};event.streams=[e.stream];pc.dispatchEvent(event)});e.stream.getTracks().forEach(function(track){var receiver;if(window.RTCPeerConnection.prototype.getReceivers){receiver=pc.getReceivers().find(function(r){return r.track&&r.track.id===track.id})}else{receiver={track:track}}var event=new Event("track");event.track=track;event.receiver=receiver;event.transceiver={receiver:receiver};event.streams=[e.stream];pc.dispatchEvent(event)})};pc.addEventListener("addstream",pc._ontrackpoly)}return origSetRemoteDescription.apply(pc,arguments)}}},shimGetSendersWithDtmf:function(window){if(typeof window==="object"&&window.RTCPeerConnection&&!("getSenders"in window.RTCPeerConnection.prototype)&&"createDTMFSender"in window.RTCPeerConnection.prototype){var shimSenderWithDtmf=function(pc,track){return{track:track,get dtmf(){if(this._dtmf===undefined){if(track.kind==="audio"){this._dtmf=pc.createDTMFSender(track)}else{this._dtmf=null}}return this._dtmf},_pc:pc}};if(!window.RTCPeerConnection.prototype.getSenders){window.RTCPeerConnection.prototype.getSenders=function(){this._senders=this._senders||[];return this._senders.slice()};var origAddTrack=window.RTCPeerConnection.prototype.addTrack;window.RTCPeerConnection.prototype.addTrack=function(track,stream){var pc=this;var sender=origAddTrack.apply(pc,arguments);if(!sender){sender=shimSenderWithDtmf(pc,track);pc._senders.push(sender)}return sender};var origRemoveTrack=window.RTCPeerConnection.prototype.removeTrack;window.RTCPeerConnection.prototype.removeTrack=function(sender){var pc=this;origRemoveTrack.apply(pc,arguments);var idx=pc._senders.indexOf(sender);if(idx!==-1){pc._senders.splice(idx,1)}}}var origAddStream=window.RTCPeerConnection.prototype.addStream;window.RTCPeerConnection.prototype.addStream=function(stream){var pc=this;pc._senders=pc._senders||[];origAddStream.apply(pc,[stream]);stream.getTracks().forEach(function(track){pc._senders.push(shimSenderWithDtmf(pc,track))})};var origRemoveStream=window.RTCPeerConnection.prototype.removeStream;window.RTCPeerConnection.prototype.removeStream=function(stream){var pc=this;pc._senders=pc._senders||[];origRemoveStream.apply(pc,[pc._streams[stream.id]||stream]);stream.getTracks().forEach(function(track){var sender=pc._senders.find(function(s){return s.track===track});if(sender){pc._senders.splice(pc._senders.indexOf(sender),1)}})}}else if(typeof window==="object"&&window.RTCPeerConnection&&"getSenders"in window.RTCPeerConnection.prototype&&"createDTMFSender"in window.RTCPeerConnection.prototype&&window.RTCRtpSender&&!("dtmf"in window.RTCRtpSender.prototype)){var origGetSenders=window.RTCPeerConnection.prototype.getSenders;window.RTCPeerConnection.prototype.getSenders=function(){var pc=this;var senders=origGetSenders.apply(pc,[]);senders.forEach(function(sender){sender._pc=pc});return senders};Object.defineProperty(window.RTCRtpSender.prototype,"dtmf",{get:function(){if(this._dtmf===undefined){if(this.track.kind==="audio"){this._dtmf=this._pc.createDTMFSender(this.track)}else{this._dtmf=null}}return this._dtmf}})}},shimSourceObject:function(window){var URL=window&&window.URL;if(typeof window==="object"){if(window.HTMLMediaElement&&!("srcObject"in window.HTMLMediaElement.prototype)){Object.defineProperty(window.HTMLMediaElement.prototype,"srcObject",{get:function(){return this._srcObject},set:function(stream){var self=this;this._srcObject=stream;if(this.src){URL.revokeObjectURL(this.src)}if(!stream){this.src="";return undefined}this.src=URL.createObjectURL(stream);stream.addEventListener("addtrack",function(){if(self.src){URL.revokeObjectURL(self.src)}self.src=URL.createObjectURL(stream)});stream.addEventListener("removetrack",function(){if(self.src){URL.revokeObjectURL(self.src)}self.src=URL.createObjectURL(stream)})}})}}},shimAddTrackRemoveTrack:function(window){var browserDetails=utils.detectBrowser(window);if(window.RTCPeerConnection.prototype.addTrack&&browserDetails.version>=62){return}var origGetLocalStreams=window.RTCPeerConnection.prototype.getLocalStreams;window.RTCPeerConnection.prototype.getLocalStreams=function(){var self=this;var nativeStreams=origGetLocalStreams.apply(this);self._reverseStreams=self._reverseStreams||{};return nativeStreams.map(function(stream){return self._reverseStreams[stream.id]})};var origAddStream=window.RTCPeerConnection.prototype.addStream;window.RTCPeerConnection.prototype.addStream=function(stream){var pc=this;pc._streams=pc._streams||{};pc._reverseStreams=pc._reverseStreams||{};stream.getTracks().forEach(function(track){var alreadyExists=pc.getSenders().find(function(s){return s.track===track});if(alreadyExists){throw new DOMException("Track already exists.","InvalidAccessError")}});if(!pc._reverseStreams[stream.id]){var newStream=new window.MediaStream(stream.getTracks());pc._streams[stream.id]=newStream;pc._reverseStreams[newStream.id]=stream;stream=newStream}origAddStream.apply(pc,[stream])};var origRemoveStream=window.RTCPeerConnection.prototype.removeStream;window.RTCPeerConnection.prototype.removeStream=function(stream){var pc=this;pc._streams=pc._streams||{};pc._reverseStreams=pc._reverseStreams||{};origRemoveStream.apply(pc,[pc._streams[stream.id]||stream]);delete pc._reverseStreams[pc._streams[stream.id]?pc._streams[stream.id].id:stream.id];delete pc._streams[stream.id]};window.RTCPeerConnection.prototype.addTrack=function(track,stream){var pc=this;if(pc.signalingState==="closed"){throw new DOMException("The RTCPeerConnection's signalingState is 'closed'.","InvalidStateError")}var streams=[].slice.call(arguments,1);if(streams.length!==1||!streams[0].getTracks().find(function(t){return t===track})){throw new DOMException("The adapter.js addTrack polyfill only supports a single "+" stream which is associated with the specified track.","NotSupportedError")}var alreadyExists=pc.getSenders().find(function(s){return s.track===track});if(alreadyExists){throw new DOMException("Track already exists.","InvalidAccessError")}pc._streams=pc._streams||{};pc._reverseStreams=pc._reverseStreams||{};var oldStream=pc._streams[stream.id];if(oldStream){oldStream.addTrack(track);Promise.resolve().then(function(){pc.dispatchEvent(new Event("negotiationneeded"))})}else{var newStream=new window.MediaStream([track]);pc._streams[stream.id]=newStream;pc._reverseStreams[newStream.id]=stream;pc.addStream(newStream)}return pc.getSenders().find(function(s){return s.track===track})};function replaceInternalStreamId(pc,description){var sdp=description.sdp;Object.keys(pc._reverseStreams||[]).forEach(function(internalId){var externalStream=pc._reverseStreams[internalId];var internalStream=pc._streams[externalStream.id];sdp=sdp.replace(new RegExp(internalStream.id,"g"),externalStream.id)});return new RTCSessionDescription({type:description.type,sdp:sdp})}function replaceExternalStreamId(pc,description){var sdp=description.sdp;Object.keys(pc._reverseStreams||[]).forEach(function(internalId){var externalStream=pc._reverseStreams[internalId];var internalStream=pc._streams[externalStream.id];sdp=sdp.replace(new RegExp(externalStream.id,"g"),internalStream.id)});return new RTCSessionDescription({type:description.type,sdp:sdp})}["createOffer","createAnswer"].forEach(function(method){var nativeMethod=window.RTCPeerConnection.prototype[method];window.RTCPeerConnection.prototype[method]=function(){var pc=this;var args=arguments;var isLegacyCall=arguments.length&&typeof arguments[0]==="function";if(isLegacyCall){return nativeMethod.apply(pc,[function(description){var desc=replaceInternalStreamId(pc,description);args[0].apply(null,[desc])},function(err){if(args[1]){args[1].apply(null,err)}},arguments[2]])}return nativeMethod.apply(pc,arguments).then(function(description){return replaceInternalStreamId(pc,description)})}});var origSetLocalDescription=window.RTCPeerConnection.prototype.setLocalDescription;window.RTCPeerConnection.prototype.setLocalDescription=function(){var pc=this;if(!arguments.length||!arguments[0].type){return origSetLocalDescription.apply(pc,arguments)}arguments[0]=replaceExternalStreamId(pc,arguments[0]);return origSetLocalDescription.apply(pc,arguments)};var origLocalDescription=Object.getOwnPropertyDescriptor(window.RTCPeerConnection.prototype,"localDescription");Object.defineProperty(window.RTCPeerConnection.prototype,"localDescription",{get:function(){var pc=this;var description=origLocalDescription.get.apply(this);if(description.type===""){return description}return replaceInternalStreamId(pc,description)}});window.RTCPeerConnection.prototype.removeTrack=function(sender){var pc=this;if(pc.signalingState==="closed"){throw new DOMException("The RTCPeerConnection's signalingState is 'closed'.","InvalidStateError")}if(!sender._pc){throw new DOMException("Argument 1 of RTCPeerConnection.removeTrack "+"does not implement interface RTCRtpSender.","TypeError")}var isLocal=sender._pc===pc;if(!isLocal){throw new DOMException("Sender was not created by this connection.","InvalidAccessError")}pc._streams=pc._streams||{};var stream;Object.keys(pc._streams).forEach(function(streamid){var hasTrack=pc._streams[streamid].getTracks().find(function(track){return sender.track===track});if(hasTrack){stream=pc._streams[streamid]}});if(stream){if(stream.getTracks().length===1){pc.removeStream(stream)}else{stream.removeTrack(sender.track)}pc.dispatchEvent(new Event("negotiationneeded"))}}},shimPeerConnection:function(window){var browserDetails=utils.detectBrowser(window);if(!window.RTCPeerConnection){window.RTCPeerConnection=function(pcConfig,pcConstraints){logging("PeerConnection");if(pcConfig&&pcConfig.iceTransportPolicy){pcConfig.iceTransports=pcConfig.iceTransportPolicy}return new window.webkitRTCPeerConnection(pcConfig,pcConstraints)};window.RTCPeerConnection.prototype=window.webkitRTCPeerConnection.prototype;if(window.webkitRTCPeerConnection.generateCertificate){Object.defineProperty(window.RTCPeerConnection,"generateCertificate",{get:function(){return window.webkitRTCPeerConnection.generateCertificate}})}}else{var OrigPeerConnection=window.RTCPeerConnection;window.RTCPeerConnection=function(pcConfig,pcConstraints){if(pcConfig&&pcConfig.iceServers){var newIceServers=[];for(var i=0;i0&&typeof selector==="function"){return origGetStats.apply(this,arguments)}if(origGetStats.length===0&&(arguments.length===0||typeof arguments[0]!=="function")){return origGetStats.apply(this,[])}var fixChromeStats_=function(response){var standardReport={};var reports=response.result();reports.forEach(function(report){var standardStats={id:report.id,timestamp:report.timestamp,type:{localcandidate:"local-candidate",remotecandidate:"remote-candidate"}[report.type]||report.type};report.names().forEach(function(name){standardStats[name]=report.stat(name)});standardReport[standardStats.id]=standardStats});return standardReport};var makeMapStats=function(stats){return new Map(Object.keys(stats).map(function(key){return[key,stats[key]]}))};if(arguments.length>=2){var successCallbackWrapper_=function(response){args[1](makeMapStats(fixChromeStats_(response)))};return origGetStats.apply(this,[successCallbackWrapper_,arguments[0]])}return new Promise(function(resolve,reject){origGetStats.apply(self,[function(response){resolve(makeMapStats(fixChromeStats_(response)))},reject])}).then(successCallback,errorCallback)};if(browserDetails.version<51){["setLocalDescription","setRemoteDescription","addIceCandidate"].forEach(function(method){var nativeMethod=window.RTCPeerConnection.prototype[method];window.RTCPeerConnection.prototype[method]=function(){var args=arguments;var self=this;var promise=new Promise(function(resolve,reject){nativeMethod.apply(self,[args[0],resolve,reject])});if(args.length<2){return promise}return promise.then(function(){args[1].apply(null,[])},function(err){if(args.length>=3){args[2].apply(null,[err])}})}})}if(browserDetails.version<52){["createOffer","createAnswer"].forEach(function(method){var nativeMethod=window.RTCPeerConnection.prototype[method];window.RTCPeerConnection.prototype[method]=function(){var self=this;if(arguments.length<1||arguments.length===1&&typeof arguments[0]==="object"){var opts=arguments.length===1?arguments[0]:undefined;return new Promise(function(resolve,reject){nativeMethod.apply(self,[resolve,reject,opts])})}return nativeMethod.apply(this,arguments)}})}["setLocalDescription","setRemoteDescription","addIceCandidate"].forEach(function(method){var nativeMethod=window.RTCPeerConnection.prototype[method];window.RTCPeerConnection.prototype[method]=function(){arguments[0]=new(method==="addIceCandidate"?window.RTCIceCandidate:window.RTCSessionDescription)(arguments[0]);return nativeMethod.apply(this,arguments)}});var nativeAddIceCandidate=window.RTCPeerConnection.prototype.addIceCandidate;window.RTCPeerConnection.prototype.addIceCandidate=function(){if(!arguments[0]){if(arguments[1]){arguments[1].apply(null)}return Promise.resolve()}return nativeAddIceCandidate.apply(this,arguments)}}};module.exports={shimMediaStream:chromeShim.shimMediaStream,shimOnTrack:chromeShim.shimOnTrack,shimAddTrackRemoveTrack:chromeShim.shimAddTrackRemoveTrack,shimGetSendersWithDtmf:chromeShim.shimGetSendersWithDtmf,shimSourceObject:chromeShim.shimSourceObject,shimPeerConnection:chromeShim.shimPeerConnection,shimGetUserMedia:require("./getusermedia")}},{"../utils.js":32,"./getusermedia":25}],25:[function(require,module,exports){"use strict";var utils=require("../utils.js");var logging=utils.log;module.exports=function(window){var browserDetails=utils.detectBrowser(window);var navigator=window&&window.navigator;var constraintsToChrome_=function(c){if(typeof c!=="object"||c.mandatory||c.optional){return c}var cc={};Object.keys(c).forEach(function(key){if(key==="require"||key==="advanced"||key==="mediaSource"){return}var r=typeof c[key]==="object"?c[key]:{ideal:c[key]};if(r.exact!==undefined&&typeof r.exact==="number"){r.min=r.max=r.exact}var oldname_=function(prefix,name){if(prefix){return prefix+name.charAt(0).toUpperCase()+name.slice(1)}return name==="deviceId"?"sourceId":name};if(r.ideal!==undefined){cc.optional=cc.optional||[];var oc={};if(typeof r.ideal==="number"){oc[oldname_("min",key)]=r.ideal;cc.optional.push(oc);oc={};oc[oldname_("max",key)]=r.ideal;cc.optional.push(oc)}else{oc[oldname_("",key)]=r.ideal;cc.optional.push(oc)}}if(r.exact!==undefined&&typeof r.exact!=="number"){cc.mandatory=cc.mandatory||{};cc.mandatory[oldname_("",key)]=r.exact}else{["min","max"].forEach(function(mix){if(r[mix]!==undefined){cc.mandatory=cc.mandatory||{};cc.mandatory[oldname_(mix,key)]=r[mix]}})}});if(c.advanced){cc.optional=(cc.optional||[]).concat(c.advanced)}return cc};var shimConstraints_=function(constraints,func){constraints=JSON.parse(JSON.stringify(constraints));if(constraints&&typeof constraints.audio==="object"){var remap=function(obj,a,b){if(a in obj&&!(b in obj)){obj[b]=obj[a];delete obj[a]}};constraints=JSON.parse(JSON.stringify(constraints));remap(constraints.audio,"autoGainControl","googAutoGainControl");remap(constraints.audio,"noiseSuppression","googNoiseSuppression");constraints.audio=constraintsToChrome_(constraints.audio)}if(constraints&&typeof constraints.video==="object"){var face=constraints.video.facingMode;face=face&&(typeof face==="object"?face:{ideal:face});var getSupportedFacingModeLies=browserDetails.version<61;if(face&&(face.exact==="user"||face.exact==="environment"||face.ideal==="user"||face.ideal==="environment")&&!(navigator.mediaDevices.getSupportedConstraints&&navigator.mediaDevices.getSupportedConstraints().facingMode&&!getSupportedFacingModeLies)){delete constraints.video.facingMode;var matches;if(face.exact==="environment"||face.ideal==="environment"){matches=["back","rear"]}else if(face.exact==="user"||face.ideal==="user"){matches=["front"]}if(matches){return navigator.mediaDevices.enumerateDevices().then(function(devices){devices=devices.filter(function(d){return d.kind==="videoinput"});var dev=devices.find(function(d){return matches.some(function(match){return d.label.toLowerCase().indexOf(match)!==-1})});if(!dev&&devices.length&&matches.indexOf("back")!==-1){dev=devices[devices.length-1]}if(dev){constraints.video.deviceId=face.exact?{exact:dev.deviceId}:{ideal:dev.deviceId}}constraints.video=constraintsToChrome_(constraints.video);logging("chrome: "+JSON.stringify(constraints));return func(constraints)})}}constraints.video=constraintsToChrome_(constraints.video)}logging("chrome: "+JSON.stringify(constraints));return func(constraints)};var shimError_=function(e){return{name:{PermissionDeniedError:"NotAllowedError",InvalidStateError:"NotReadableError",DevicesNotFoundError:"NotFoundError",ConstraintNotSatisfiedError:"OverconstrainedError",TrackStartError:"NotReadableError",MediaDeviceFailedDueToShutdown:"NotReadableError",MediaDeviceKillSwitchOn:"NotReadableError"}[e.name]||e.name,message:e.message,constraint:e.constraintName,toString:function(){return this.name+(this.message&&": ")+this.message}}};var getUserMedia_=function(constraints,onSuccess,onError){shimConstraints_(constraints,function(c){navigator.webkitGetUserMedia(c,onSuccess,function(e){if(onError){onError(shimError_(e))}})})};navigator.getUserMedia=getUserMedia_;var getUserMediaPromise_=function(constraints){return new Promise(function(resolve,reject){navigator.getUserMedia(constraints,resolve,reject)})};if(!navigator.mediaDevices){navigator.mediaDevices={getUserMedia:getUserMediaPromise_,enumerateDevices:function(){return new Promise(function(resolve){var kinds={audio:"audioinput",video:"videoinput"};return window.MediaStreamTrack.getSources(function(devices){resolve(devices.map(function(device){return{label:device.label,kind:kinds[device.kind],deviceId:device.id,groupId:""}}))})})},getSupportedConstraints:function(){return{deviceId:true,echoCancellation:true,facingMode:true,frameRate:true,height:true,width:true}}}}if(!navigator.mediaDevices.getUserMedia){navigator.mediaDevices.getUserMedia=function(constraints){return getUserMediaPromise_(constraints)}}else{var origGetUserMedia=navigator.mediaDevices.getUserMedia.bind(navigator.mediaDevices);navigator.mediaDevices.getUserMedia=function(cs){return shimConstraints_(cs,function(c){return origGetUserMedia(c).then(function(stream){if(c.audio&&!stream.getAudioTracks().length||c.video&&!stream.getVideoTracks().length){stream.getTracks().forEach(function(track){track.stop()});throw new DOMException("","NotFoundError")}return stream},function(e){return Promise.reject(shimError_(e))})})}}if(typeof navigator.mediaDevices.addEventListener==="undefined"){navigator.mediaDevices.addEventListener=function(){logging("Dummy mediaDevices.addEventListener called.")}}if(typeof navigator.mediaDevices.removeEventListener==="undefined"){navigator.mediaDevices.removeEventListener=function(){logging("Dummy mediaDevices.removeEventListener called.")}}}},{"../utils.js":32}],26:[function(require,module,exports){"use strict";var SDPUtils=require("sdp");var utils=require("./utils");function wrapPeerConnectionEvent(window,eventNameToWrap,wrapper){if(!window.RTCPeerConnection){return}var proto=window.RTCPeerConnection.prototype;var nativeAddEventListener=proto.addEventListener;proto.addEventListener=function(nativeEventName,cb){if(nativeEventName!==eventNameToWrap){return nativeAddEventListener.apply(this,arguments)}var wrappedCallback=function(e){cb(wrapper(e))};this._eventMap=this._eventMap||{};this._eventMap[cb]=wrappedCallback;return nativeAddEventListener.apply(this,[nativeEventName,wrappedCallback])};var nativeRemoveEventListener=proto.removeEventListener;proto.removeEventListener=function(nativeEventName,cb){if(nativeEventName!==eventNameToWrap||!this._eventMap||!this._eventMap[cb]){return nativeRemoveEventListener.apply(this,arguments)}var unwrappedCb=this._eventMap[cb];delete this._eventMap[cb];return nativeRemoveEventListener.apply(this,[nativeEventName,unwrappedCb])};Object.defineProperty(proto,"on"+eventNameToWrap,{get:function(){return this["_on"+eventNameToWrap]},set:function(cb){if(this["_on"+eventNameToWrap]){this.removeEventListener(eventNameToWrap,this["_on"+eventNameToWrap]);delete this["_on"+eventNameToWrap]}if(cb){this.addEventListener(eventNameToWrap,this["_on"+eventNameToWrap]=cb)}}})}module.exports={shimRTCIceCandidate:function(window){if(window.RTCIceCandidate&&"foundation"in window.RTCIceCandidate.prototype){return}var NativeRTCIceCandidate=window.RTCIceCandidate;window.RTCIceCandidate=function(args){if(typeof args==="object"&&args.candidate&&args.candidate.indexOf("a=")===0){args=JSON.parse(JSON.stringify(args));args.candidate=args.candidate.substr(2)}var nativeCandidate=new NativeRTCIceCandidate(args);var parsedCandidate=SDPUtils.parseCandidate(args.candidate);var augmentedCandidate=Object.assign(nativeCandidate,parsedCandidate);augmentedCandidate.toJSON=function(){return{candidate:augmentedCandidate.candidate,sdpMid:augmentedCandidate.sdpMid,sdpMLineIndex:augmentedCandidate.sdpMLineIndex,usernameFragment:augmentedCandidate.usernameFragment}};return augmentedCandidate};wrapPeerConnectionEvent(window,"icecandidate",function(e){if(e.candidate){Object.defineProperty(e,"candidate",{value:new window.RTCIceCandidate(e.candidate),writable:"false"})}return e})},shimCreateObjectURL:function(window){var URL=window&&window.URL;if(!(typeof window==="object"&&window.HTMLMediaElement&&"srcObject"in window.HTMLMediaElement.prototype&&URL.createObjectURL&&URL.revokeObjectURL)){return undefined}var nativeCreateObjectURL=URL.createObjectURL.bind(URL);var nativeRevokeObjectURL=URL.revokeObjectURL.bind(URL);var streams=new Map,newId=0;URL.createObjectURL=function(stream){if("getTracks"in stream){var url="polyblob:"+ ++newId;streams.set(url,stream);utils.deprecated("URL.createObjectURL(stream)","elem.srcObject = stream");return url}return nativeCreateObjectURL(stream)};URL.revokeObjectURL=function(url){nativeRevokeObjectURL(url);streams.delete(url)};var dsc=Object.getOwnPropertyDescriptor(window.HTMLMediaElement.prototype,"src");Object.defineProperty(window.HTMLMediaElement.prototype,"src",{get:function(){return dsc.get.apply(this)},set:function(url){this.srcObject=streams.get(url)||null;return dsc.set.apply(this,[url])}});var nativeSetAttribute=window.HTMLMediaElement.prototype.setAttribute;window.HTMLMediaElement.prototype.setAttribute=function(){if(arguments.length===2&&(""+arguments[0]).toLowerCase()==="src"){this.srcObject=streams.get(arguments[1])||null}return nativeSetAttribute.apply(this,arguments)}}}},{"./utils":32,sdp:18}],27:[function(require,module,exports){"use strict";var utils=require("../utils");var shimRTCPeerConnection=require("rtcpeerconnection-shim");module.exports={shimGetUserMedia:require("./getusermedia"),shimPeerConnection:function(window){var browserDetails=utils.detectBrowser(window);if(window.RTCIceGatherer){if(!window.RTCIceCandidate){window.RTCIceCandidate=function(args){return args}}if(!window.RTCSessionDescription){window.RTCSessionDescription=function(args){return args}}if(browserDetails.version<15025){var origMSTEnabled=Object.getOwnPropertyDescriptor(window.MediaStreamTrack.prototype,"enabled");Object.defineProperty(window.MediaStreamTrack.prototype,"enabled",{set:function(value){origMSTEnabled.set.call(this,value);var ev=new Event("enabled");ev.enabled=value;this.dispatchEvent(ev)}})}}if(window.RTCRtpSender&&!("dtmf"in window.RTCRtpSender.prototype)){Object.defineProperty(window.RTCRtpSender.prototype,"dtmf",{get:function(){if(this._dtmf===undefined){if(this.track.kind==="audio"){this._dtmf=new window.RTCDtmfSender(this)}else if(this.track.kind==="video"){this._dtmf=null}}return this._dtmf}})}window.RTCPeerConnection=shimRTCPeerConnection(window,browserDetails.version)},shimReplaceTrack:function(window){if(window.RTCRtpSender&&!("replaceTrack"in window.RTCRtpSender.prototype)){window.RTCRtpSender.prototype.replaceTrack=window.RTCRtpSender.prototype.setTrack}}}},{"../utils":32,"./getusermedia":28,"rtcpeerconnection-shim":9}],28:[function(require,module,exports){"use strict";module.exports=function(window){var navigator=window&&window.navigator;var shimError_=function(e){return{name:{PermissionDeniedError:"NotAllowedError"}[e.name]||e.name,message:e.message,constraint:e.constraint,toString:function(){return this.name}}};var origGetUserMedia=navigator.mediaDevices.getUserMedia.bind(navigator.mediaDevices);navigator.mediaDevices.getUserMedia=function(c){return origGetUserMedia(c).catch(function(e){return Promise.reject(shimError_(e))})}}},{}],29:[function(require,module,exports){"use strict";var utils=require("../utils");var firefoxShim={shimOnTrack:function(window){if(typeof window==="object"&&window.RTCPeerConnection&&!("ontrack"in window.RTCPeerConnection.prototype)){Object.defineProperty(window.RTCPeerConnection.prototype,"ontrack",{get:function(){return this._ontrack},set:function(f){if(this._ontrack){this.removeEventListener("track",this._ontrack);this.removeEventListener("addstream",this._ontrackpoly)}this.addEventListener("track",this._ontrack=f);this.addEventListener("addstream",this._ontrackpoly=function(e){e.stream.getTracks().forEach(function(track){var event=new Event("track");event.track=track;event.receiver={track:track};event.transceiver={receiver:event.receiver};event.streams=[e.stream];this.dispatchEvent(event)}.bind(this))}.bind(this))}})}if(typeof window==="object"&&window.RTCTrackEvent&&"receiver"in window.RTCTrackEvent.prototype&&!("transceiver"in window.RTCTrackEvent.prototype)){Object.defineProperty(window.RTCTrackEvent.prototype,"transceiver",{get:function(){return{receiver:this.receiver}}})}},shimSourceObject:function(window){if(typeof window==="object"){if(window.HTMLMediaElement&&!("srcObject"in window.HTMLMediaElement.prototype)){Object.defineProperty(window.HTMLMediaElement.prototype,"srcObject",{get:function(){return this.mozSrcObject},set:function(stream){this.mozSrcObject=stream}})}}},shimPeerConnection:function(window){var browserDetails=utils.detectBrowser(window);if(typeof window!=="object"||!(window.RTCPeerConnection||window.mozRTCPeerConnection)){return}if(!window.RTCPeerConnection){window.RTCPeerConnection=function(pcConfig,pcConstraints){if(browserDetails.version<38){if(pcConfig&&pcConfig.iceServers){var newIceServers=[];for(var i=0;i55&&"autoGainControl"in navigator.mediaDevices.getSupportedConstraints())){var remap=function(obj,a,b){if(a in obj&&!(b in obj)){obj[b]=obj[a];delete obj[a]}};var nativeGetUserMedia=navigator.mediaDevices.getUserMedia.bind(navigator.mediaDevices);navigator.mediaDevices.getUserMedia=function(c){if(typeof c==="object"&&typeof c.audio==="object"){c=JSON.parse(JSON.stringify(c));remap(c.audio,"autoGainControl","mozAutoGainControl");remap(c.audio,"noiseSuppression","mozNoiseSuppression")}return nativeGetUserMedia(c)};if(MediaStreamTrack&&MediaStreamTrack.prototype.getSettings){var nativeGetSettings=MediaStreamTrack.prototype.getSettings;MediaStreamTrack.prototype.getSettings=function(){var obj=nativeGetSettings.apply(this,arguments);remap(obj,"mozAutoGainControl","autoGainControl");remap(obj,"mozNoiseSuppression","noiseSuppression");return obj}}if(MediaStreamTrack&&MediaStreamTrack.prototype.applyConstraints){var nativeApplyConstraints=MediaStreamTrack.prototype.applyConstraints;MediaStreamTrack.prototype.applyConstraints=function(c){if(this.kind==="audio"&&typeof c==="object"){c=JSON.parse(JSON.stringify(c));remap(c,"autoGainControl","mozAutoGainControl");remap(c,"noiseSuppression","mozNoiseSuppression")}return nativeApplyConstraints.apply(this,[c])}}}navigator.getUserMedia=function(constraints,onSuccess,onError){if(browserDetails.version<44){return getUserMedia_(constraints,onSuccess,onError)}utils.deprecated("navigator.getUserMedia","navigator.mediaDevices.getUserMedia");navigator.mediaDevices.getUserMedia(constraints).then(onSuccess,onError)}}},{"../utils":32}],31:[function(require,module,exports){"use strict";var utils=require("../utils");var safariShim={shimLocalStreamsAPI:function(window){if(typeof window!=="object"||!window.RTCPeerConnection){return}if(!("getLocalStreams"in window.RTCPeerConnection.prototype)){window.RTCPeerConnection.prototype.getLocalStreams=function(){if(!this._localStreams){this._localStreams=[]}return this._localStreams}}if(!("getStreamById"in window.RTCPeerConnection.prototype)){window.RTCPeerConnection.prototype.getStreamById=function(id){var result=null;if(this._localStreams){this._localStreams.forEach(function(stream){if(stream.id===id){result=stream}})}if(this._remoteStreams){this._remoteStreams.forEach(function(stream){if(stream.id===id){result=stream}})}return result}}if(!("addStream"in window.RTCPeerConnection.prototype)){var _addTrack=window.RTCPeerConnection.prototype.addTrack;window.RTCPeerConnection.prototype.addStream=function(stream){if(!this._localStreams){this._localStreams=[]}if(this._localStreams.indexOf(stream)===-1){this._localStreams.push(stream)}var self=this;stream.getTracks().forEach(function(track){_addTrack.call(self,track,stream)})};window.RTCPeerConnection.prototype.addTrack=function(track,stream){if(stream){if(!this._localStreams){this._localStreams=[stream]}else if(this._localStreams.indexOf(stream)===-1){this._localStreams.push(stream)}}_addTrack.call(this,track,stream)}}if(!("removeStream"in window.RTCPeerConnection.prototype)){window.RTCPeerConnection.prototype.removeStream=function(stream){if(!this._localStreams){this._localStreams=[]}var index=this._localStreams.indexOf(stream);if(index===-1){return}this._localStreams.splice(index,1);var self=this;var tracks=stream.getTracks();this.getSenders().forEach(function(sender){if(tracks.indexOf(sender.track)!==-1){self.removeTrack(sender)}})}}},shimRemoteStreamsAPI:function(window){if(typeof window!=="object"||!window.RTCPeerConnection){return}if(!("getRemoteStreams"in window.RTCPeerConnection.prototype)){window.RTCPeerConnection.prototype.getRemoteStreams=function(){return this._remoteStreams?this._remoteStreams:[]}}if(!("onaddstream"in window.RTCPeerConnection.prototype)){Object.defineProperty(window.RTCPeerConnection.prototype,"onaddstream",{get:function(){return this._onaddstream},set:function(f){if(this._onaddstream){this.removeEventListener("addstream",this._onaddstream);this.removeEventListener("track",this._onaddstreampoly)}this.addEventListener("addstream",this._onaddstream=f);this.addEventListener("track",this._onaddstreampoly=function(e){var stream=e.streams[0];if(!this._remoteStreams){this._remoteStreams=[]}if(this._remoteStreams.indexOf(stream)>=0){return}this._remoteStreams.push(stream);var event=new Event("addstream");event.stream=e.streams[0];this.dispatchEvent(event)}.bind(this))}})}},shimCallbacksAPI:function(window){if(typeof window!=="object"||!window.RTCPeerConnection){return}var prototype=window.RTCPeerConnection.prototype;var createOffer=prototype.createOffer;var createAnswer=prototype.createAnswer;var setLocalDescription=prototype.setLocalDescription;var setRemoteDescription=prototype.setRemoteDescription;var addIceCandidate=prototype.addIceCandidate;prototype.createOffer=function(successCallback,failureCallback){var options=arguments.length>=2?arguments[2]:arguments[0];var promise=createOffer.apply(this,[options]);if(!failureCallback){return promise}promise.then(successCallback,failureCallback);return Promise.resolve()};prototype.createAnswer=function(successCallback,failureCallback){var options=arguments.length>=2?arguments[2]:arguments[0];var promise=createAnswer.apply(this,[options]);if(!failureCallback){return promise}promise.then(successCallback,failureCallback);return Promise.resolve()};var withCallback=function(description,successCallback,failureCallback){var promise=setLocalDescription.apply(this,[description]);if(!failureCallback){return promise}promise.then(successCallback,failureCallback);return Promise.resolve()};prototype.setLocalDescription=withCallback;withCallback=function(description,successCallback,failureCallback){var promise=setRemoteDescription.apply(this,[description]);if(!failureCallback){return promise}promise.then(successCallback,failureCallback);return Promise.resolve()};prototype.setRemoteDescription=withCallback;withCallback=function(candidate,successCallback,failureCallback){var promise=addIceCandidate.apply(this,[candidate]);if(!failureCallback){return promise}promise.then(successCallback,failureCallback);return Promise.resolve()};prototype.addIceCandidate=withCallback},shimGetUserMedia:function(window){var navigator=window&&window.navigator;if(!navigator.getUserMedia){if(navigator.webkitGetUserMedia){navigator.getUserMedia=navigator.webkitGetUserMedia.bind(navigator)}else if(navigator.mediaDevices&&navigator.mediaDevices.getUserMedia){navigator.getUserMedia=function(constraints,cb,errcb){navigator.mediaDevices.getUserMedia(constraints).then(cb,errcb)}.bind(navigator)}}},shimRTCIceServerUrls:function(window){var OrigPeerConnection=window.RTCPeerConnection;window.RTCPeerConnection=function(pcConfig,pcConstraints){if(pcConfig&&pcConfig.iceServers){var newIceServers=[];for(var i=0;i=pos&&parseInt(match[pos],10)},detectBrowser:function(window){var navigator=window&&window.navigator;var result={};result.browser=null;result.version=null;if(typeof window==="undefined"||!window.navigator){result.browser="Not a browser.";return result}if(navigator.mozGetUserMedia){result.browser="firefox";result.version=this.extractVersion(navigator.userAgent,/Firefox\/(\d+)\./,1)}else if(navigator.webkitGetUserMedia){if(window.webkitRTCPeerConnection){result.browser="chrome";result.version=this.extractVersion(navigator.userAgent,/Chrom(e|ium)\/(\d+)\./,2)}else{if(navigator.userAgent.match(/Version\/(\d+).(\d+)/)){result.browser="safari";result.version=this.extractVersion(navigator.userAgent,/AppleWebKit\/(\d+)\./,1)}else{result.browser="Unsupported webkit-based browser "+"with GUM support but no WebRTC support.";return result}}}else if(navigator.mediaDevices&&navigator.userAgent.match(/Edge\/(\d+).(\d+)$/)){result.browser="edge";result.version=this.extractVersion(navigator.userAgent,/Edge\/(\d+).(\d+)$/,2)}else if(navigator.mediaDevices&&navigator.userAgent.match(/AppleWebKit\/(\d+)\./)){result.browser="safari";result.version=this.extractVersion(navigator.userAgent,/AppleWebKit\/(\d+)\./,1)}else{result.browser="Not a supported browser.";return result}return result}};module.exports={log:utils.log,deprecated:utils.deprecated,disableLog:utils.disableLog,disableWarnings:utils.disableWarnings,extractVersion:utils.extractVersion,shimCreateObjectURL:utils.shimCreateObjectURL,detectBrowser:utils.detectBrowser.bind(utils)}},{}],33:[function(require,module,exports){module.exports=WildEmitter;function WildEmitter(){}WildEmitter.mixin=function(constructor){var prototype=constructor.prototype||constructor;prototype.isWildEmitter=true;prototype.on=function(event,groupName,fn){this.callbacks=this.callbacks||{};var hasGroup=arguments.length===3,group=hasGroup?arguments[1]:undefined,func=hasGroup?arguments[2]:arguments[1];func._groupName=group;(this.callbacks[event]=this.callbacks[event]||[]).push(func);return this};prototype.once=function(event,groupName,fn){var self=this,hasGroup=arguments.length===3,group=hasGroup?arguments[1]:undefined,func=hasGroup?arguments[2]:arguments[1];function on(){self.off(event,on);func.apply(this,arguments)}this.on(event,group,on);return this};prototype.releaseGroup=function(groupName){this.callbacks=this.callbacks||{};var item,i,len,handlers;for(item in this.callbacks){handlers=this.callbacks[item];for(i=0,len=handlers.length;inotReconnectIfNumLessThan){enabledPings=false;updateNotReconnectIfLessThan();Logger.debug("Server did not respond to ping message #"+pingNum+". Reconnecting... ");ws.reconnectWs()}}}}(pingNextNum))}else{Logger.debug("Trying to send ping, but ping is not enabled")}}function usePing(){if(!pingPongStarted){Logger.debug("Starting ping (if configured)");pingPongStarted=true;if(configuration.heartbeat!=undefined){pingInterval=setInterval(sendPing,configuration.heartbeat);sendPing()}}}this.close=function(){Logger.debug("Closing jsonRpcClient explicitly by client");if(pingInterval!=undefined){Logger.debug("Clearing ping interval");clearInterval(pingInterval)}pingPongStarted=false;enabledPings=false;if(configuration.sendCloseMessage){Logger.debug("Sending close message");this.send("closeSession",null,function(error,result){if(error){Logger.error("Error sending close message: "+JSON.stringify(error))}ws.close()})}else{ws.close()}};this.forceClose=function(millis){ws.forceClose(millis)};this.reconnect=function(){ws.reconnectWs()}}module.exports=JsonRpcClient},{"../":40,"./transports/webSocketWithReconnection":39}],38:[function(require,module,exports){var WebSocketWithReconnection=require("./webSocketWithReconnection");exports.WebSocketWithReconnection=WebSocketWithReconnection},{"./webSocketWithReconnection":39}],39:[function(require,module,exports){(function(global){"use strict";var BrowserWebSocket=global.WebSocket||global.MozWebSocket;var Logger=console;var MAX_RETRIES=2e3;var RETRY_TIME_MS=3e3;var CONNECTING=0;var OPEN=1;var CLOSING=2;var CLOSED=3;function WebSocketWithReconnection(config){var closing=false;var registerMessageHandler;var wsUri=config.uri;var useSockJS=config.useSockJS;var reconnecting=false;var forcingDisconnection=false;var ws;if(useSockJS){ws=new SockJS(wsUri)}else{ws=new WebSocket(wsUri)}ws.onopen=function(){logConnected(ws,wsUri);if(config.onconnected){config.onconnected()}};ws.onerror=function(error){Logger.error("Could not connect to "+wsUri+" (invoking onerror if defined)",error);if(config.onerror){config.onerror(error)}};function logConnected(ws,wsUri){try{Logger.debug("WebSocket connected to "+wsUri)}catch(e){Logger.error(e)}}var reconnectionOnClose=function(){if(ws.readyState===CLOSED){if(closing){Logger.debug("Connection closed by user")}else{Logger.debug("Connection closed unexpectecly. Reconnecting...");reconnectToSameUri(MAX_RETRIES,1)}}else{Logger.debug("Close callback from previous websocket. Ignoring it")}};ws.onclose=reconnectionOnClose;function reconnectToSameUri(maxRetries,numRetries){Logger.debug("reconnectToSameUri (attempt #"+numRetries+", max="+maxRetries+")");if(numRetries===1){if(reconnecting){Logger.warn("Trying to reconnectToNewUri when reconnecting... Ignoring this reconnection.");return}else{reconnecting=true}if(config.onreconnecting){config.onreconnecting()}}if(forcingDisconnection){reconnectToNewUri(maxRetries,numRetries,wsUri)}else{if(config.newWsUriOnReconnection){config.newWsUriOnReconnection(function(error,newWsUri){if(error){Logger.debug(error);setTimeout(function(){reconnectToSameUri(maxRetries,numRetries+1)},RETRY_TIME_MS)}else{reconnectToNewUri(maxRetries,numRetries,newWsUri)}})}else{reconnectToNewUri(maxRetries,numRetries,wsUri)}}}function reconnectToNewUri(maxRetries,numRetries,reconnectWsUri){Logger.debug("Reconnection attempt #"+numRetries);ws.close();wsUri=reconnectWsUri||wsUri;var newWs;if(useSockJS){newWs=new SockJS(wsUri)}else{newWs=new WebSocket(wsUri)}newWs.onopen=function(){Logger.debug("Reconnected after "+numRetries+" attempts...");logConnected(newWs,wsUri);reconnecting=false;registerMessageHandler();if(config.onreconnected()){config.onreconnected()}newWs.onclose=reconnectionOnClose};var onErrorOrClose=function(error){Logger.warn("Reconnection error: ",error);if(numRetries===maxRetries){if(config.ondisconnect){config.ondisconnect()}}else{setTimeout(function(){reconnectToSameUri(maxRetries,numRetries+1)},RETRY_TIME_MS)}};newWs.onerror=onErrorOrClose;ws=newWs}this.close=function(){closing=true;ws.close()};this.forceClose=function(millis){Logger.debug("Testing: Force WebSocket close");if(millis){Logger.debug("Testing: Change wsUri for "+millis+" millis to simulate net failure");var goodWsUri=wsUri;wsUri="wss://21.234.12.34.4:443/";forcingDisconnection=true;setTimeout(function(){Logger.debug("Testing: Recover good wsUri "+goodWsUri);wsUri=goodWsUri;forcingDisconnection=false},millis)}ws.close()};this.reconnectWs=function(){Logger.debug("reconnectWs");reconnectToSameUri(MAX_RETRIES,1,wsUri)};this.send=function(message){ws.send(message)};this.addEventListener=function(type,callback){registerMessageHandler=function(){ws.addEventListener(type,callback)};registerMessageHandler()}}module.exports=WebSocketWithReconnection}).call(this,typeof global!=="undefined"?global:typeof self!=="undefined"?self:typeof window!=="undefined"?window:{})},{}],40:[function(require,module,exports){var defineProperty_IE8=false;if(Object.defineProperty){try{Object.defineProperty({},"x",{})}catch(e){defineProperty_IE8=true}}if(!Function.prototype.bind){Function.prototype.bind=function(oThis){if(typeof this!=="function"){throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable")}var aArgs=Array.prototype.slice.call(arguments,1),fToBind=this,fNOP=function(){},fBound=function(){return fToBind.apply(this instanceof fNOP&&oThis?this:oThis,aArgs.concat(Array.prototype.slice.call(arguments)))};fNOP.prototype=this.prototype;fBound.prototype=new fNOP;return fBound}}var EventEmitter=require("events").EventEmitter;var inherits=require("inherits");var packers=require("./packers");var Mapper=require("./Mapper");var BASE_TIMEOUT=5e3;function unifyResponseMethods(responseMethods){if(!responseMethods)return{};for(var key in responseMethods){var value=responseMethods[key];if(typeof value=="string")responseMethods[key]={response:value}}return responseMethods}function unifyTransport(transport){if(!transport)return;if(transport instanceof Function)return{send:transport};if(transport.send instanceof Function)return transport;if(transport.postMessage instanceof Function){transport.send=transport.postMessage;return transport}if(transport.write instanceof Function){transport.send=transport.write;return transport}if(transport.onmessage!==undefined)return;if(transport.pause instanceof Function)return;throw new SyntaxError("Transport is not a function nor a valid object")}function RpcNotification(method,params){if(defineProperty_IE8){this.method=method;this.params=params}else{Object.defineProperty(this,"method",{value:method,enumerable:true});Object.defineProperty(this,"params",{value:params,enumerable:true})}}function RpcBuilder(packer,options,transport,onRequest){var self=this;if(!packer)throw new SyntaxError("Packer is not defined");if(!packer.pack||!packer.unpack)throw new SyntaxError("Packer is invalid");var responseMethods=unifyResponseMethods(packer.responseMethods);if(options instanceof Function){if(transport!=undefined)throw new SyntaxError("There can't be parameters after onRequest");onRequest=options;transport=undefined;options=undefined}if(options&&options.send instanceof Function){if(transport&&!(transport instanceof Function))throw new SyntaxError("Only a function can be after transport");onRequest=transport;transport=options;options=undefined}if(transport instanceof Function){if(onRequest!=undefined)throw new SyntaxError("There can't be parameters after onRequest");onRequest=transport;transport=undefined}if(transport&&transport.send instanceof Function)if(onRequest&&!(onRequest instanceof Function))throw new SyntaxError("Only a function can be after transport");options=options||{};EventEmitter.call(this);if(onRequest)this.on("request",onRequest);if(defineProperty_IE8)this.peerID=options.peerID;else Object.defineProperty(this,"peerID",{value:options.peerID});var max_retries=options.max_retries||0;function transportMessage(event){self.decode(event.data||event)}this.getTransport=function(){return transport};this.setTransport=function(value){if(transport){if(transport.removeEventListener)transport.removeEventListener("message",transportMessage);else if(transport.removeListener)transport.removeListener("data",transportMessage)}if(value){if(value.addEventListener)value.addEventListener("message",transportMessage);else if(value.addListener)value.addListener("data",transportMessage)}transport=unifyTransport(value)};if(!defineProperty_IE8)Object.defineProperty(this,"transport",{get:this.getTransport.bind(this),set:this.setTransport.bind(this)});this.setTransport(transport);var request_timeout=options.request_timeout||BASE_TIMEOUT;var ping_request_timeout=options.ping_request_timeout||request_timeout;var response_timeout=options.response_timeout||BASE_TIMEOUT;var duplicates_timeout=options.duplicates_timeout||BASE_TIMEOUT;var requestID=0;var requests=new Mapper;var responses=new Mapper;var processedResponses=new Mapper;var message2Key={};function storeResponse(message,id,dest){var response={message:message,timeout:setTimeout(function(){responses.remove(id,dest)},response_timeout)};responses.set(response,id,dest)}function storeProcessedResponse(ack,from){var timeout=setTimeout(function(){processedResponses.remove(ack,from)},duplicates_timeout);processedResponses.set(timeout,ack,from)}function RpcRequest(method,params,id,from,transport){RpcNotification.call(this,method,params);this.getTransport=function(){return transport};this.setTransport=function(value){transport=unifyTransport(value)};if(!defineProperty_IE8)Object.defineProperty(this,"transport",{get:this.getTransport.bind(this),set:this.setTransport.bind(this)});var response=responses.get(id,from);if(!(transport||self.getTransport())){if(defineProperty_IE8)this.duplicated=Boolean(response);else Object.defineProperty(this,"duplicated",{value:Boolean(response)})}var responseMethod=responseMethods[method];this.pack=packer.pack.bind(packer,this,id);this.reply=function(error,result,transport){if(error instanceof Function||error&&error.send instanceof Function){if(result!=undefined)throw new SyntaxError("There can't be parameters after callback");transport=error;result=null;error=undefined}else if(result instanceof Function||result&&result.send instanceof Function){if(transport!=undefined)throw new SyntaxError("There can't be parameters after callback");transport=result;result=null}transport=unifyTransport(transport);if(response)clearTimeout(response.timeout);if(from!=undefined){if(error)error.dest=from;if(result)result.dest=from}var message;if(error||result!=undefined){if(self.peerID!=undefined){if(error)error.from=self.peerID;else result.from=self.peerID}if(responseMethod){if(responseMethod.error==undefined&&error)message={error:error};else{var method=error?responseMethod.error:responseMethod.response;message={method:method,params:error||result}}}else message={error:error,result:result};message=packer.pack(message,id)}else if(response)message=response.message;else message=packer.pack({result:null},id);storeResponse(message,id,from);transport=transport||this.getTransport()||self.getTransport();if(transport)return transport.send(message);return message}}inherits(RpcRequest,RpcNotification);function cancel(message){var key=message2Key[message];if(!key)return;delete message2Key[message];var request=requests.pop(key.id,key.dest);if(!request)return;clearTimeout(request.timeout);storeProcessedResponse(key.id,key.dest)}this.cancel=function(message){if(message)return cancel(message);for(var message in message2Key)cancel(message)};this.close=function(){var transport=this.getTransport();if(transport&&transport.close)transport.close();this.cancel();processedResponses.forEach(clearTimeout);responses.forEach(function(response){clearTimeout(response.timeout)})};this.encode=function(method,params,dest,transport,callback){if(params instanceof Function){if(dest!=undefined)throw new SyntaxError("There can't be parameters after callback");callback=params;transport=undefined;dest=undefined;params=undefined}else if(dest instanceof Function){if(transport!=undefined)throw new SyntaxError("There can't be parameters after callback");callback=dest;transport=undefined;dest=undefined}else if(transport instanceof Function){if(callback!=undefined)throw new SyntaxError("There can't be parameters after callback");callback=transport;transport=undefined}if(self.peerID!=undefined){params=params||{};params.from=self.peerID}if(dest!=undefined){params=params||{};params.dest=dest}var message={method:method,params:params};if(callback){var id=requestID++;var retried=0;message=packer.pack(message,id);function dispatchCallback(error,result){self.cancel(message);callback(error,result)}var request={message:message,callback:dispatchCallback,responseMethods:responseMethods[method]||{}};var encode_transport=unifyTransport(transport);function sendRequest(transport){var rt=method==="ping"?ping_request_timeout:request_timeout;request.timeout=setTimeout(timeout,rt*Math.pow(2,retried++));message2Key[message]={id:id,dest:dest};requests.set(request,id,dest);transport=transport||encode_transport||self.getTransport();if(transport)return transport.send(message);return message}function retry(transport){transport=unifyTransport(transport);console.warn(retried+" retry for request message:",message);var timeout=processedResponses.pop(id,dest);clearTimeout(timeout);return sendRequest(transport)}function timeout(){if(retried0){return sdp.slice(0,n)}else{return sdp}}function getSimulcastInfo(videoStream){var videoTracks=videoStream.getVideoTracks();if(!videoTracks.length){logger.warn("No video tracks available in the video stream");return""}var lines=["a=x-google-flag:conference","a=ssrc-group:SIM 1 2 3","a=ssrc:1 cname:localVideo","a=ssrc:1 msid:"+videoStream.id+" "+videoTracks[0].id,"a=ssrc:1 mslabel:"+videoStream.id,"a=ssrc:1 label:"+videoTracks[0].id,"a=ssrc:2 cname:localVideo","a=ssrc:2 msid:"+videoStream.id+" "+videoTracks[0].id,"a=ssrc:2 mslabel:"+videoStream.id,"a=ssrc:2 label:"+videoTracks[0].id,"a=ssrc:3 cname:localVideo","a=ssrc:3 msid:"+videoStream.id+" "+videoTracks[0].id,"a=ssrc:3 mslabel:"+videoStream.id,"a=ssrc:3 label:"+videoTracks[0].id];lines.push("");return lines.join("\n")}function WebRtcPeer(mode,options,callback){if(!(this instanceof WebRtcPeer)){return new WebRtcPeer(mode,options,callback)}WebRtcPeer.super_.call(this);if(options instanceof Function){callback=options;options=undefined}options=options||{};callback=(callback||noop).bind(this);var self=this;var localVideo=options.localVideo;var remoteVideo=options.remoteVideo;var videoStream=options.videoStream;var audioStream=options.audioStream;var mediaConstraints=options.mediaConstraints;var connectionConstraints=options.connectionConstraints;var pc=options.peerConnection;var sendSource=options.sendSource||"webcam";var dataChannelConfig=options.dataChannelConfig;var useDataChannels=options.dataChannels||false;var dataChannel;var guid=uuid.v4();var configuration=recursive({iceServers:freeice()},options.configuration);var onicecandidate=options.onicecandidate;if(onicecandidate)this.on("icecandidate",onicecandidate);var oncandidategatheringdone=options.oncandidategatheringdone;if(oncandidategatheringdone){this.on("candidategatheringdone",oncandidategatheringdone)}var simulcast=options.simulcast;var multistream=options.multistream;var interop=new sdpTranslator.Interop;var candidatesQueueOut=[];var candidategatheringdone=false;Object.defineProperties(this,{peerConnection:{get:function(){return pc}},id:{value:options.id||guid,writable:false},remoteVideo:{get:function(){return remoteVideo}},localVideo:{get:function(){return localVideo}},dataChannel:{get:function(){return dataChannel}},currentFrame:{get:function(){if(!remoteVideo)return;if(remoteVideo.readyStateUnifiedPlan",dumpSDP(localDescription))}callback(null,localDescription.sdp,self.processAnswer.bind(self))}).catch(callback)};this.getLocalSessionDescriptor=function(){return pc.localDescription};this.getRemoteSessionDescriptor=function(){return pc.remoteDescription};function setRemoteVideo(){if(remoteVideo){var stream=pc.getRemoteStreams()[0];var url=stream?URL.createObjectURL(stream):"";remoteVideo.pause();remoteVideo.src=url;remoteVideo.load();logger.debug("Remote URL:",url)}}this.showLocalVideo=function(){localVideo.src=URL.createObjectURL(videoStream);localVideo.muted=true};this.send=function(data){if(dataChannel&&dataChannel.readyState==="open"){dataChannel.send(data)}else{logger.warn("Trying to send data over a non-existing or closed data channel")}};this.processAnswer=function(sdpAnswer,callback){callback=(callback||noop).bind(this);var answer=new RTCSessionDescription({type:"answer",sdp:sdpAnswer});if(multistream&&usePlanB){var planBAnswer=interop.toPlanB(answer);logger.debug("asnwer::planB",dumpSDP(planBAnswer));answer=planBAnswer}logger.debug("SDP answer received, setting remote description");if(pc.signalingState==="closed"){return callback("PeerConnection is closed")}pc.setRemoteDescription(answer,function(){setRemoteVideo();callback()},callback)};this.processOffer=function(sdpOffer,callback){callback=callback.bind(this);var offer=new RTCSessionDescription({type:"offer",sdp:sdpOffer});if(multistream&&usePlanB){var planBOffer=interop.toPlanB(offer);logger.debug("offer::planB",dumpSDP(planBOffer));offer=planBOffer}logger.debug("SDP offer received, setting remote description");if(pc.signalingState==="closed"){return callback("PeerConnection is closed")}pc.setRemoteDescription(offer).then(function(){return setRemoteVideo()}).then(function(){return pc.createAnswer()}).then(function(answer){answer=mangleSdpToAddSimulcast(answer);logger.debug("Created SDP answer");return pc.setLocalDescription(answer)}).then(function(){var localDescription=pc.localDescription;if(multistream&&usePlanB){localDescription=interop.toUnifiedPlan(localDescription);logger.debug("answer::origPlanB->UnifiedPlan",dumpSDP(localDescription))}logger.debug("Local description set",localDescription.sdp);callback(null,localDescription.sdp)}).catch(callback)};function mangleSdpToAddSimulcast(answer){if(simulcast){if(browser.name==="Chrome"||browser.name==="Chromium"){logger.debug("Adding multicast info");answer=new RTCSessionDescription({type:answer.type,sdp:removeFIDFromOffer(answer.sdp)+getSimulcastInfo(videoStream)})}else{logger.warn("Simulcast is only available in Chrome browser.")}}return answer}function start(){if(pc.signalingState==="closed"){callback('The peer connection object is in "closed" state. This is most likely due to an invocation of the dispose method before accepting in the dialogue')}if(videoStream&&localVideo){self.showLocalVideo()}if(videoStream){pc.addStream(videoStream)}if(audioStream){pc.addStream(audioStream)}var browser=parser.getBrowser();if(mode==="sendonly"&&(browser.name==="Chrome"||browser.name==="Chromium")&&browser.major===39){mode="sendrecv"}callback()}if(mode!=="recvonly"&&!videoStream&&!audioStream){function getMedia(constraints){if(constraints===undefined){constraints=MEDIA_CONSTRAINTS}navigator.mediaDevices.getUserMedia(constraints).then(function(stream){videoStream=stream;start()}).catch(callback)}if(sendSource==="webcam"){getMedia(mediaConstraints)}else{getScreenConstraints(sendSource,function(error,constraints_){if(error)return callback(error);constraints=[mediaConstraints];constraints.unshift(constraints_);getMedia(recursive.apply(undefined,constraints))},guid)}}else{setTimeout(start,0)}this.on("_dispose",function(){if(localVideo){localVideo.pause();localVideo.src="";localVideo.load();localVideo.muted=false}if(remoteVideo){remoteVideo.pause();remoteVideo.src="";remoteVideo.load()}self.removeAllListeners();if(window.cancelChooseDesktopMedia!==undefined){window.cancelChooseDesktopMedia(guid)}})}inherits(WebRtcPeer,EventEmitter);function createEnableDescriptor(type){var method="get"+type+"Tracks";return{enumerable:true,get:function(){if(!this.peerConnection)return;var streams=this.peerConnection.getLocalStreams();if(!streams.length)return;for(var i=0,stream;stream=streams[i];i++){var tracks=stream[method]();for(var j=0,track;track=tracks[j];j++)if(!track.enabled)return false}return true},set:function(value){function trackSetEnable(track){track.enabled=value}this.peerConnection.getLocalStreams().forEach(function(stream){stream[method]().forEach(trackSetEnable)})}}}Object.defineProperties(WebRtcPeer.prototype,{enabled:{enumerable:true,get:function(){return this.audioEnabled&&this.videoEnabled},set:function(value){this.audioEnabled=this.videoEnabled=value}},audioEnabled:createEnableDescriptor("Audio"),videoEnabled:createEnableDescriptor("Video")});WebRtcPeer.prototype.getLocalStream=function(index){if(this.peerConnection){return this.peerConnection.getLocalStreams()[index||0]}};WebRtcPeer.prototype.getRemoteStream=function(index){if(this.peerConnection){return this.peerConnection.getRemoteStreams()[index||0]}};WebRtcPeer.prototype.dispose=function(){logger.debug("Disposing WebRtcPeer");var pc=this.peerConnection;var dc=this.dataChannel;try{if(dc){if(dc.signalingState==="closed")return;dc.close()}if(pc){if(pc.signalingState==="closed")return;pc.getLocalStreams().forEach(streamStop);pc.close()}}catch(err){logger.warn("Exception disposing webrtc peer "+err)}this.emit("_dispose")};function WebRtcPeerRecvonly(options,callback){if(!(this instanceof WebRtcPeerRecvonly)){return new WebRtcPeerRecvonly(options,callback)}WebRtcPeerRecvonly.super_.call(this,"recvonly",options,callback)}inherits(WebRtcPeerRecvonly,WebRtcPeer);function WebRtcPeerSendonly(options,callback){if(!(this instanceof WebRtcPeerSendonly)){return new WebRtcPeerSendonly(options,callback)}WebRtcPeerSendonly.super_.call(this,"sendonly",options,callback)}inherits(WebRtcPeerSendonly,WebRtcPeer);function WebRtcPeerSendrecv(options,callback){if(!(this instanceof WebRtcPeerSendrecv)){return new WebRtcPeerSendrecv(options,callback)}WebRtcPeerSendrecv.super_.call(this,"sendrecv",options,callback)}inherits(WebRtcPeerSendrecv,WebRtcPeer);function harkUtils(stream,options){return hark(stream,options)}exports.bufferizeCandidates=bufferizeCandidates;exports.WebRtcPeerRecvonly=WebRtcPeerRecvonly;exports.WebRtcPeerSendonly=WebRtcPeerSendonly;exports.WebRtcPeerSendrecv=WebRtcPeerSendrecv;exports.hark=harkUtils},{events:1,freeice:2,hark:5,inherits:6,merge:7,"sdp-translator":15,"ua-parser-js":19,uuid:21}],45:[function(require,module,exports){var WebRtcPeer=require("./WebRtcPeer");exports.WebRtcPeer=WebRtcPeer},{"./WebRtcPeer":44}],46:[function(require,module,exports){"use strict";Object.defineProperty(exports,"__esModule",{value:true});var OpenVidu_1=require("./OpenVidu");if(window){window["OpenVidu"]=OpenVidu_1.OpenVidu}},{"./OpenVidu":47}],47:[function(require,module,exports){"use strict";Object.defineProperty(exports,"__esModule",{value:true});var OpenViduInternal_1=require("../OpenViduInternal/OpenViduInternal");var Session_1=require("./Session");var Publisher_1=require("./Publisher");var adapter=require("webrtc-adapter");if(window){window["adapter"]=adapter}var OpenVidu=function(){function OpenVidu(){this.openVidu=new OpenViduInternal_1.OpenViduInternal;console.info("'OpenVidu' initialized")}OpenVidu.prototype.initSession=function(param1,param2){if(this.checkSystemRequirements()){if(typeof param2=="string"){return new Session_1.Session(this.openVidu.initSession(param2),this)}else{return new Session_1.Session(this.openVidu.initSession(param1),this)}}else{alert("Browser not supported")}};OpenVidu.prototype.initPublisher=function(parentId,cameraOptions,callback){if(this.checkSystemRequirements()){if(cameraOptions!=null){var cameraOptionsAux={sendAudio:cameraOptions.audio!=null?cameraOptions.audio:true,sendVideo:cameraOptions.video!=null?cameraOptions.video:true,activeAudio:cameraOptions.activeAudio!=null?cameraOptions.activeAudio:true,activeVideo:cameraOptions.activeVideo!=null?cameraOptions.activeVideo:true,data:true,mediaConstraints:this.openVidu.generateMediaConstraints(cameraOptions)};cameraOptions=cameraOptionsAux}else{cameraOptions={sendAudio:true,sendVideo:true,activeAudio:true,activeVideo:true,data:true,mediaConstraints:{audio:true,video:{width:{ideal:1280}}}}}var publisher=new Publisher_1.Publisher(this.openVidu.initPublisherTagged(parentId,cameraOptions,callback),parentId);console.info("'Publisher' initialized");return publisher}else{alert("Browser not supported")}};OpenVidu.prototype.checkSystemRequirements=function(){var browser=adapter.browserDetails.browser;var version=adapter.browserDetails.version;if(browser=="firefox"&&version==null){return 1}if(browser=="chrome"&&version>=28||browser=="edge"&&version>=12||browser=="firefox"&&version>=22){return 1}else{return 0}};OpenVidu.prototype.getDevices=function(callback){navigator.mediaDevices.enumerateDevices().then(function(deviceInfos){callback(null,deviceInfos)}).catch(function(error){console.error("Error getting devices",error);callback(error,null)})};OpenVidu.prototype.enableProdMode=function(){console.log=function(){};console.debug=function(){};console.info=function(){};console.warn=function(){}};return OpenVidu}();exports.OpenVidu=OpenVidu},{"../OpenViduInternal/OpenViduInternal":52,"./Publisher":48,"./Session":49,"webrtc-adapter":22}],48:[function(require,module,exports){"use strict";Object.defineProperty(exports,"__esModule",{value:true});var EventEmitter=require("wolfy87-eventemitter");var Publisher=function(){function Publisher(stream,parentId){var _this=this;this.ee=new EventEmitter;this.accessAllowed=false;this.stream=stream;this.stream.addEventListener("camera-access-changed",function(event){_this.accessAllowed=event.accessAllowed;if(_this.accessAllowed){_this.ee.emitEvent("accessAllowed")}else{_this.ee.emitEvent("accessDenied")}});if(document.getElementById(parentId)!=null){this.element=document.getElementById(parentId)}}Publisher.prototype.publishAudio=function(value){this.stream.getWebRtcPeer().audioEnabled=value};Publisher.prototype.publishVideo=function(value){this.stream.getWebRtcPeer().videoEnabled=value};Publisher.prototype.destroy=function(){this.session.unpublish(this);this.stream.dispose();this.stream.removeVideo(this.element);return this};Publisher.prototype.subscribeToRemote=function(){this.stream.subscribeToMyRemote()};Publisher.prototype.on=function(eventName,callback){var _this=this;this.ee.addListener(eventName,function(event){if(event){console.info("Event '"+eventName+"' triggered by 'Publisher'",event)}else{console.info("Event '"+eventName+"' triggered by 'Publisher'")}callback(event)});if(eventName=="videoElementCreated"){if(this.stream.isVideoELementCreated){this.ee.emitEvent("videoElementCreated",[{element:this.stream.getVideoElement()}])}else{this.stream.addOnceEventListener("video-element-created-by-stream",function(element){_this.id=element.id;_this.ee.emitEvent("videoElementCreated",[{element:element.element}])})}}if(eventName=="videoPlaying"){var video=this.stream.getVideoElement();if(!this.stream.displayMyRemote()&&video&&video.currentTime>0&&video.paused==false&&video.ended==false&&video.readyState==4){this.ee.emitEvent("videoPlaying",[{element:this.stream.getVideoElement()}])}else{this.stream.addOnceEventListener("video-is-playing",function(element){_this.ee.emitEvent("videoPlaying",[{element:element.element}])})}}if(eventName=="remoteVideoPlaying"){var video=this.stream.getVideoElement();if(this.stream.displayMyRemote()&&video&&video.currentTime>0&&video.paused==false&&video.ended==false&&video.readyState==4){this.ee.emitEvent("remoteVideoPlaying",[{element:this.stream.getVideoElement()}])}else{this.stream.addOnceEventListener("remote-video-is-playing",function(element){_this.ee.emitEvent("remoteVideoPlaying",[{element:element.element}])})}}if(eventName=="streamCreated"){if(this.stream.isReady){this.ee.emitEvent("streamCreated",[{stream:this.stream}])}else{this.stream.addEventListener("stream-created-by-publisher",function(){console.warn("Publisher emitting streamCreated");_this.ee.emitEvent("streamCreated",[{stream:_this.stream}])})}}if(eventName=="accessAllowed"){if(this.stream.accessIsAllowed){this.ee.emitEvent("accessAllowed")}else{this.stream.addEventListener("access-allowed-by-publisher",function(){_this.ee.emitEvent("accessAllowed")})}}if(eventName=="accessDenied"){if(this.stream.accessIsDenied){this.ee.emitEvent("accessDenied")}else{this.stream.addEventListener("access-denied-by-publisher",function(){_this.ee.emitEvent("accessDenied")})}}};return Publisher}();exports.Publisher=Publisher},{"wolfy87-eventemitter":34}],49:[function(require,module,exports){"use strict";Object.defineProperty(exports,"__esModule",{value:true});var Subscriber_1=require("./Subscriber");var EventEmitter=require("wolfy87-eventemitter");var Session=function(){function Session(session,openVidu){var _this=this;this.session=session;this.openVidu=openVidu;this.ee=new EventEmitter;this.sessionId=session.getSessionId();this.session.addEventListener("stream-destroyed-default",function(event){event.stream.removeVideo()});this.session.addEventListener("session-disconnected-default",function(){var s;for(var _i=0,_a=_this.openVidu.openVidu.getRemoteStreams();_i<_a.length;_i++){s=_a[_i];s.removeVideo()}if(_this.connection){for(var streamId in _this.connection.getStreams()){_this.connection.getStreams()[streamId].removeVideo()}}});this.session.addEventListener("update-connection-object",function(event){_this.connection=event.connection})}Session.prototype.connect=function(param1,param2,param3){if(param3){this.session.configure({sessionId:this.session.getSessionId(),participantId:param1,metadata:this.session.stringClientMetadata(param2),subscribeToStreams:false});this.session.connect(param1,param3)}else{this.session.configure({sessionId:this.session.getSessionId(),participantId:param1,metadata:"",subscribeToStreams:false});this.session.connect(param1,param2)}};Session.prototype.disconnect=function(){var _this=this;this.openVidu.openVidu.close(false);this.session.emitEvent("sessionDisconnected",[{preventDefault:function(){_this.session.removeEvent("session-disconnected-default")}}]);this.session.emitEvent("session-disconnected-default",[{}])};Session.prototype.publish=function(publisher){publisher.session=this;publisher.stream.publish()};Session.prototype.unpublish=function(publisher){this.session.unpublish(publisher.stream)};Session.prototype.on=function(eventName,callback){this.session.addEventListener(eventName,function(event){if(event){console.info("Event '"+eventName+"' triggered by 'Session'",event)}else{console.info("Event '"+eventName+"' triggered by 'Session'")}callback(event)})};Session.prototype.once=function(eventName,callback){this.session.addOnceEventListener(eventName,function(event){callback(event)})};Session.prototype.off=function(eventName,eventHandler){this.session.removeListener(eventName,eventHandler)};Session.prototype.subscribe=function(param1,param2,param3){this.session.subscribe(param1);var subscriber=new Subscriber_1.Subscriber(param1,param2);param1.playOnlyVideo(param2,null);return subscriber};Session.prototype.unsubscribe=function(subscriber){this.session.unsuscribe(subscriber.stream);subscriber.stream.removeVideo()};Session.prototype.onStreamCreated=function(callback){this.session.addEventListener("streamCreated",function(streamEvent){callback(streamEvent.stream)})};Session.prototype.onStreamDestroyed=function(callback){this.session.addEventListener("streamDestroyed",function(streamEvent){callback(streamEvent.stream)})};Session.prototype.onParticipantJoined=function(callback){this.session.addEventListener("participant-joined",function(participantEvent){callback(participantEvent.connection)})};Session.prototype.onParticipantLeft=function(callback){this.session.addEventListener("participant-left",function(participantEvent){callback(participantEvent.connection)})};Session.prototype.onParticipantPublished=function(callback){this.session.addEventListener("participant-published",function(participantEvent){callback(participantEvent.connection)})};Session.prototype.onParticipantEvicted=function(callback){this.session.addEventListener("participant-evicted",function(participantEvent){callback(participantEvent.connection)})};Session.prototype.onRoomClosed=function(callback){this.session.addEventListener("room-closed",function(roomEvent){callback(roomEvent.room)})};Session.prototype.onLostConnection=function(callback){this.session.addEventListener("lost-connection",function(roomEvent){callback(roomEvent.room)})};Session.prototype.onMediaError=function(callback){this.session.addEventListener("error-media",function(errorEvent){callback(errorEvent.error)})};return Session}();exports.Session=Session},{"./Subscriber":50,"wolfy87-eventemitter":34}],50:[function(require,module,exports){"use strict";Object.defineProperty(exports,"__esModule",{value:true});var EventEmitter=require("wolfy87-eventemitter");var Subscriber=function(){function Subscriber(stream,parentId){this.ee=new EventEmitter;this.stream=stream;if(document.getElementById(parentId)!=null){this.element=document.getElementById(parentId)}}Subscriber.prototype.on=function(eventName,callback){var _this=this;this.ee.addListener(eventName,function(event){if(event){console.info("Event '"+eventName+"' triggered by 'Subscriber'",event)}else{console.info("Event '"+eventName+"' triggered by 'Subscriber'")}callback(event)});if(eventName=="videoElementCreated"){if(this.stream.isVideoELementCreated){this.ee.emitEvent("videoElementCreated",[{element:this.stream.getVideoElement()}])}else{this.stream.addOnceEventListener("video-element-created-by-stream",function(element){console.warn("Subscriber emitting videoElementCreated");_this.id=element.id;_this.ee.emitEvent("videoElementCreated",[{element:element}])})}}if(eventName=="videoPlaying"){var video=this.stream.getVideoElement();if(!this.stream.displayMyRemote()&&video&&video.currentTime>0&&video.paused==false&&video.ended==false&&video.readyState==4){this.ee.emitEvent("videoPlaying",[{element:this.stream.getVideoElement()}])}else{this.stream.addOnceEventListener("video-is-playing",function(element){_this.ee.emitEvent("videoPlaying",[{element:element.element}])})}}};return Subscriber}();exports.Subscriber=Subscriber},{"wolfy87-eventemitter":34}],51:[function(require,module,exports){"use strict";Object.defineProperty(exports,"__esModule",{value:true});var Stream_1=require("./Stream");var Connection=function(){function Connection(openVidu,local,room,options){this.openVidu=openVidu;this.local=local;this.room=room;this.options=options;this.streams={};this.streamsOpts=[];console.info("'Connection' created ("+(local?"local":"remote")+")"+(local?"":", with 'connectionId' ["+(options?options.id:"")+"] "));if(options){this.connectionId=options.id;this.data=options.metadata;if(options.streams){this.initStreams(options)}}}Connection.prototype.addStream=function(stream){this.streams[stream.getIdInParticipant()]=stream;this.room.getStreams()[stream.getIdInParticipant()]=stream};Connection.prototype.getStreams=function(){return this.streams};Connection.prototype.dispose=function(){for(var key in this.streams){this.streams[key].dispose()}};Connection.prototype.sendIceCandidate=function(candidate){console.debug(this.local?"Local":"Remote","candidate for",this.connectionId,JSON.stringify(candidate));this.openVidu.sendRequest("onIceCandidate",{endpointName:this.connectionId,candidate:candidate.candidate,sdpMid:candidate.sdpMid,sdpMLineIndex:candidate.sdpMLineIndex},function(error,response){if(error){console.error("Error sending ICE candidate: "+JSON.stringify(error))}})};Connection.prototype.initStreams=function(options){for(var _i=0,_a=options.streams;_i<_a.length;_i++){var streamOptions=_a[_i];var streamOpts={id:streamOptions.id,connection:this,sendAudio:streamOptions.sendAudio,sendVideo:streamOptions.sendVideo,recvAudio:streamOptions.audioActive==undefined?true:streamOptions.audioActive,recvVideo:streamOptions.videoActive==undefined?true:streamOptions.videoActive,activeAudio:streamOptions.activeAudio,activeVideo:streamOptions.activeVideo,data:streamOptions.data,mediaConstraints:streamOptions.mediaConstraints};var stream=new Stream_1.Stream(this.openVidu,false,this.room,streamOpts);this.addStream(stream);this.streamsOpts.push(streamOpts)}console.info("Remote 'Connection' with 'connectionId' ["+this.connectionId+"] is now configured for receiving Streams with options: ",this.streamsOpts)};return Connection}();exports.Connection=Connection},{"./Stream":54}],52:[function(require,module,exports){"use strict";Object.defineProperty(exports,"__esModule",{value:true});var SessionInternal_1=require("./SessionInternal");var Stream_1=require("./Stream");var RpcBuilder=require("../KurentoUtils/kurento-jsonrpc");var OpenViduInternal=function(){function OpenViduInternal(){this.remoteStreams=[]}OpenViduInternal.prototype.initSession=function(sessionId){console.info("'Session' initialized with 'sessionId' ["+sessionId+"]");this.session=new SessionInternal_1.SessionInternal(this,sessionId);return this.session};OpenViduInternal.prototype.initPublisherTagged=function(parentId,cameraOptions,callback){var _this=this;this.getCamera(cameraOptions);if(callback==null){this.camera.requestCameraAccess(function(error,camera){if(error){console.error("Error accessing the camera",error)}else{_this.camera.setVideoElement(_this.cameraReady(camera,parentId))}});return this.camera}else{this.camera.requestCameraAccess(function(error,camera){if(error){callback(error)}else{_this.camera.setVideoElement(_this.cameraReady(camera,parentId));callback(undefined)}});return this.camera}};OpenViduInternal.prototype.cameraReady=function(camera,parentId){this.camera=camera;var videoElement=this.camera.playOnlyVideo(parentId,null);this.camera.emitStreamReadyEvent();return videoElement};OpenViduInternal.prototype.initPublisher=function(cameraOptions,callback){this.getCamera(cameraOptions);this.camera.requestCameraAccess(function(error,camera){if(error)callback(error);else callback(undefined)})};OpenViduInternal.prototype.getLocalStream=function(){return this.camera};OpenViduInternal.prototype.getRemoteStreams=function(){return this.remoteStreams};OpenViduInternal.prototype.getWsUri=function(){return this.wsUri};OpenViduInternal.prototype.setWsUri=function(wsUri){this.wsUri=wsUri};OpenViduInternal.prototype.getSecret=function(){return this.secret};OpenViduInternal.prototype.setSecret=function(secret){this.secret=secret};OpenViduInternal.prototype.getOpenViduServerURL=function(){return"https://"+this.wsUri.split("wss://")[1].split("/room")[0]};OpenViduInternal.prototype.getRoom=function(){return this.session};OpenViduInternal.prototype.connect=function(callback){this.callback=callback;this.initJsonRpcClient(this.wsUri)};OpenViduInternal.prototype.initJsonRpcClient=function(wsUri){var config={heartbeat:3e3,sendCloseMessage:false,ws:{uri:wsUri,useSockJS:false,onconnected:this.connectCallback.bind(this),ondisconnect:this.disconnectCallback.bind(this),onreconnecting:this.reconnectingCallback.bind(this),onreconnected:this.reconnectedCallback.bind(this)},rpc:{requestTimeout:15e3,participantJoined:this.onParticipantJoined.bind(this),participantPublished:this.onParticipantPublished.bind(this),participantUnpublished:this.onParticipantLeft.bind(this),participantLeft:this.onParticipantLeft.bind(this),participantEvicted:this.onParticipantEvicted.bind(this),sendMessage:this.onNewMessage.bind(this),iceCandidate:this.iceCandidateEvent.bind(this),mediaError:this.onMediaError.bind(this),custonNotification:this.customNotification.bind(this)}};this.jsonRpcClient=new RpcBuilder.clients.JsonRpcClient(config)};OpenViduInternal.prototype.customNotification=function(params){if(this.isRoomAvailable()){this.session.emitEvent("custom-message-received",[{params:params}])}};OpenViduInternal.prototype.connectCallback=function(error){if(error){this.callback(error)}else{this.callback(null)}};OpenViduInternal.prototype.isRoomAvailable=function(){if(this.session!==undefined&&this.session instanceof SessionInternal_1.SessionInternal){return true}else{console.warn("Room instance not found");return false}};OpenViduInternal.prototype.disconnectCallback=function(){console.warn("Websocket connection lost");if(this.isRoomAvailable()){this.session.onLostConnection()}else{alert("Connection error. Please reload page.")}};OpenViduInternal.prototype.reconnectingCallback=function(){console.warn("Websocket connection lost (reconnecting)");if(this.isRoomAvailable()){this.session.onLostConnection()}else{alert("Connection error. Please reload page.")}};OpenViduInternal.prototype.reconnectedCallback=function(){console.warn("Websocket reconnected")};OpenViduInternal.prototype.onParticipantJoined=function(params){if(this.isRoomAvailable()){this.session.onParticipantJoined(params)}};OpenViduInternal.prototype.onParticipantPublished=function(params){if(this.isRoomAvailable()){this.session.onParticipantPublished(params)}};OpenViduInternal.prototype.onParticipantLeft=function(params){if(this.isRoomAvailable()){this.session.onParticipantLeft(params)}};OpenViduInternal.prototype.onParticipantEvicted=function(params){if(this.isRoomAvailable()){this.session.onParticipantEvicted(params)}};OpenViduInternal.prototype.onNewMessage=function(params){if(this.isRoomAvailable()){this.session.onNewMessage(params)}};OpenViduInternal.prototype.iceCandidateEvent=function(params){if(this.isRoomAvailable()){this.session.recvIceCandidate(params)}};OpenViduInternal.prototype.onRoomClosed=function(params){if(this.isRoomAvailable()){this.session.onRoomClosed(params)}};OpenViduInternal.prototype.onMediaError=function(params){if(this.isRoomAvailable()){this.session.onMediaError(params)}};OpenViduInternal.prototype.setRpcParams=function(params){this.rpcParams=params};OpenViduInternal.prototype.sendRequest=function(method,params,callback){if(params&¶ms instanceof Function){callback=params;params=undefined}params=params||{};if(this.rpcParams&&this.rpcParams!==null&&this.rpcParams!==undefined){for(var index in this.rpcParams){if(this.rpcParams.hasOwnProperty(index)){params[index]=this.rpcParams[index];console.debug("RPC param added to request {"+index+": "+this.rpcParams[index]+"}")}}}console.debug('Sending request: {method:"'+method+'", params: '+JSON.stringify(params)+"}");this.jsonRpcClient.send(method,params,callback)};OpenViduInternal.prototype.close=function(forced){if(this.isRoomAvailable()){this.session.leave(forced,this.jsonRpcClient)}};OpenViduInternal.prototype.disconnectParticipant=function(stream){if(this.isRoomAvailable()){this.session.disconnect(stream)}};OpenViduInternal.prototype.getCamera=function(options){if(this.camera){return this.camera}options=options||{sendAudio:true,sendVideo:true,activeAudio:true,activeVideo:true,data:true,mediaConstraints:{audio:true,video:{width:{ideal:1280}}}};options.connection=this.session.getLocalParticipant();this.camera=new Stream_1.Stream(this,true,this.session,options);return this.camera};OpenViduInternal.prototype.sendMessage=function(room,user,message){this.sendRequest("sendMessage",{message:message,userMessage:user,roomMessage:room},function(error,response){if(error){console.error(error)}})};OpenViduInternal.prototype.sendCustomRequest=function(params,callback){this.sendRequest("customRequest",params,callback)};OpenViduInternal.prototype.toggleLocalVideoTrack=function(activate){this.getCamera().getWebRtcPeer().videoEnabled=activate};OpenViduInternal.prototype.toggleLocalAudioTrack=function(activate){this.getCamera().getWebRtcPeer().audioEnabled=activate};OpenViduInternal.prototype.publishLocalVideoAudio=function(){this.toggleLocalVideoTrack(true);this.toggleLocalAudioTrack(true)};OpenViduInternal.prototype.unpublishLocalVideoAudio=function(){this.toggleLocalVideoTrack(false);this.toggleLocalAudioTrack(false)};OpenViduInternal.prototype.generateMediaConstraints=function(cameraOptions){var mediaConstraints={audio:cameraOptions.audio,video:{}};if(!cameraOptions.video){mediaConstraints.video=false}else{var w=void 0,h=void 0;switch(cameraOptions.quality){case"LOW":w=320;h=240;break;case"MEDIUM":w=640;h=480;break;case"HIGH":w=1280;h=720;break;default:w=640;h=480}mediaConstraints.video["width"]={exact:w};mediaConstraints.video["height"]={exact:h}}return mediaConstraints};return OpenViduInternal}();exports.OpenViduInternal=OpenViduInternal},{"../KurentoUtils/kurento-jsonrpc":40,"./SessionInternal":53,"./Stream":54}],53:[function(require,module,exports){"use strict";Object.defineProperty(exports,"__esModule",{value:true});var Connection_1=require("./Connection");var EventEmitter=require("wolfy87-eventemitter");var SECRET_PARAM="?secret=";var SessionInternal=function(){function SessionInternal(openVidu,sessionId){this.openVidu=openVidu;this.ee=new EventEmitter;this.streams={};this.participants={};this.participantsSpeaking=[];this.connected=false;this.sessionId=this.getUrlWithoutSecret(sessionId);this.localParticipant=new Connection_1.Connection(this.openVidu,true,this);if(!this.openVidu.getWsUri()){this.processOpenViduUrl(sessionId)}}SessionInternal.prototype.processOpenViduUrl=function(url){this.openVidu.setSecret(this.getSecretFromUrl(url));this.openVidu.setWsUri(this.getFinalUrl(url))};SessionInternal.prototype.getSecretFromUrl=function(url){var secret="";if(url.indexOf(SECRET_PARAM)!==-1){secret=url.substring(url.lastIndexOf(SECRET_PARAM)+SECRET_PARAM.length,url.length)}return secret};SessionInternal.prototype.getUrlWithoutSecret=function(url){if(url.indexOf(SECRET_PARAM)!==-1){url=url.substring(0,url.lastIndexOf(SECRET_PARAM))}return url};SessionInternal.prototype.getFinalUrl=function(url){url=this.getUrlWithoutSecret(url).substring(0,url.lastIndexOf("/"))+"/room";if(url.indexOf(".ngrok.io")!==-1){url=url.replace("ws://","wss://");var regex=/\.ngrok\.io:\d+/;url=url.replace(regex,".ngrok.io")}else if(url.indexOf("localhost")!==-1||url.indexOf("127.0.0.1")!=-1){}return url};SessionInternal.prototype.connect=function(token,callback){var _this=this;this.openVidu.connect(function(error){if(error){callback("ERROR CONNECTING TO OPENVIDU")}else{if(!token){token=_this.randomToken()}var joinParams={token:token,session:_this.sessionId,metadata:_this.options.metadata,secret:_this.openVidu.getSecret(),dataChannels:false};if(_this.localParticipant){if(Object.keys(_this.localParticipant.getStreams()).some(function(streamId){return _this.streams[streamId].isDataChannelEnabled()})){joinParams.dataChannels=true}}_this.openVidu.sendRequest("joinRoom",joinParams,function(error,response){if(error){callback(error)}else{_this.connected=true;var exParticipants=response.value;_this.localParticipant.connectionId=response.id;_this.participants[response.id]=_this.localParticipant;var roomEvent={participants:new Array,streams:new Array};var length_1=exParticipants.length;for(var i=0;i0){_this.ee.emitEvent("update-main-speaker",[{participantId:_this.participantsSpeaking[_this.participantsSpeaking.length-1]}])}},this.updateSpeakerInterval)};SessionInternal.prototype.getLocalParticipant=function(){return this.localParticipant};SessionInternal.prototype.addEventListener=function(eventName,listener){this.ee.on(eventName,listener)};SessionInternal.prototype.addOnceEventListener=function(eventName,listener){this.ee.once(eventName,listener)};SessionInternal.prototype.removeListener=function(eventName,listener){this.ee.off(eventName,listener)};SessionInternal.prototype.removeEvent=function(eventName){this.ee.removeEvent(eventName)};SessionInternal.prototype.emitEvent=function(eventName,eventsArray){this.ee.emitEvent(eventName,eventsArray)};SessionInternal.prototype.subscribe=function(stream){stream.subscribe()};SessionInternal.prototype.unsuscribe=function(stream){console.info("Unsubscribing from "+stream.getId());this.openVidu.sendRequest("unsubscribeFromVideo",{sender:stream.getId()},function(error,response){if(error){console.error("Error unsubscribing from Subscriber",error)}else{console.info("Unsubscribed correctly from "+stream.getId())}})};SessionInternal.prototype.onParticipantPublished=function(options){options.metadata=this.participants[options.id].data;var connection=this.participants[options.id];if(connection){connection.options=options;connection.initStreams(options)}else{connection=new Connection_1.Connection(this.openVidu,false,this,options)}var pid=connection.connectionId;if(!(pid in this.participants)){console.debug("Remote Connection not found in connections list by its id ["+pid+"]")}else{console.debug("Remote Connection found in connections list by its id ["+pid+"]")}connection.creationTime=this.participants[pid].creationTime;this.participants[pid]=connection;this.ee.emitEvent("participant-published",[{connection:connection}]);var streams=connection.getStreams();for(var key in streams){var stream=streams[key];if(this.subscribeToStreams){stream.subscribe()}this.ee.emitEvent("streamCreated",[{stream:stream}]);this.openVidu.getRemoteStreams().push(stream)}};SessionInternal.prototype.onParticipantJoined=function(msg){var connection=new Connection_1.Connection(this.openVidu,false,this,msg);connection.creationTime=(new Date).getTime();var pid=connection.connectionId;if(!(pid in this.participants)){this.participants[pid]=connection}else{console.warn("Connection already exists in connections list with "+"the same connectionId, old:",this.participants[pid],", joined now:",connection);connection=this.participants[pid]}this.ee.emitEvent("participant-joined",[{connection:connection}]);this.ee.emitEvent("connectionCreated",[{connection:connection}])};SessionInternal.prototype.onParticipantLeft=function(msg){var _this=this;var connection=this.participants[msg.name];if(connection!==undefined){delete this.participants[msg.name];this.ee.emitEvent("participant-left",[{connection:connection}]);var streams=connection.getStreams();for(var key in streams){this.ee.emitEvent("streamDestroyed",[{stream:streams[key],preventDefault:function(){_this.ee.removeEvent("stream-destroyed-default")}}]);this.ee.emitEvent("stream-destroyed-default",[{stream:streams[key]}]);var index=this.openVidu.getRemoteStreams().indexOf(streams[key]);this.openVidu.getRemoteStreams().splice(index,1)}connection.dispose();this.ee.emitEvent("connectionDestroyed",[{connection:connection}])}else{console.warn("Participant "+msg.name+" unknown. Participants: "+JSON.stringify(this.participants))}};SessionInternal.prototype.onParticipantEvicted=function(msg){this.ee.emitEvent("participant-evicted",[{localParticipant:this.localParticipant}])};SessionInternal.prototype.onNewMessage=function(msg){console.info("New message: "+JSON.stringify(msg));var room=msg.room;var user=msg.user;var message=msg.message;if(user!==undefined){this.ee.emitEvent("newMessage",[{room:room,user:user,message:message}])}else{console.warn("User undefined in new message:",msg)}};SessionInternal.prototype.recvIceCandidate=function(msg){var candidate={candidate:msg.candidate,sdpMid:msg.sdpMid,sdpMLineIndex:msg.sdpMLineIndex};var connection=this.participants[msg.endpointName];if(!connection){console.error("Participant not found for endpoint "+msg.endpointName+". Ice candidate will be ignored.",candidate);return}var streams=connection.getStreams();var _loop_1=function(key){var stream=streams[key];stream.getWebRtcPeer().addIceCandidate(candidate,function(error){if(error){console.error("Error adding candidate for "+key+" stream of endpoint "+msg.endpointName+": "+error)}})};for(var key in streams){_loop_1(key)}};SessionInternal.prototype.onRoomClosed=function(msg){console.info("Room closed: "+JSON.stringify(msg));var room=msg.room;if(room!==undefined){this.ee.emitEvent("room-closed",[{room:room}])}else{console.warn("Room undefined in on room closed",msg)}};SessionInternal.prototype.onLostConnection=function(){if(!this.connected){console.warn("Not connected to room: if you are not debugging, this is probably a certificate error");if(window.confirm('If you are not debugging, this is probably a certificate error at "'+this.openVidu.getOpenViduServerURL()+'"\n\nClick OK to navigate and accept it')){location.assign(this.openVidu.getOpenViduServerURL()+"/accept-certificate")}return}console.warn("Lost connection in Session "+this.id);var room=this.id;if(room!==undefined){this.ee.emitEvent("lost-connection",[{room:room}])}else{console.warn("Room undefined when lost connection")}};SessionInternal.prototype.onMediaError=function(params){console.error("Media error: "+JSON.stringify(params));var error=params.error;if(error){this.ee.emitEvent("error-media",[{error:error}])}else{console.warn("Received undefined media error. Params:",params)}};SessionInternal.prototype.leave=function(forced,jsonRpcClient){forced=!!forced;console.info("Leaving Session (forced="+forced+")");if(this.connected&&!forced){this.openVidu.sendRequest("leaveRoom",function(error,response){if(error){console.error(error)}jsonRpcClient.close()})}else{jsonRpcClient.close()}this.connected=false;if(this.participants){for(var pid in this.participants){this.participants[pid].dispose();delete this.participants[pid]}}};SessionInternal.prototype.disconnect=function(stream){var connection=stream.getParticipant();if(!connection){console.error("Stream to disconnect has no participant",stream);return}delete this.participants[connection.connectionId];connection.dispose();if(connection===this.localParticipant){console.info("Unpublishing my media (I'm "+connection.connectionId+")");delete this.localParticipant;this.openVidu.sendRequest("unpublishVideo",function(error,response){if(error){console.error(error)}else{console.info("Media unpublished correctly")}})}else{this.unsuscribe(stream)}};SessionInternal.prototype.unpublish=function(stream){var connection=stream.getParticipant();if(!connection){console.error("Stream to disconnect has no participant",stream);return}if(connection===this.localParticipant){delete this.participants[connection.connectionId];connection.dispose();console.info("Unpublishing my media (I'm "+connection.connectionId+")");delete this.localParticipant;this.openVidu.sendRequest("unpublishVideo",function(error,response){if(error){console.error(error)}else{console.info("Media unpublished correctly")}})}};SessionInternal.prototype.getStreams=function(){return this.streams};SessionInternal.prototype.addParticipantSpeaking=function(participantId){this.participantsSpeaking.push(participantId)};SessionInternal.prototype.removeParticipantSpeaking=function(participantId){var pos=-1;for(var i=0;i=16){userName=userName.substring(0,16)+"..."}name.appendChild(document.createTextNode(userName));name.id="name-"+this.getId();name.className="name";name.title=this.getId();this.showSpinner(thumbnailId);return this.playOnlyVideo(container,thumbnailId)};Stream.prototype.getIdInParticipant=function(){return this.id};Stream.prototype.getParticipant=function(){return this.connection};Stream.prototype.getId=function(){return this.connection.connectionId+"_"+this.id};Stream.prototype.getRTCPeerConnection=function(){return this.getWebRtcPeer().peerConnection};Stream.prototype.requestCameraAccess=function(callback){var _this=this;this.connection.addStream(this);var constraints=this.mediaConstraints;this.userMediaHasVideo(function(hasVideo){if(!hasVideo){constraints.video=false;_this.sendVideo=false;_this.requestCameraAccesAux(constraints,callback)}else{_this.requestCameraAccesAux(constraints,callback)}})};Stream.prototype.requestCameraAccesAux=function(constraints,callback){var _this=this;navigator.mediaDevices.getUserMedia(constraints).then(function(userStream){_this.cameraAccessSuccess(userStream,callback)}).catch(function(error){_this.accessIsDenied=true;_this.accessIsAllowed=false;_this.ee.emitEvent("access-denied-by-publisher");console.error("Access denied",error);callback(error,_this)})};Stream.prototype.cameraAccessSuccess=function(userStream,callback){this.accessIsAllowed=true;this.accessIsDenied=false;this.ee.emitEvent("access-allowed-by-publisher");if(userStream.getAudioTracks()[0]!=null){userStream.getAudioTracks()[0].enabled=this.activeAudio}if(userStream.getVideoTracks()[0]!=null){userStream.getVideoTracks()[0].enabled=this.activeVideo}this.wrStream=userStream;this.emitSrcEvent(this.wrStream);callback(undefined,this)};Stream.prototype.userMediaHasVideo=function(callback){navigator.mediaDevices.enumerateDevices().then(function(mediaDevices){var videoInput=mediaDevices.filter(function(deviceInfo){return deviceInfo.kind==="videoinput"})[0];callback(videoInput!=null)})};Stream.prototype.publishVideoCallback=function(error,sdpOfferParam,wp){var _this=this;if(error){return console.error("(publish) SDP offer error: "+JSON.stringify(error))}console.debug("Sending SDP offer to publish as "+this.getId(),sdpOfferParam);this.openVidu.sendRequest("publishVideo",{sdpOffer:sdpOfferParam,doLoopback:this.displayMyRemote()||false,audioActive:this.sendAudio,videoActive:this.sendVideo},function(error,response){if(error){console.error("Error on publishVideo: "+JSON.stringify(error))}else{_this.processSdpAnswer(response.sdpAnswer);console.info("'Publisher' succesfully published to session")}})};Stream.prototype.startVideoCallback=function(error,sdpOfferParam,wp){var _this=this;if(error){return console.error("(subscribe) SDP offer error: "+JSON.stringify(error))}console.debug("Sending SDP offer to subscribe to "+this.getId(),sdpOfferParam);this.openVidu.sendRequest("receiveVideoFrom",{sender:this.getId(),sdpOffer:sdpOfferParam},function(error,response){if(error){console.error("Error on recvVideoFrom: "+JSON.stringify(error))}else{_this.processSdpAnswer(response.sdpAnswer)}})};Stream.prototype.initWebRtcPeer=function(sdpOfferCallback){var _this=this;if(this.local){var userMediaConstraints={audio:this.sendAudio,video:this.sendVideo};var options={videoStream:this.wrStream,mediaConstraints:userMediaConstraints,onicecandidate:this.connection.sendIceCandidate.bind(this.connection)};if(this.dataChannel){options.dataChannelConfig={id:this.getChannelName(),onopen:this.onDataChannelOpen,onclose:this.onDataChannelClosed};options.dataChannels=true}if(this.displayMyRemote()){this.wp=kurentoUtils.WebRtcPeer.WebRtcPeerSendrecv(options,function(error){if(error){return console.error(error)}_this.wp.generateOffer(sdpOfferCallback.bind(_this))})}else{this.wp=kurentoUtils.WebRtcPeer.WebRtcPeerSendonly(options,function(error){if(error){return console.error(error)}_this.wp.generateOffer(sdpOfferCallback.bind(_this))})}}else{var offerConstraints={audio:this.recvAudio,video:this.recvVideo};console.debug("'Session.subscribe(Stream)' called. Constraints of generate SDP offer",offerConstraints);var options={onicecandidate:this.connection.sendIceCandidate.bind(this.connection),mediaConstraints:offerConstraints};this.wp=kurentoUtils.WebRtcPeer.WebRtcPeerRecvonly(options,function(error){if(error){return console.error(error)}_this.wp.generateOffer(sdpOfferCallback.bind(_this))})}console.debug("Waiting for SDP offer to be generated ("+(this.local?"local":"remote")+" 'Stream': "+this.getId()+")")};Stream.prototype.publish=function(){var _this=this;if(this.isReady){this.initWebRtcPeer(this.publishVideoCallback)}else{this.ee.once("stream-ready",function(streamEvent){_this.publish()})}};Stream.prototype.subscribe=function(){this.initWebRtcPeer(this.startVideoCallback)};Stream.prototype.processSdpAnswer=function(sdpAnswer){var _this=this;var answer=new RTCSessionDescription({type:"answer",sdp:sdpAnswer});console.debug(this.getId()+": set peer connection with recvd SDP answer",sdpAnswer);var participantId=this.getId();var pc=this.wp.peerConnection;pc.setRemoteDescription(answer,function(){if(!_this.local||_this.displayMyRemote()){_this.wrStream=pc.getRemoteStreams()[0];console.debug("Peer remote stream",_this.wrStream);if(_this.wrStream!=undefined){_this.emitSrcEvent(_this.wrStream);_this.speechEvent=kurentoUtils.WebRtcPeer.hark(_this.wrStream,{threshold:_this.room.thresholdSpeaker});_this.speechEvent.on("speaking",function(){_this.room.addParticipantSpeaking(participantId);_this.room.emitEvent("stream-speaking",[{participantId:participantId}])});_this.speechEvent.on("stopped_speaking",function(){_this.room.removeParticipantSpeaking(participantId);_this.room.emitEvent("stream-stopped-speaking",[{participantId:participantId}])})}for(var _i=0,_a=_this.videoElements;_i<_a.length;_i++){var videoElement=_a[_i];var thumbnailId=videoElement.thumb;var video=videoElement.video;video.srcObject=_this.wrStream;video.onplaying=function(){if(_this.local&&_this.displayMyRemote()){console.info("Your own remote 'Stream' with id ["+_this.getId()+"] video is now playing");_this.ee.emitEvent("remote-video-is-playing",[{element:_this.video}])}else if(!_this.local&&!_this.displayMyRemote()){console.info("Remote 'Stream' with id ["+_this.getId()+"] video is now playing");_this.ee.emitEvent("video-is-playing",[{element:_this.video}])}}}_this.room.emitEvent("stream-subscribed",[{stream:_this}])}},function(error){console.error(_this.getId()+": Error setting SDP to the peer connection: "+JSON.stringify(error))})};Stream.prototype.unpublish=function(){if(this.wp){this.wp.dispose()}else{if(this.wrStream){this.wrStream.getAudioTracks().forEach(function(track){track.stop&&track.stop()});this.wrStream.getVideoTracks().forEach(function(track){track.stop&&track.stop()})}}if(this.speechEvent){this.speechEvent.stop()}console.info(this.getId()+": Stream '"+this.id+"' unpublished")};Stream.prototype.dispose=function(){function disposeElement(element){if(element&&element.parentNode){element.parentNode.removeChild(element)}}this.elements.forEach(function(e){return disposeElement(e)});disposeElement("progress-"+this.getId());if(this.wp){this.wp.dispose()}else{if(this.wrStream){this.wrStream.getAudioTracks().forEach(function(track){track.stop&&track.stop()});this.wrStream.getVideoTracks().forEach(function(track){track.stop&&track.stop()})}}if(this.speechEvent){this.speechEvent.stop()}console.info((this.local?"Local ":"Remote ")+"'Stream' with id ["+this.getId()+"]' has been succesfully disposed")};return Stream}();exports.Stream=Stream},{"../KurentoUtils/kurento-utils-js":45,"webrtc-adapter":22,"wolfy87-eventemitter":34}]},{},[46]); \ No newline at end of file +(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o0&&this._events[type].length>m){this._events[type].warned=true;console.error("(node) warning: possible EventEmitter memory "+"leak detected. %d listeners added. "+"Use emitter.setMaxListeners() to increase limit.",this._events[type].length);if(typeof console.trace==="function"){console.trace()}}}return this};EventEmitter.prototype.on=EventEmitter.prototype.addListener;EventEmitter.prototype.once=function(type,listener){if(!isFunction(listener))throw TypeError("listener must be a function");var fired=false;function g(){this.removeListener(type,g);if(!fired){fired=true;listener.apply(this,arguments)}}g.listener=listener;this.on(type,g);return this};EventEmitter.prototype.removeListener=function(type,listener){var list,position,length,i;if(!isFunction(listener))throw TypeError("listener must be a function");if(!this._events||!this._events[type])return this;list=this._events[type];length=list.length;position=-1;if(list===listener||isFunction(list.listener)&&list.listener===listener){delete this._events[type];if(this._events.removeListener)this.emit("removeListener",type,listener)}else if(isObject(list)){for(i=length;i-- >0;){if(list[i]===listener||list[i].listener&&list[i].listener===listener){position=i;break}}if(position<0)return this;if(list.length===1){list.length=0;delete this._events[type]}else{list.splice(position,1)}if(this._events.removeListener)this.emit("removeListener",type,listener)}return this};EventEmitter.prototype.removeAllListeners=function(type){var key,listeners;if(!this._events)return this;if(!this._events.removeListener){if(arguments.length===0)this._events={};else if(this._events[type])delete this._events[type];return this}if(arguments.length===0){for(key in this._events){if(key==="removeListener")continue;this.removeAllListeners(key)}this.removeAllListeners("removeListener");this._events={};return this}listeners=this._events[type];if(isFunction(listeners)){this.removeListener(type,listeners)}else if(listeners){while(listeners.length)this.removeListener(type,listeners[listeners.length-1])}delete this._events[type];return this};EventEmitter.prototype.listeners=function(type){var ret;if(!this._events||!this._events[type])ret=[];else if(isFunction(this._events[type]))ret=[this._events[type]];else ret=this._events[type].slice();return ret};EventEmitter.prototype.listenerCount=function(type){if(this._events){var evlistener=this._events[type];if(isFunction(evlistener))return 1;else if(evlistener)return evlistener.length}return 0};EventEmitter.listenerCount=function(emitter,type){return emitter.listenerCount(type)};function isFunction(arg){return typeof arg==="function"}function isNumber(arg){return typeof arg==="number"}function isObject(arg){return typeof arg==="object"&&arg!==null}function isUndefined(arg){return arg===void 0}},{}],2:[function(require,module,exports){"use strict";var normalice=require("normalice");var freeice=module.exports=function(opts){var servers={stun:(opts||{}).stun||require("./stun.json"),turn:(opts||{}).turn||require("./turn.json")};var stunCount=(opts||{}).stunCount||2;var turnCount=(opts||{}).turnCount||0;var selected;function getServers(type,count){var out=[];var input=[].concat(servers[type]);var idx;while(input.length&&out.lengthmaxVolume&&fftBins[i]<0){maxVolume=fftBins[i]}}return maxVolume}var audioContextType;if(typeof window!=="undefined"){audioContextType=window.AudioContext||window.webkitAudioContext}var audioContext=null;module.exports=function(stream,options){var harker=new WildEmitter;if(!audioContextType)return harker;var options=options||{},smoothing=options.smoothing||.1,interval=options.interval||50,threshold=options.threshold,play=options.play,history=options.history||10,running=true;if(!audioContext){audioContext=new audioContextType}var sourceNode,fftBins,analyser;analyser=audioContext.createAnalyser();analyser.fftSize=512;analyser.smoothingTimeConstant=smoothing;fftBins=new Float32Array(analyser.frequencyBinCount);if(stream.jquery)stream=stream[0];if(stream instanceof HTMLAudioElement||stream instanceof HTMLVideoElement){sourceNode=audioContext.createMediaElementSource(stream);if(typeof play==="undefined")play=true;threshold=threshold||-50}else{sourceNode=audioContext.createMediaStreamSource(stream);threshold=threshold||-50}sourceNode.connect(analyser);if(play)analyser.connect(audioContext.destination);harker.speaking=false;harker.setThreshold=function(t){threshold=t};harker.setInterval=function(i){interval=i};harker.stop=function(){running=false;harker.emit("volume_change",-100,threshold);if(harker.speaking){harker.speaking=false;harker.emit("stopped_speaking")}analyser.disconnect();sourceNode.disconnect()};harker.speakingHistory=[];for(var i=0;ithreshold&&!harker.speaking){for(var i=harker.speakingHistory.length-3;i=2){harker.speaking=true;harker.emit("speaking")}}else if(currentVolumethreshold));looper()},interval)};looper();return harker}},{wildemitter:31}],6:[function(require,module,exports){if(typeof Object.create==="function"){module.exports=function inherits(ctor,superCtor){ctor.super_=superCtor;ctor.prototype=Object.create(superCtor.prototype,{constructor:{value:ctor,enumerable:false,writable:true,configurable:true}})}}else{module.exports=function inherits(ctor,superCtor){ctor.super_=superCtor;var TempCtor=function(){};TempCtor.prototype=superCtor.prototype;ctor.prototype=new TempCtor;ctor.prototype.constructor=ctor}}},{}],7:[function(require,module,exports){(function(isNode){var Public=function(clone){return merge(clone===true,false,arguments)},publicName="merge";Public.recursive=function(clone){return merge(clone===true,true,arguments)};Public.clone=function(input){var output=input,type=typeOf(input),index,size;if(type==="array"){output=[];size=input.length;for(index=0;index1){url=parts[1];parts=parts[0].split(":");output.username=parts[0];output.credential=(input||{}).credential||parts[1]||""}output.url=protocol+url;output.urls=[output.url];return output}},{}],9:[function(require,module,exports){var grammar=module.exports={v:[{name:"version",reg:/^(\d*)$/}],o:[{name:"origin",reg:/^(\S*) (\d*) (\d*) (\S*) IP(\d) (\S*)/,names:["username","sessionId","sessionVersion","netType","ipVer","address"],format:"%s %s %d %s IP%d %s"}],s:[{name:"name"}],i:[{name:"description"}],u:[{name:"uri"}],e:[{name:"email"}],p:[{name:"phone"}],z:[{name:"timezones"}],r:[{name:"repeats"}],t:[{name:"timing",reg:/^(\d*) (\d*)/,names:["start","stop"],format:"%d %d"}],c:[{name:"connection",reg:/^IN IP(\d) (\S*)/,names:["version","ip"],format:"IN IP%d %s"}],b:[{push:"bandwidth",reg:/^(TIAS|AS|CT|RR|RS):(\d*)/,names:["type","limit"],format:"%s:%s"}],m:[{reg:/^(\w*) (\d*) ([\w\/]*)(?: (.*))?/,names:["type","port","protocol","payloads"],format:"%s %d %s %s"}],a:[{push:"rtp",reg:/^rtpmap:(\d*) ([\w\-]*)(?:\s*\/(\d*)(?:\s*\/(\S*))?)?/,names:["payload","codec","rate","encoding"],format:function(o){return o.encoding?"rtpmap:%d %s/%s/%s":o.rate?"rtpmap:%d %s/%s":"rtpmap:%d %s"}},{push:"fmtp",reg:/^fmtp:(\d*) ([\S| ]*)/,names:["payload","config"],format:"fmtp:%d %s"},{name:"control",reg:/^control:(.*)/,format:"control:%s"},{name:"rtcp",reg:/^rtcp:(\d*)(?: (\S*) IP(\d) (\S*))?/,names:["port","netType","ipVer","address"],format:function(o){return o.address!=null?"rtcp:%d %s IP%d %s":"rtcp:%d"}},{push:"rtcpFbTrrInt",reg:/^rtcp-fb:(\*|\d*) trr-int (\d*)/,names:["payload","value"],format:"rtcp-fb:%d trr-int %d"},{push:"rtcpFb",reg:/^rtcp-fb:(\*|\d*) ([\w-_]*)(?: ([\w-_]*))?/,names:["payload","type","subtype"],format:function(o){return o.subtype!=null?"rtcp-fb:%s %s %s":"rtcp-fb:%s %s"}},{push:"ext",reg:/^extmap:([\w_\/]*) (\S*)(?: (\S*))?/,names:["value","uri","config"],format:function(o){return o.config!=null?"extmap:%s %s %s":"extmap:%s %s"}},{push:"crypto",reg:/^crypto:(\d*) ([\w_]*) (\S*)(?: (\S*))?/,names:["id","suite","config","sessionConfig"],format:function(o){return o.sessionConfig!=null?"crypto:%d %s %s %s":"crypto:%d %s %s"}},{name:"setup",reg:/^setup:(\w*)/,format:"setup:%s"},{name:"mid",reg:/^mid:([^\s]*)/,format:"mid:%s"},{name:"msid",reg:/^msid:(.*)/,format:"msid:%s"},{name:"ptime",reg:/^ptime:(\d*)/,format:"ptime:%d"},{name:"maxptime",reg:/^maxptime:(\d*)/,format:"maxptime:%d"},{name:"direction",reg:/^(sendrecv|recvonly|sendonly|inactive)/},{name:"icelite",reg:/^(ice-lite)/},{name:"iceUfrag",reg:/^ice-ufrag:(\S*)/,format:"ice-ufrag:%s"},{name:"icePwd",reg:/^ice-pwd:(\S*)/,format:"ice-pwd:%s"},{name:"fingerprint",reg:/^fingerprint:(\S*) (\S*)/,names:["type","hash"],format:"fingerprint:%s %s"},{push:"candidates",reg:/^candidate:(\S*) (\d*) (\S*) (\d*) (\S*) (\d*) typ (\S*)(?: raddr (\S*) rport (\d*))?(?: tcptype (\S*))?(?: generation (\d*))?/,names:["foundation","component","transport","priority","ip","port","type","raddr","rport","tcptype","generation"],format:function(o){var str="candidate:%s %d %s %d %s %d typ %s";str+=o.raddr!=null?" raddr %s rport %d":"%v%v";str+=o.tcptype!=null?" tcptype %s":"%v";if(o.generation!=null){str+=" generation %d"}return str}},{name:"endOfCandidates",reg:/^(end-of-candidates)/},{name:"remoteCandidates",reg:/^remote-candidates:(.*)/,format:"remote-candidates:%s"},{name:"iceOptions",reg:/^ice-options:(\S*)/,format:"ice-options:%s"},{push:"ssrcs",reg:/^ssrc:(\d*) ([\w_]*):(.*)/,names:["id","attribute","value"],format:"ssrc:%d %s:%s"},{push:"ssrcGroups",reg:/^ssrc-group:(\w*) (.*)/,names:["semantics","ssrcs"],format:"ssrc-group:%s %s"},{name:"msidSemantic",reg:/^msid-semantic:\s?(\w*) (\S*)/,names:["semantic","token"],format:"msid-semantic: %s %s"},{push:"groups",reg:/^group:(\w*) (.*)/,names:["type","mids"],format:"group:%s %s"},{name:"rtcpMux",reg:/^(rtcp-mux)/},{name:"rtcpRsize",reg:/^(rtcp-rsize)/},{push:"invalid",names:["value"]}]};Object.keys(grammar).forEach(function(key){var objs=grammar[key];objs.forEach(function(obj){if(!obj.reg){obj.reg=/(.*)/}if(!obj.format){obj.format="%s"}})})},{}],10:[function(require,module,exports){var parser=require("./parser");var writer=require("./writer");exports.write=writer;exports.parse=parser.parse;exports.parseFmtpConfig=parser.parseFmtpConfig;exports.parsePayloads=parser.parsePayloads;exports.parseRemoteCandidates=parser.parseRemoteCandidates},{"./parser":11,"./writer":12}],11:[function(require,module,exports){var toIntIfInt=function(v){return String(Number(v))===v?Number(v):v};var attachProperties=function(match,location,names,rawName){if(rawName&&!names){location[rawName]=toIntIfInt(match[1])}else{for(var i=0;i=len){return x}var arg=args[i];i+=1;switch(x){case"%%":return"%";case"%s":return String(arg);case"%d":return Number(arg);case"%v":return""}})};var makeLine=function(type,obj,location){var str=obj.format instanceof Function?obj.format(obj.push?location:location[obj.name]):obj.format;var args=[type+"="+str];if(obj.names){for(var i=0;i3||!session.media.every(function(m){return["video","audio","data"].indexOf(m.mid)!==-1})){console.warn("This description does not look like Plan B.");return desc}var mids=[];session.media.forEach(function(m){mids.push(m.mid)});var hasBundle=false;if(typeof session.groups!=="undefined"&&Array.isArray(session.groups)){hasBundle=session.groups.every(function(g){return g.type!=="BUNDLE"||arrayEquals.apply(g.mids.sort(),[mids.sort()])})}if(!hasBundle){var mustBeBundle=false;session.media.forEach(function(m){if(m.direction!=="inactive"){mustBeBundle=true}});if(mustBeBundle){throw new Error("Cannot convert to Unified Plan because m-lines that"+" are not bundled were found.")}}var type;if(desc.type==="answer"){type="offer"}else if(desc.type==="offer"){type="answer"}else{throw new Error("Type '"+desc.type+"' not supported.")}var cached;if(typeof this.cache[type]!=="undefined"){cached=transform.parse(this.cache[type])}var recvonlySsrcs={audio:{},video:{}};var mid2ul={};var bIdx=0;var uIdx=0;var sources2ul={};var candidates;var iceUfrag;var icePwd;var fingerprint;var payloads={};var rtcpFb={};var rtp={};session.media.forEach(function(bLine){if((typeof bLine.rtcpMux!=="string"||bLine.rtcpMux!=="rtcp-mux")&&bLine.direction!=="inactive"){throw new Error("Cannot convert to Unified Plan because m-lines "+"without the rtcp-mux attribute were found.")}if(bLine.type==="application"){mid2ul[bLine.mid]=bLine;return}var sources=bLine.sources;var ssrcGroups=bLine.ssrcGroups;var port=bLine.port;if(typeof bLine.candidates!="undefined"){if(typeof candidates!="undefined"){candidates=candidates.concat(bLine.candidates)}else{candidates=bLine.candidates}}if(typeof iceUfrag!="undefined"&&typeof bLine.iceUfrag!="undefined"&&iceUfrag!=bLine.iceUfrag){throw new Error("Only BUNDLE supported, iceUfrag must be the same for all m-lines.\n"+"\tLast iceUfrag: "+iceUfrag+"\n"+"\tNew iceUfrag: "+bLine.iceUfrag)}if(typeof bLine.iceUfrag!="undefined"){iceUfrag=bLine.iceUfrag}if(typeof icePwd!="undefined"&&typeof bLine.icePwd!="undefined"&&icePwd!=bLine.icePwd){throw new Error("Only BUNDLE supported, icePwd must be the same for all m-lines.\n"+"\tLast icePwd: "+icePwd+"\n"+"\tNew icePwd: "+bLine.icePwd)}if(typeof bLine.icePwd!="undefined"){icePwd=bLine.icePwd}if(typeof fingerprint!="undefined"&&typeof bLine.fingerprint!="undefined"&&(fingerprint.type!=bLine.fingerprint.type||fingerprint.hash!=bLine.fingerprint.hash)){throw new Error("Only BUNDLE supported, fingerprint must be the same for all m-lines.\n"+"\tLast fingerprint: "+JSON.stringify(fingerprint)+"\n"+"\tNew fingerprint: "+JSON.stringify(bLine.fingerprint))}if(typeof bLine.fingerprint!="undefined"){fingerprint=bLine.fingerprint}payloads[bLine.type]=bLine.payloads;rtcpFb[bLine.type]=bLine.rtcpFb;rtp[bLine.type]=bLine.rtp;var ssrc2group={};if(typeof ssrcGroups!=="undefined"&&Array.isArray(ssrcGroups)){ssrcGroups.forEach(function(ssrcGroup){if(typeof ssrcGroup.ssrcs!=="undefined"&&Array.isArray(ssrcGroup.ssrcs)){ssrcGroup.ssrcs.forEach(function(ssrc){if(typeof ssrc2group[ssrc]==="undefined"){ssrc2group[ssrc]=[]}ssrc2group[ssrc].push(ssrcGroup)})}})}var ssrc2ml={};if(typeof sources==="object"){delete bLine.sources;delete bLine.ssrcGroups;delete bLine.candidates;delete bLine.iceUfrag;delete bLine.icePwd;delete bLine.fingerprint;delete bLine.port;delete bLine.mid;Object.keys(sources).forEach(function(ssrc){var uLine;if(desc.type==="offer"){if(!sources[ssrc].msid){recvonlySsrcs[bLine.type][ssrc]=sources[ssrc];return}}if(typeof ssrc2group[ssrc]!=="undefined"&&Array.isArray(ssrc2group[ssrc])){ssrc2group[ssrc].some(function(ssrcGroup){return ssrcGroup.ssrcs.some(function(related){if(typeof ssrc2ml[related]==="object"){uLine=ssrc2ml[related];return true}})})}if(typeof uLine==="object"){uLine.sources[ssrc]=sources[ssrc];delete sources[ssrc].msid}else{uLine=Object.create(bLine);ssrc2ml[ssrc]=uLine;if(typeof sources[ssrc].msid!=="undefined"){uLine.msid=sources[ssrc].msid;delete sources[ssrc].msid}uLine.sources={};uLine.sources[ssrc]=sources[ssrc];uLine.ssrcGroups=ssrc2group[ssrc];if(typeof cached!=="undefined"&&typeof cached.media!=="undefined"&&Array.isArray(cached.media)){cached.media.forEach(function(m){if(typeof m.sources==="object"){Object.keys(m.sources).forEach(function(s){if(s===ssrc){uLine.mid=m.mid}})}})}if(typeof uLine.mid==="undefined"){uLine.mid=[bLine.type,"-",ssrc].join("")}uLine.candidates=candidates;uLine.iceUfrag=iceUfrag;uLine.icePwd=icePwd;uLine.fingerprint=fingerprint;uLine.port=port;mid2ul[uLine.mid]=uLine;sources2ul[uIdx]=uLine.sources;self.cache.mlU2BMap[uIdx]=bIdx;if(typeof self.cache.mlB2UMap[bIdx]==="undefined"){self.cache.mlB2UMap[bIdx]=uIdx}uIdx++}})}else{var uLine=bLine;uLine.candidates=candidates;uLine.iceUfrag=iceUfrag;uLine.icePwd=icePwd;uLine.fingerprint=fingerprint;uLine.port=port;mid2ul[uLine.mid]=uLine;self.cache.mlU2BMap[uIdx]=bIdx;if(typeof self.cache.mlB2UMap[bIdx]==="undefined"){self.cache.mlB2UMap[bIdx]=uIdx}}bIdx++});session.media=[];mids=[];if(desc.type==="answer"){for(var i=0;i0){idx=self.getFirstSendingIndexFromAnswer(type);if(idx===null){for(var i=0;iidx){var mLine=session.media[idx];Object.keys(recvonlySsrcs[type]).forEach(function(ssrc){if(mLine.sources&&mLine.sources[ssrc]){console.warn("Replacing an existing SSRC.")}if(!mLine.sources){mLine.sources={}}mLine.sources[ssrc]=recvonlySsrcs[type][ssrc]})}});if(typeof session.groups!=="undefined"){session.groups.some(function(group){if(group.type==="BUNDLE"){group.mids=mids.join(" ");return true}})}session.msidSemantic={semantic:"WMS",token:"*"};var resStr=transform.write(session);this.cache[desc.type]=resStr;return new RTCSessionDescription({type:desc.type,sdp:resStr})}},{"./array-equals":13,"./transform":16}],16:[function(require,module,exports){var transform=require("sdp-transform");exports.write=function(session,opts){if(typeof session!=="undefined"&&typeof session.media!=="undefined"&&Array.isArray(session.media)){session.media.forEach(function(mLine){if(typeof mLine.sources!=="undefined"&&Object.keys(mLine.sources).length!==0){mLine.ssrcs=[];Object.keys(mLine.sources).forEach(function(ssrc){var source=mLine.sources[ssrc];Object.keys(source).forEach(function(attribute){mLine.ssrcs.push({id:ssrc,attribute:attribute,value:source[attribute]})})});delete mLine.sources}if(typeof mLine.ssrcGroups!=="undefined"&&Array.isArray(mLine.ssrcGroups)){mLine.ssrcGroups.forEach(function(ssrcGroup){if(typeof ssrcGroup.ssrcs!=="undefined"&&Array.isArray(ssrcGroup.ssrcs)){ssrcGroup.ssrcs=ssrcGroup.ssrcs.join(" ")}})}})}if(typeof session!=="undefined"&&typeof session.groups!=="undefined"&&Array.isArray(session.groups)){session.groups.forEach(function(g){if(typeof g.mids!=="undefined"&&Array.isArray(g.mids)){g.mids=g.mids.join(" ")}})}return transform.write(session,opts)};exports.parse=function(sdp){var session=transform.parse(sdp);if(typeof session!=="undefined"&&typeof session.media!=="undefined"&&Array.isArray(session.media)){session.media.forEach(function(mLine){if(typeof mLine.ssrcs!=="undefined"&&Array.isArray(mLine.ssrcs)){mLine.sources={};mLine.ssrcs.forEach(function(ssrc){if(!mLine.sources[ssrc.id])mLine.sources[ssrc.id]={};mLine.sources[ssrc.id][ssrc.attribute]=ssrc.value});delete mLine.ssrcs}if(typeof mLine.ssrcGroups!=="undefined"&&Array.isArray(mLine.ssrcGroups)){mLine.ssrcGroups.forEach(function(ssrcGroup){if(typeof ssrcGroup.ssrcs==="string"){ssrcGroup.ssrcs=ssrcGroup.ssrcs.split(" ")}})}})}if(typeof session!=="undefined"&&typeof session.groups!=="undefined"&&Array.isArray(session.groups)){session.groups.forEach(function(g){if(typeof g.mids==="string"){g.mids=g.mids.split(" ")}})}return session}},{"sdp-transform":10}],17:[function(require,module,exports){"use strict";var SDPUtils={};SDPUtils.generateIdentifier=function(){return Math.random().toString(36).substr(2,10)};SDPUtils.localCName=SDPUtils.generateIdentifier();SDPUtils.splitLines=function(blob){return blob.trim().split("\n").map(function(line){return line.trim()})};SDPUtils.splitSections=function(blob){var parts=blob.split("\nm=");return parts.map(function(part,index){return(index>0?"m="+part:part).trim()+"\r\n"})};SDPUtils.matchPrefix=function(blob,prefix){return SDPUtils.splitLines(blob).filter(function(line){return line.indexOf(prefix)===0})};SDPUtils.parseCandidate=function(line){var parts;if(line.indexOf("a=candidate:")===0){parts=line.substring(12).split(" ")}else{parts=line.substring(10).split(" ")}var candidate={foundation:parts[0],component:parts[1],protocol:parts[2].toLowerCase(),priority:parseInt(parts[3],10),ip:parts[4],port:parseInt(parts[5],10),type:parts[7]};for(var i=8;i0?parts[0].split("/")[1]:"sendrecv",uri:parts[1]}};SDPUtils.writeExtmap=function(headerExtension){return"a=extmap:"+(headerExtension.id||headerExtension.preferredId)+(headerExtension.direction&&headerExtension.direction!=="sendrecv"?"/"+headerExtension.direction:"")+" "+headerExtension.uri+"\r\n"};SDPUtils.parseFmtp=function(line){var parsed={};var kv;var parts=line.substr(line.indexOf(" ")+1).split(";");for(var j=0;j-1){parts.attribute=line.substr(sp+1,colon-sp-1);parts.value=line.substr(colon+1)}else{parts.attribute=line.substr(sp+1)}return parts};SDPUtils.getMid=function(mediaSection){var mid=SDPUtils.matchPrefix(mediaSection,"a=mid:")[0];if(mid){return mid.substr(6)}};SDPUtils.parseFingerprint=function(line){var parts=line.substr(14).split(" ");return{algorithm:parts[0].toLowerCase(),value:parts[1]}};SDPUtils.getDtlsParameters=function(mediaSection,sessionpart){var lines=SDPUtils.matchPrefix(mediaSection+sessionpart,"a=fingerprint:");return{role:"auto",fingerprints:lines.map(SDPUtils.parseFingerprint)}};SDPUtils.writeDtlsParameters=function(params,setupType){var sdp="a=setup:"+setupType+"\r\n";params.fingerprints.forEach(function(fp){sdp+="a=fingerprint:"+fp.algorithm+" "+fp.value+"\r\n"});return sdp};SDPUtils.getIceParameters=function(mediaSection,sessionpart){var lines=SDPUtils.splitLines(mediaSection);lines=lines.concat(SDPUtils.splitLines(sessionpart));var iceParameters={usernameFragment:lines.filter(function(line){return line.indexOf("a=ice-ufrag:")===0})[0].substr(12),password:lines.filter(function(line){return line.indexOf("a=ice-pwd:")===0})[0].substr(10)};return iceParameters};SDPUtils.writeIceParameters=function(params){return"a=ice-ufrag:"+params.usernameFragment+"\r\n"+"a=ice-pwd:"+params.password+"\r\n"};SDPUtils.parseRtpParameters=function(mediaSection){var description={codecs:[],headerExtensions:[],fecMechanisms:[],rtcp:[]};var lines=SDPUtils.splitLines(mediaSection);var mline=lines[0].split(" ");for(var i=3;i0?"9":"0";sdp+=" UDP/TLS/RTP/SAVPF ";sdp+=caps.codecs.map(function(codec){if(codec.preferredPayloadType!==undefined){return codec.preferredPayloadType}return codec.payloadType}).join(" ")+"\r\n";sdp+="c=IN IP4 0.0.0.0\r\n";sdp+="a=rtcp:9 IN IP4 0.0.0.0\r\n";caps.codecs.forEach(function(codec){sdp+=SDPUtils.writeRtpMap(codec);sdp+=SDPUtils.writeFmtp(codec);sdp+=SDPUtils.writeRtcpFb(codec)});var maxptime=0;caps.codecs.forEach(function(codec){if(codec.maxptime>maxptime){maxptime=codec.maxptime}});if(maxptime>0){sdp+="a=maxptime:"+maxptime+"\r\n"}sdp+="a=rtcp-mux\r\n";caps.headerExtensions.forEach(function(extension){sdp+=SDPUtils.writeExtmap(extension)});return sdp};SDPUtils.parseRtpEncodingParameters=function(mediaSection){var encodingParameters=[];var description=SDPUtils.parseRtpParameters(mediaSection);var hasRed=description.fecMechanisms.indexOf("RED")!==-1;var hasUlpfec=description.fecMechanisms.indexOf("ULPFEC")!==-1;var ssrcs=SDPUtils.matchPrefix(mediaSection,"a=ssrc:").map(function(line){return SDPUtils.parseSsrcMedia(line)}).filter(function(parts){return parts.attribute==="cname"});var primarySsrc=ssrcs.length>0&&ssrcs[0].ssrc;var secondarySsrc;var flows=SDPUtils.matchPrefix(mediaSection,"a=ssrc-group:FID").map(function(line){var parts=line.split(" ");parts.shift();return parts.map(function(part){return parseInt(part,10)})});if(flows.length>0&&flows[0].length>1&&flows[0][0]===primarySsrc){secondarySsrc=flows[0][1]}description.codecs.forEach(function(codec){if(codec.name.toUpperCase()==="RTX"&&codec.parameters.apt){var encParam={ssrc:primarySsrc,codecPayloadType:parseInt(codec.parameters.apt,10),rtx:{ssrc:secondarySsrc}};encodingParameters.push(encParam);if(hasRed){encParam=JSON.parse(JSON.stringify(encParam));encParam.fec={ssrc:secondarySsrc,mechanism:hasUlpfec?"red+ulpfec":"red"};encodingParameters.push(encParam)}}});if(encodingParameters.length===0&&primarySsrc){encodingParameters.push({ssrc:primarySsrc})}var bandwidth=SDPUtils.matchPrefix(mediaSection,"b=");if(bandwidth.length){if(bandwidth[0].indexOf("b=TIAS:")===0){bandwidth=parseInt(bandwidth[0].substr(7),10)}else if(bandwidth[0].indexOf("b=AS:")===0){bandwidth=parseInt(bandwidth[0].substr(5),10)}encodingParameters.forEach(function(params){params.maxBitrate=bandwidth})}return encodingParameters};SDPUtils.parseRtcpParameters=function(mediaSection){var rtcpParameters={};var cname;var remoteSsrc=SDPUtils.matchPrefix(mediaSection,"a=ssrc:").map(function(line){return SDPUtils.parseSsrcMedia(line)}).filter(function(obj){return obj.attribute==="cname"})[0];if(remoteSsrc){rtcpParameters.cname=remoteSsrc.value;rtcpParameters.ssrc=remoteSsrc.ssrc}var rsize=SDPUtils.matchPrefix(mediaSection,"a=rtcp-rsize");rtcpParameters.reducedSize=rsize.length>0;rtcpParameters.compound=rsize.length===0;var mux=SDPUtils.matchPrefix(mediaSection,"a=rtcp-mux");rtcpParameters.mux=mux.length>0;return rtcpParameters};SDPUtils.parseMsid=function(mediaSection){var parts;var spec=SDPUtils.matchPrefix(mediaSection,"a=msid:");if(spec.length===1){parts=spec[0].substr(7).split(" ");return{stream:parts[0],track:parts[1]}}var planB=SDPUtils.matchPrefix(mediaSection,"a=ssrc:").map(function(line){return SDPUtils.parseSsrcMedia(line)}).filter(function(parts){return parts.attribute==="msid"});if(planB.length>0){parts=planB[0].value.split(" ");return{stream:parts[0],track:parts[1]}}};SDPUtils.writeSessionBoilerplate=function(){return"v=0\r\n"+"o=thisisadapterortc 8169639915646943137 2 IN IP4 127.0.0.1\r\n"+"s=-\r\n"+"t=0 0\r\n"};SDPUtils.writeMediaSection=function(transceiver,caps,type,stream){var sdp=SDPUtils.writeRtpDescription(transceiver.kind,caps);sdp+=SDPUtils.writeIceParameters(transceiver.iceGatherer.getLocalParameters());sdp+=SDPUtils.writeDtlsParameters(transceiver.dtlsTransport.getLocalParameters(),type==="offer"?"actpass":"active");sdp+="a=mid:"+transceiver.mid+"\r\n";if(transceiver.direction){sdp+="a="+transceiver.direction+"\r\n"}else if(transceiver.rtpSender&&transceiver.rtpReceiver){sdp+="a=sendrecv\r\n"}else if(transceiver.rtpSender){sdp+="a=sendonly\r\n"}else if(transceiver.rtpReceiver){sdp+="a=recvonly\r\n"}else{sdp+="a=inactive\r\n"}if(transceiver.rtpSender){var msid="msid:"+stream.id+" "+transceiver.rtpSender.track.id+"\r\n";sdp+="a="+msid;sdp+="a=ssrc:"+transceiver.sendEncodingParameters[0].ssrc+" "+msid;if(transceiver.sendEncodingParameters[0].rtx){sdp+="a=ssrc:"+transceiver.sendEncodingParameters[0].rtx.ssrc+" "+msid;sdp+="a=ssrc-group:FID "+transceiver.sendEncodingParameters[0].ssrc+" "+transceiver.sendEncodingParameters[0].rtx.ssrc+"\r\n"}}sdp+="a=ssrc:"+transceiver.sendEncodingParameters[0].ssrc+" cname:"+SDPUtils.localCName+"\r\n";if(transceiver.rtpSender&&transceiver.sendEncodingParameters[0].rtx){sdp+="a=ssrc:"+transceiver.sendEncodingParameters[0].rtx.ssrc+" cname:"+SDPUtils.localCName+"\r\n"}return sdp};SDPUtils.getDirection=function(mediaSection,sessionpart){var lines=SDPUtils.splitLines(mediaSection);for(var i=0;i0){if(q.length==2){if(typeof q[1]==FUNC_TYPE){this[q[0]]=q[1].call(this,match)}else{this[q[0]]=q[1]}}else if(q.length==3){if(typeof q[1]===FUNC_TYPE&&!(q[1].exec&&q[1].test)){this[q[0]]=match?q[1].call(this,match,q[2]):undefined}else{this[q[0]]=match?match.replace(q[1],q[2]):undefined}}else if(q.length==4){this[q[0]]=match?q[3].call(this,match.replace(q[1],q[2])):undefined}}else{this[q]=match?match:undefined}}}}i+=2}},str:function(str,map){for(var i in map){if(typeof map[i]===OBJ_TYPE&&map[i].length>0){for(var j=0;j>>((i&3)<<3)&255}return _rnds}}module.exports=rng}).call(this,typeof global!=="undefined"?global:typeof self!=="undefined"?self:typeof window!=="undefined"?window:{})},{}],20:[function(require,module,exports){var _rng=require("./rng");var _byteToHex=[];var _hexToByte={};for(var i=0;i<256;i++){_byteToHex[i]=(i+256).toString(16).substr(1);_hexToByte[_byteToHex[i]]=i}function parse(s,buf,offset){var i=buf&&offset||0,ii=0;buf=buf||[];s.toLowerCase().replace(/[0-9a-f]{2}/g,function(oct){if(ii<16){buf[i+ii++]=_hexToByte[oct]}});while(ii<16){buf[i+ii++]=0}return buf}function unparse(buf,offset){var i=offset||0,bth=_byteToHex;return bth[buf[i++]]+bth[buf[i++]]+bth[buf[i++]]+bth[buf[i++]]+"-"+bth[buf[i++]]+bth[buf[i++]]+"-"+bth[buf[i++]]+bth[buf[i++]]+"-"+bth[buf[i++]]+bth[buf[i++]]+"-"+bth[buf[i++]]+bth[buf[i++]]+bth[buf[i++]]+bth[buf[i++]]+bth[buf[i++]]+bth[buf[i++]]}var _seedBytes=_rng();var _nodeId=[_seedBytes[0]|1,_seedBytes[1],_seedBytes[2],_seedBytes[3],_seedBytes[4],_seedBytes[5]];var _clockseq=(_seedBytes[6]<<8|_seedBytes[7])&16383;var _lastMSecs=0,_lastNSecs=0;function v1(options,buf,offset){var i=buf&&offset||0;var b=buf||[];options=options||{};var clockseq=options.clockseq!==undefined?options.clockseq:_clockseq;var msecs=options.msecs!==undefined?options.msecs:(new Date).getTime();var nsecs=options.nsecs!==undefined?options.nsecs:_lastNSecs+1;var dt=msecs-_lastMSecs+(nsecs-_lastNSecs)/1e4;if(dt<0&&options.clockseq===undefined){clockseq=clockseq+1&16383}if((dt<0||msecs>_lastMSecs)&&options.nsecs===undefined){nsecs=0}if(nsecs>=1e4){throw new Error("uuid.v1(): Can't create more than 10M uuids/sec")}_lastMSecs=msecs;_lastNSecs=nsecs;_clockseq=clockseq;msecs+=122192928e5;var tl=((msecs&268435455)*1e4+nsecs)%4294967296;b[i++]=tl>>>24&255;b[i++]=tl>>>16&255;b[i++]=tl>>>8&255;b[i++]=tl&255;var tmh=msecs/4294967296*1e4&268435455;b[i++]=tmh>>>8&255;b[i++]=tmh&255;b[i++]=tmh>>>24&15|16;b[i++]=tmh>>>16&255;b[i++]=clockseq>>>8|128;b[i++]=clockseq&255;var node=options.node||_nodeId;for(var n=0;n<6;n++){b[i+n]=node[n]}return buf?buf:unparse(b)}function v4(options,buf,offset){var i=buf&&offset||0;if(typeof options=="string"){buf=options=="binary"?new Array(16):null;options=null}options=options||{};var rnds=options.random||(options.rng||_rng)();rnds[6]=rnds[6]&15|64;rnds[8]=rnds[8]&63|128;if(buf){for(var ii=0;ii<16;ii++){buf[i+ii]=rnds[ii]}}return buf||unparse(rnds)}var uuid=v4;uuid.v1=v1;uuid.v4=v4;uuid.parse=parse;uuid.unparse=unparse;module.exports=uuid},{"./rng":19}],21:[function(require,module,exports){"use strict";(function(){var utils=require("./utils");var logging=utils.log;var browserDetails=utils.browserDetails;module.exports.browserDetails=browserDetails;module.exports.extractVersion=utils.extractVersion;module.exports.disableLog=utils.disableLog;var chromeShim=require("./chrome/chrome_shim")||null;var edgeShim=require("./edge/edge_shim")||null;var firefoxShim=require("./firefox/firefox_shim")||null;var safariShim=require("./safari/safari_shim")||null;switch(browserDetails.browser){case"chrome":if(!chromeShim||!chromeShim.shimPeerConnection){logging("Chrome shim is not included in this adapter release.");return}logging("adapter.js shimming chrome.");module.exports.browserShim=chromeShim;chromeShim.shimGetUserMedia();chromeShim.shimMediaStream();utils.shimCreateObjectURL();chromeShim.shimSourceObject();chromeShim.shimPeerConnection();chromeShim.shimOnTrack();chromeShim.shimGetSendersWithDtmf();break;case"firefox":if(!firefoxShim||!firefoxShim.shimPeerConnection){logging("Firefox shim is not included in this adapter release.");return}logging("adapter.js shimming firefox.");module.exports.browserShim=firefoxShim;firefoxShim.shimGetUserMedia();utils.shimCreateObjectURL();firefoxShim.shimSourceObject();firefoxShim.shimPeerConnection();firefoxShim.shimOnTrack();break;case"edge":if(!edgeShim||!edgeShim.shimPeerConnection){logging("MS edge shim is not included in this adapter release.");return}logging("adapter.js shimming edge.");module.exports.browserShim=edgeShim;edgeShim.shimGetUserMedia();utils.shimCreateObjectURL();edgeShim.shimPeerConnection();edgeShim.shimReplaceTrack();break;case"safari":if(!safariShim){logging("Safari shim is not included in this adapter release.");return}logging("adapter.js shimming safari.");module.exports.browserShim=safariShim;safariShim.shimOnAddStream();safariShim.shimGetUserMedia();break;default:logging("Unsupported browser!")}})()},{"./chrome/chrome_shim":22,"./edge/edge_shim":24,"./firefox/firefox_shim":27,"./safari/safari_shim":29,"./utils":30}],22:[function(require,module,exports){"use strict";var logging=require("../utils.js").log;var browserDetails=require("../utils.js").browserDetails;var chromeShim={shimMediaStream:function(){window.MediaStream=window.MediaStream||window.webkitMediaStream},shimOnTrack:function(){if(typeof window==="object"&&window.RTCPeerConnection&&!("ontrack"in window.RTCPeerConnection.prototype)){Object.defineProperty(window.RTCPeerConnection.prototype,"ontrack",{get:function(){return this._ontrack},set:function(f){var self=this;if(this._ontrack){this.removeEventListener("track",this._ontrack);this.removeEventListener("addstream",this._ontrackpoly)}this.addEventListener("track",this._ontrack=f);this.addEventListener("addstream",this._ontrackpoly=function(e){e.stream.addEventListener("addtrack",function(te){var event=new Event("track");event.track=te.track;event.receiver={track:te.track};event.streams=[e.stream];self.dispatchEvent(event)});e.stream.getTracks().forEach(function(track){var event=new Event("track");event.track=track;event.receiver={track:track};event.streams=[e.stream];this.dispatchEvent(event)}.bind(this))}.bind(this))}})}},shimGetSendersWithDtmf:function(){if(typeof window==="object"&&window.RTCPeerConnection&&!("getSenders"in RTCPeerConnection.prototype)&&"createDTMFSender"in RTCPeerConnection.prototype){RTCPeerConnection.prototype.getSenders=function(){return this._senders};var origAddStream=RTCPeerConnection.prototype.addStream;var origRemoveStream=RTCPeerConnection.prototype.removeStream;RTCPeerConnection.prototype.addStream=function(stream){var pc=this;pc._senders=pc._senders||[];origAddStream.apply(pc,[stream]);stream.getTracks().forEach(function(track){pc._senders.push({track:track,get dtmf(){if(this._dtmf===undefined){if(track.kind==="audio"){this._dtmf=pc.createDTMFSender(track)}else{this._dtmf=null}}return this._dtmf}})})};RTCPeerConnection.prototype.removeStream=function(stream){var pc=this;pc._senders=pc._senders||[];origRemoveStream.apply(pc,[stream]);stream.getTracks().forEach(function(track){var sender=pc._senders.find(function(s){return s.track===track});if(sender){pc._senders.splice(pc._senders.indexOf(sender),1)}})}}},shimSourceObject:function(){if(typeof window==="object"){if(window.HTMLMediaElement&&!("srcObject"in window.HTMLMediaElement.prototype)){Object.defineProperty(window.HTMLMediaElement.prototype,"srcObject",{get:function(){return this._srcObject},set:function(stream){var self=this;this._srcObject=stream;if(this.src){URL.revokeObjectURL(this.src)}if(!stream){this.src="";return undefined}this.src=URL.createObjectURL(stream);stream.addEventListener("addtrack",function(){if(self.src){URL.revokeObjectURL(self.src)}self.src=URL.createObjectURL(stream)});stream.addEventListener("removetrack",function(){if(self.src){URL.revokeObjectURL(self.src)}self.src=URL.createObjectURL(stream)})}})}}},shimPeerConnection:function(){if(!window.RTCPeerConnection){window.RTCPeerConnection=function(pcConfig,pcConstraints){logging("PeerConnection");if(pcConfig&&pcConfig.iceTransportPolicy){pcConfig.iceTransports=pcConfig.iceTransportPolicy}return new webkitRTCPeerConnection(pcConfig,pcConstraints)};window.RTCPeerConnection.prototype=webkitRTCPeerConnection.prototype;if(webkitRTCPeerConnection.generateCertificate){Object.defineProperty(window.RTCPeerConnection,"generateCertificate",{get:function(){return webkitRTCPeerConnection.generateCertificate}})}}else{var OrigPeerConnection=RTCPeerConnection;window.RTCPeerConnection=function(pcConfig,pcConstraints){if(pcConfig&&pcConfig.iceServers){var newIceServers=[];for(var i=0;i0&&typeof selector==="function"){return origGetStats.apply(this,arguments)}if(origGetStats.length===0&&(arguments.length===0||typeof arguments[0]!=="function")){return origGetStats.apply(this,[])}var fixChromeStats_=function(response){var standardReport={};var reports=response.result();reports.forEach(function(report){var standardStats={id:report.id,timestamp:report.timestamp,type:{localcandidate:"local-candidate",remotecandidate:"remote-candidate"}[report.type]||report.type};report.names().forEach(function(name){standardStats[name]=report.stat(name)});standardReport[standardStats.id]=standardStats});return standardReport};var makeMapStats=function(stats){return new Map(Object.keys(stats).map(function(key){return[key,stats[key]]}))};if(arguments.length>=2){var successCallbackWrapper_=function(response){args[1](makeMapStats(fixChromeStats_(response)))};return origGetStats.apply(this,[successCallbackWrapper_,arguments[0]])}return new Promise(function(resolve,reject){origGetStats.apply(self,[function(response){resolve(makeMapStats(fixChromeStats_(response)))},reject])}).then(successCallback,errorCallback)};if(browserDetails.version<51){["setLocalDescription","setRemoteDescription","addIceCandidate"].forEach(function(method){var nativeMethod=RTCPeerConnection.prototype[method];RTCPeerConnection.prototype[method]=function(){var args=arguments;var self=this;var promise=new Promise(function(resolve,reject){nativeMethod.apply(self,[args[0],resolve,reject])});if(args.length<2){return promise}return promise.then(function(){args[1].apply(null,[])},function(err){if(args.length>=3){args[2].apply(null,[err])}})}})}if(browserDetails.version<52){["createOffer","createAnswer"].forEach(function(method){var nativeMethod=RTCPeerConnection.prototype[method];RTCPeerConnection.prototype[method]=function(){var self=this;if(arguments.length<1||arguments.length===1&&typeof arguments[0]==="object"){var opts=arguments.length===1?arguments[0]:undefined;return new Promise(function(resolve,reject){nativeMethod.apply(self,[resolve,reject,opts])})}return nativeMethod.apply(this,arguments)}})}["setLocalDescription","setRemoteDescription","addIceCandidate"].forEach(function(method){var nativeMethod=RTCPeerConnection.prototype[method];RTCPeerConnection.prototype[method]=function(){arguments[0]=new(method==="addIceCandidate"?RTCIceCandidate:RTCSessionDescription)(arguments[0]);return nativeMethod.apply(this,arguments)}});var nativeAddIceCandidate=RTCPeerConnection.prototype.addIceCandidate;RTCPeerConnection.prototype.addIceCandidate=function(){if(!arguments[0]){if(arguments[1]){arguments[1].apply(null)}return Promise.resolve()}return nativeAddIceCandidate.apply(this,arguments)}}};module.exports={shimMediaStream:chromeShim.shimMediaStream,shimOnTrack:chromeShim.shimOnTrack,shimGetSendersWithDtmf:chromeShim.shimGetSendersWithDtmf,shimSourceObject:chromeShim.shimSourceObject,shimPeerConnection:chromeShim.shimPeerConnection,shimGetUserMedia:require("./getusermedia")}},{"../utils.js":30,"./getusermedia":23}],23:[function(require,module,exports){"use strict";var logging=require("../utils.js").log;var browserDetails=require("../utils.js").browserDetails;module.exports=function(){var constraintsToChrome_=function(c){if(typeof c!=="object"||c.mandatory||c.optional){return c}var cc={};Object.keys(c).forEach(function(key){if(key==="require"||key==="advanced"||key==="mediaSource"){return}var r=typeof c[key]==="object"?c[key]:{ideal:c[key]};if(r.exact!==undefined&&typeof r.exact==="number"){r.min=r.max=r.exact}var oldname_=function(prefix,name){if(prefix){return prefix+name.charAt(0).toUpperCase()+name.slice(1)}return name==="deviceId"?"sourceId":name};if(r.ideal!==undefined){cc.optional=cc.optional||[];var oc={};if(typeof r.ideal==="number"){oc[oldname_("min",key)]=r.ideal;cc.optional.push(oc);oc={};oc[oldname_("max",key)]=r.ideal;cc.optional.push(oc)}else{oc[oldname_("",key)]=r.ideal;cc.optional.push(oc)}}if(r.exact!==undefined&&typeof r.exact!=="number"){cc.mandatory=cc.mandatory||{};cc.mandatory[oldname_("",key)]=r.exact}else{["min","max"].forEach(function(mix){if(r[mix]!==undefined){cc.mandatory=cc.mandatory||{};cc.mandatory[oldname_(mix,key)]=r[mix]}})}});if(c.advanced){cc.optional=(cc.optional||[]).concat(c.advanced)}return cc};var shimConstraints_=function(constraints,func){constraints=JSON.parse(JSON.stringify(constraints));if(constraints&&constraints.audio){constraints.audio=constraintsToChrome_(constraints.audio)}if(constraints&&typeof constraints.video==="object"){var face=constraints.video.facingMode;face=face&&(typeof face==="object"?face:{ideal:face});var getSupportedFacingModeLies=browserDetails.version<61;if(face&&(face.exact==="user"||face.exact==="environment"||face.ideal==="user"||face.ideal==="environment")&&!(navigator.mediaDevices.getSupportedConstraints&&navigator.mediaDevices.getSupportedConstraints().facingMode&&!getSupportedFacingModeLies)){delete constraints.video.facingMode;var matches;if(face.exact==="environment"||face.ideal==="environment"){matches=["back","rear"]}else if(face.exact==="user"||face.ideal==="user"){matches=["front"]}if(matches){return navigator.mediaDevices.enumerateDevices().then(function(devices){devices=devices.filter(function(d){return d.kind==="videoinput"});var dev=devices.find(function(d){return matches.some(function(match){return d.label.toLowerCase().indexOf(match)!==-1})});if(!dev&&devices.length&&matches.indexOf("back")!==-1){dev=devices[devices.length-1]}if(dev){constraints.video.deviceId=face.exact?{exact:dev.deviceId}:{ideal:dev.deviceId}}constraints.video=constraintsToChrome_(constraints.video);logging("chrome: "+JSON.stringify(constraints));return func(constraints)})}}constraints.video=constraintsToChrome_(constraints.video)}logging("chrome: "+JSON.stringify(constraints));return func(constraints)};var shimError_=function(e){return{name:{PermissionDeniedError:"NotAllowedError",ConstraintNotSatisfiedError:"OverconstrainedError"}[e.name]||e.name,message:e.message,constraint:e.constraintName,toString:function(){return this.name+(this.message&&": ")+this.message}}};var getUserMedia_=function(constraints,onSuccess,onError){shimConstraints_(constraints,function(c){navigator.webkitGetUserMedia(c,onSuccess,function(e){onError(shimError_(e))})})};navigator.getUserMedia=getUserMedia_;var getUserMediaPromise_=function(constraints){return new Promise(function(resolve,reject){navigator.getUserMedia(constraints,resolve,reject)})};if(!navigator.mediaDevices){navigator.mediaDevices={getUserMedia:getUserMediaPromise_,enumerateDevices:function(){return new Promise(function(resolve){var kinds={audio:"audioinput",video:"videoinput"};return MediaStreamTrack.getSources(function(devices){resolve(devices.map(function(device){return{label:device.label,kind:kinds[device.kind],deviceId:device.id,groupId:""}}))})})},getSupportedConstraints:function(){return{deviceId:true,echoCancellation:true,facingMode:true,frameRate:true,height:true,width:true}}}}if(!navigator.mediaDevices.getUserMedia){navigator.mediaDevices.getUserMedia=function(constraints){return getUserMediaPromise_(constraints)}}else{var origGetUserMedia=navigator.mediaDevices.getUserMedia.bind(navigator.mediaDevices);navigator.mediaDevices.getUserMedia=function(cs){return shimConstraints_(cs,function(c){return origGetUserMedia(c).then(function(stream){if(c.audio&&!stream.getAudioTracks().length||c.video&&!stream.getVideoTracks().length){stream.getTracks().forEach(function(track){track.stop()});throw new DOMException("","NotFoundError")}return stream},function(e){return Promise.reject(shimError_(e))})})}}if(typeof navigator.mediaDevices.addEventListener==="undefined"){navigator.mediaDevices.addEventListener=function(){logging("Dummy mediaDevices.addEventListener called.")}}if(typeof navigator.mediaDevices.removeEventListener==="undefined"){navigator.mediaDevices.removeEventListener=function(){logging("Dummy mediaDevices.removeEventListener called.")}}}},{"../utils.js":30}],24:[function(require,module,exports){"use strict";var browserDetails=require("../utils").browserDetails;var shimRTCPeerConnection=require("./rtcpeerconnection_shim");module.exports={shimGetUserMedia:require("./getusermedia"),shimPeerConnection:function(){if(window.RTCIceGatherer){if(!window.RTCIceCandidate){window.RTCIceCandidate=function(args){return args}}if(!window.RTCSessionDescription){window.RTCSessionDescription=function(args){return args}}if(browserDetails.version<15025){var origMSTEnabled=Object.getOwnPropertyDescriptor(MediaStreamTrack.prototype,"enabled");Object.defineProperty(MediaStreamTrack.prototype,"enabled",{set:function(value){origMSTEnabled.set.call(this,value);var ev=new Event("enabled");ev.enabled=value;this.dispatchEvent(ev)}})}}window.RTCPeerConnection=shimRTCPeerConnection(browserDetails.version)},shimReplaceTrack:function(){if(window.RTCRtpSender&&!("replaceTrack"in RTCRtpSender.prototype)){RTCRtpSender.prototype.replaceTrack=RTCRtpSender.prototype.setTrack}}}},{"../utils":30,"./getusermedia":25,"./rtcpeerconnection_shim":26}],25:[function(require,module,exports){"use strict";module.exports=function(){var shimError_=function(e){return{name:{PermissionDeniedError:"NotAllowedError"}[e.name]||e.name,message:e.message,constraint:e.constraint,toString:function(){return this.name}}};var origGetUserMedia=navigator.mediaDevices.getUserMedia.bind(navigator.mediaDevices);navigator.mediaDevices.getUserMedia=function(c){return origGetUserMedia(c).catch(function(e){return Promise.reject(shimError_(e))})}}},{}],26:[function(require,module,exports){"use strict";var SDPUtils=require("sdp");function sortTracks(tracks){var audioTracks=tracks.filter(function(track){return track.kind==="audio"});var videoTracks=tracks.filter(function(track){return track.kind==="video"});tracks=[];while(audioTracks.length||videoTracks.length){if(audioTracks.length){tracks.push(audioTracks.shift())}if(videoTracks.length){tracks.push(videoTracks.shift())}}return tracks}function filterIceServers(iceServers,edgeVersion){var hasTurn=false;iceServers=JSON.parse(JSON.stringify(iceServers));return iceServers.filter(function(server){if(server&&(server.urls||server.url)){var urls=server.urls||server.url;if(server.url&&!server.urls){console.warn("RTCIceServer.url is deprecated! Use urls instead.")}var isString=typeof urls==="string";if(isString){urls=[urls]}urls=urls.filter(function(url){var validTurn=url.indexOf("turn:")===0&&url.indexOf("transport=udp")!==-1&&url.indexOf("turn:[")===-1&&!hasTurn;if(validTurn){hasTurn=true;return true}return url.indexOf("stun:")===0&&edgeVersion>=14393});delete server.url;server.urls=isString?urls[0]:urls;return!!urls.length}return false})}module.exports=function(edgeVersion){var RTCPeerConnection=function(config){var self=this;var _eventTarget=document.createDocumentFragment();["addEventListener","removeEventListener","dispatchEvent"].forEach(function(method){self[method]=_eventTarget[method].bind(_eventTarget)});this.onicecandidate=null;this.onaddstream=null;this.ontrack=null;this.onremovestream=null;this.onsignalingstatechange=null;this.oniceconnectionstatechange=null;this.onicegatheringstatechange=null;this.onnegotiationneeded=null;this.ondatachannel=null;this.canTrickleIceCandidates=null;this.localStreams=[];this.remoteStreams=[];this.getLocalStreams=function(){return self.localStreams};this.getRemoteStreams=function(){return self.remoteStreams};this.localDescription=new RTCSessionDescription({type:"",sdp:""});this.remoteDescription=new RTCSessionDescription({type:"",sdp:""});this.signalingState="stable";this.iceConnectionState="new";this.iceGatheringState="new";this.iceOptions={gatherPolicy:"all",iceServers:[]};if(config&&config.iceTransportPolicy){switch(config.iceTransportPolicy){case"all":case"relay":this.iceOptions.gatherPolicy=config.iceTransportPolicy;break;default:break}}this.usingBundle=config&&config.bundlePolicy==="max-bundle";if(config&&config.iceServers){this.iceOptions.iceServers=filterIceServers(config.iceServers,edgeVersion)}this._config=config||{};this.transceivers=[];this._localIceCandidatesBuffer=[]};RTCPeerConnection.prototype._emitGatheringStateChange=function(){var event=new Event("icegatheringstatechange");this.dispatchEvent(event);if(this.onicegatheringstatechange!==null){this.onicegatheringstatechange(event)}};RTCPeerConnection.prototype._emitBufferedCandidates=function(){var self=this;var sections=SDPUtils.splitSections(self.localDescription.sdp);this._localIceCandidatesBuffer.forEach(function(event){var end=!event.candidate||Object.keys(event.candidate).length===0;if(end){for(var j=1;j=15025){this.localStreams.push(stream)}else{var clonedStream=stream.clone();stream.getTracks().forEach(function(track,idx){var clonedTrack=clonedStream.getTracks()[idx];track.addEventListener("enabled",function(event){clonedTrack.enabled=event.enabled})});this.localStreams.push(clonedStream)}this._maybeFireNegotiationNeeded()};RTCPeerConnection.prototype.removeStream=function(stream){var idx=this.localStreams.indexOf(stream);if(idx>-1){this.localStreams.splice(idx,1);this._maybeFireNegotiationNeeded()}};RTCPeerConnection.prototype.getSenders=function(){return this.transceivers.filter(function(transceiver){return!!transceiver.rtpSender}).map(function(transceiver){return transceiver.rtpSender})};RTCPeerConnection.prototype.getReceivers=function(){return this.transceivers.filter(function(transceiver){return!!transceiver.rtpReceiver}).map(function(transceiver){return transceiver.rtpReceiver})};RTCPeerConnection.prototype._getCommonCapabilities=function(localCapabilities,remoteCapabilities){var commonCapabilities={codecs:[],headerExtensions:[],fecMechanisms:[]};var findCodecByPayloadType=function(pt,codecs){pt=parseInt(pt,10);for(var i=0;i0;sections.forEach(function(mediaSection,sdpMLineIndex){var transceiver=self.transceivers[sdpMLineIndex];var iceGatherer=transceiver.iceGatherer;var iceTransport=transceiver.iceTransport;var dtlsTransport=transceiver.dtlsTransport;var localCapabilities=transceiver.localCapabilities;var remoteCapabilities=transceiver.remoteCapabilities;var rejected=mediaSection.split("\n",1)[0].split(" ",2)[1]==="0";if(!rejected&&!transceiver.isDatachannel){var remoteIceParameters=SDPUtils.getIceParameters(mediaSection,sessionpart);var remoteDtlsParameters=SDPUtils.getDtlsParameters(mediaSection,sessionpart);if(isIceLite){remoteDtlsParameters.role="server"}if(!self.usingBundle||sdpMLineIndex===0){iceTransport.start(iceGatherer,remoteIceParameters,isIceLite?"controlling":"controlled");dtlsTransport.start(remoteDtlsParameters)}var params=self._getCommonCapabilities(localCapabilities,remoteCapabilities);self._transceive(transceiver,params.codecs.length>0,false)}})}this.localDescription={type:description.type,sdp:description.sdp};switch(description.type){case"offer":this._updateSignalingState("have-local-offer");break;case"answer":this._updateSignalingState("stable");break;default:throw new TypeError('unsupported type "'+description.type+'"')}var hasCallback=arguments.length>1&&typeof arguments[1]==="function";if(hasCallback){var cb=arguments[1];window.setTimeout(function(){cb();if(self.iceGatheringState==="new"){self.iceGatheringState="gathering";self._emitGatheringStateChange()}self._emitBufferedCandidates()},0)}var p=Promise.resolve();p.then(function(){if(!hasCallback){if(self.iceGatheringState==="new"){self.iceGatheringState="gathering";self._emitGatheringStateChange()}window.setTimeout(self._emitBufferedCandidates.bind(self),500)}});return p};RTCPeerConnection.prototype.setRemoteDescription=function(description){var self=this;var streams={};var receiverList=[];var sections=SDPUtils.splitSections(description.sdp);var sessionpart=sections.shift();var isIceLite=SDPUtils.matchPrefix(sessionpart,"a=ice-lite").length>0;var usingBundle=SDPUtils.matchPrefix(sessionpart,"a=group:BUNDLE ").length>0;var iceOptions=SDPUtils.matchPrefix(sessionpart,"a=ice-options:")[0];if(iceOptions){this.canTrickleIceCandidates=iceOptions.substr(14).split(" ").indexOf("trickle")>=0}else{this.canTrickleIceCandidates=false}sections.forEach(function(mediaSection,sdpMLineIndex){var lines=SDPUtils.splitLines(mediaSection);var mline=lines[0].substr(2).split(" ");var kind=mline[0];var rejected=mline[1]==="0";var direction=SDPUtils.getDirection(mediaSection,sessionpart);var remoteMsid=SDPUtils.parseMsid(mediaSection);var mid=SDPUtils.matchPrefix(mediaSection,"a=mid:");if(mid.length){mid=mid[0].substr(6)}else{mid=SDPUtils.generateIdentifier()}if(kind==="application"&&mline[2]==="DTLS/SCTP"){self.transceivers[sdpMLineIndex]={mid:mid,isDatachannel:true};return}var transceiver;var iceGatherer;var iceTransport;var dtlsTransport;var rtpSender;var rtpReceiver;var sendEncodingParameters;var recvEncodingParameters;var localCapabilities;var track;var remoteCapabilities=SDPUtils.parseRtpParameters(mediaSection);var remoteIceParameters;var remoteDtlsParameters;if(!rejected){remoteIceParameters=SDPUtils.getIceParameters(mediaSection,sessionpart);remoteDtlsParameters=SDPUtils.getDtlsParameters(mediaSection,sessionpart);remoteDtlsParameters.role="client"}recvEncodingParameters=SDPUtils.parseRtpEncodingParameters(mediaSection);var rtcpParameters=SDPUtils.parseRtcpParameters(mediaSection);var isComplete=SDPUtils.matchPrefix(mediaSection,"a=end-of-candidates",sessionpart).length>0;var cands=SDPUtils.matchPrefix(mediaSection,"a=candidate:").map(function(cand){return SDPUtils.parseCandidate(cand)}).filter(function(cand){return cand.component==="1"});if(description.type==="offer"&&!rejected){var transports=usingBundle&&sdpMLineIndex>0?{iceGatherer:self.transceivers[0].iceGatherer,iceTransport:self.transceivers[0].iceTransport,dtlsTransport:self.transceivers[0].dtlsTransport}:self._createIceAndDtlsTransports(mid,sdpMLineIndex);if(isComplete&&(!usingBundle||sdpMLineIndex===0)){transports.iceTransport.setRemoteCandidates(cands)}localCapabilities=RTCRtpReceiver.getCapabilities(kind);if(edgeVersion<15019){localCapabilities.codecs=localCapabilities.codecs.filter(function(codec){return codec.name!=="rtx"})}sendEncodingParameters=[{ssrc:(2*sdpMLineIndex+2)*1001}];if(direction==="sendrecv"||direction==="sendonly"){rtpReceiver=new RTCRtpReceiver(transports.dtlsTransport,kind);track=rtpReceiver.track;if(remoteMsid){if(!streams[remoteMsid.stream]){streams[remoteMsid.stream]=new MediaStream;Object.defineProperty(streams[remoteMsid.stream],"id",{get:function(){return remoteMsid.stream}})}Object.defineProperty(track,"id",{get:function(){return remoteMsid.track}});streams[remoteMsid.stream].addTrack(track);receiverList.push([track,rtpReceiver,streams[remoteMsid.stream]])}else{if(!streams.default){streams.default=new MediaStream}streams.default.addTrack(track);receiverList.push([track,rtpReceiver,streams.default])}}if(self.localStreams.length>0&&self.localStreams[0].getTracks().length>=sdpMLineIndex){var localTrack;if(kind==="audio"){localTrack=self.localStreams[0].getAudioTracks()[0]}else if(kind==="video"){localTrack=self.localStreams[0].getVideoTracks()[0]}if(localTrack){if(edgeVersion>=15019&&kind==="video"){sendEncodingParameters[0].rtx={ssrc:(2*sdpMLineIndex+2)*1001+1}}rtpSender=new RTCRtpSender(localTrack,transports.dtlsTransport)}}self.transceivers[sdpMLineIndex]={iceGatherer:transports.iceGatherer,iceTransport:transports.iceTransport,dtlsTransport:transports.dtlsTransport,localCapabilities:localCapabilities,remoteCapabilities:remoteCapabilities,rtpSender:rtpSender,rtpReceiver:rtpReceiver,kind:kind,mid:mid,rtcpParameters:rtcpParameters,sendEncodingParameters:sendEncodingParameters,recvEncodingParameters:recvEncodingParameters};self._transceive(self.transceivers[sdpMLineIndex],false,direction==="sendrecv"||direction==="sendonly")}else if(description.type==="answer"&&!rejected){if(usingBundle&&sdpMLineIndex>0){self._disposeIceAndDtlsTransports(sdpMLineIndex);self.transceivers[sdpMLineIndex].iceGatherer=self.transceivers[0].iceGatherer;self.transceivers[sdpMLineIndex].iceTransport=self.transceivers[0].iceTransport;self.transceivers[sdpMLineIndex].dtlsTransport=self.transceivers[0].dtlsTransport;if(self.transceivers[sdpMLineIndex].rtpSender){self.transceivers[sdpMLineIndex].rtpSender.setTransport(self.transceivers[0].dtlsTransport)}if(self.transceivers[sdpMLineIndex].rtpReceiver){self.transceivers[sdpMLineIndex].rtpReceiver.setTransport(self.transceivers[0].dtlsTransport)}}transceiver=self.transceivers[sdpMLineIndex];iceGatherer=transceiver.iceGatherer;iceTransport=transceiver.iceTransport;dtlsTransport=transceiver.dtlsTransport;rtpSender=transceiver.rtpSender;rtpReceiver=transceiver.rtpReceiver;sendEncodingParameters=transceiver.sendEncodingParameters;localCapabilities=transceiver.localCapabilities;self.transceivers[sdpMLineIndex].recvEncodingParameters=recvEncodingParameters;self.transceivers[sdpMLineIndex].remoteCapabilities=remoteCapabilities;self.transceivers[sdpMLineIndex].rtcpParameters=rtcpParameters;if((isIceLite||isComplete)&&cands.length){iceTransport.setRemoteCandidates(cands)}if(!usingBundle||sdpMLineIndex===0){iceTransport.start(iceGatherer,remoteIceParameters,"controlling");dtlsTransport.start(remoteDtlsParameters)}self._transceive(transceiver,direction==="sendrecv"||direction==="recvonly",direction==="sendrecv"||direction==="sendonly");if(rtpReceiver&&(direction==="sendrecv"||direction==="sendonly")){track=rtpReceiver.track;receiverList.push([track,rtpReceiver]);if(remoteMsid){if(!streams[remoteMsid.stream]){streams[remoteMsid.stream]=new MediaStream}streams[remoteMsid.stream].addTrack(track)}else{if(!streams.default){streams.default=new MediaStream}streams.default.addTrack(track)}}else{delete transceiver.rtpReceiver}}});this.usingBundle=usingBundle;this.remoteDescription={type:description.type,sdp:description.sdp};switch(description.type){case"offer":this._updateSignalingState("have-remote-offer");break;case"answer":this._updateSignalingState("stable");break;default:throw new TypeError('unsupported type "'+description.type+'"')}Object.keys(streams).forEach(function(sid){var stream=streams[sid];if(stream.getTracks().length){self.remoteStreams.push(stream);var event=new Event("addstream");event.stream=stream;self.dispatchEvent(event);if(self.onaddstream!==null){window.setTimeout(function(){self.onaddstream(event)},0)}receiverList.forEach(function(item){var track=item[0];var receiver=item[1];if(stream.id!==item[2].id){return}var trackEvent=new Event("track");trackEvent.track=track;trackEvent.receiver=receiver;trackEvent.streams=[stream];self.dispatchEvent(trackEvent);if(self.ontrack!==null){window.setTimeout(function(){self.ontrack(trackEvent)},0)}})}});if(arguments.length>1&&typeof arguments[1]==="function"){window.setTimeout(arguments[1],0)}return Promise.resolve()};RTCPeerConnection.prototype.close=function(){this.transceivers.forEach(function(transceiver){if(transceiver.iceTransport){transceiver.iceTransport.stop()}if(transceiver.dtlsTransport){transceiver.dtlsTransport.stop()}if(transceiver.rtpSender){transceiver.rtpSender.stop()}if(transceiver.rtpReceiver){transceiver.rtpReceiver.stop()}});this._updateSignalingState("closed")};RTCPeerConnection.prototype._updateSignalingState=function(newState){this.signalingState=newState;var event=new Event("signalingstatechange");this.dispatchEvent(event);if(this.onsignalingstatechange!==null){this.onsignalingstatechange(event)}};RTCPeerConnection.prototype._maybeFireNegotiationNeeded=function(){var event=new Event("negotiationneeded");this.dispatchEvent(event);if(this.onnegotiationneeded!==null){this.onnegotiationneeded(event)}};RTCPeerConnection.prototype._updateConnectionState=function(){var self=this;var newState;var states={new:0,closed:0,connecting:0,checking:0,connected:0,completed:0,failed:0};this.transceivers.forEach(function(transceiver){states[transceiver.iceTransport.state]++;states[transceiver.dtlsTransport.state]++});states.connected+=states.completed;newState="new";if(states.failed>0){newState="failed"}else if(states.connecting>0||states.checking>0){newState="connecting"}else if(states.disconnected>0){newState="disconnected"}else if(states.new>0){newState="new"}else if(states.connected>0||states.completed>0){newState="connected"}if(newState!==self.iceConnectionState){self.iceConnectionState=newState;var event=new Event("iceconnectionstatechange");this.dispatchEvent(event);if(this.oniceconnectionstatechange!==null){this.oniceconnectionstatechange(event)}}};RTCPeerConnection.prototype.createOffer=function(){var self=this;if(this._pendingOffer){throw new Error("createOffer called while there is a pending offer.")}var offerOptions;if(arguments.length===1&&typeof arguments[0]!=="function"){offerOptions=arguments[0]}else if(arguments.length===3){offerOptions=arguments[2]}var tracks=[];var numAudioTracks=0;var numVideoTracks=0;if(this.localStreams.length){numAudioTracks=this.localStreams.reduce(function(numTracks,stream){return numTracks+stream.getAudioTracks().length},0);numVideoTracks=this.localStreams.reduce(function(numTracks,stream){return numTracks+stream.getVideoTracks().length},0)}if(offerOptions){if(offerOptions.mandatory||offerOptions.optional){throw new TypeError("Legacy mandatory/optional constraints not supported.")}if(offerOptions.offerToReceiveAudio!==undefined){numAudioTracks=offerOptions.offerToReceiveAudio}if(offerOptions.offerToReceiveVideo!==undefined){numVideoTracks=offerOptions.offerToReceiveVideo}}this.localStreams.forEach(function(localStream){localStream.getTracks().forEach(function(track){tracks.push({kind:track.kind,track:track,stream:localStream,wantReceive:track.kind==="audio"?numAudioTracks>0:numVideoTracks>0});if(track.kind==="audio"){numAudioTracks--}else if(track.kind==="video"){numVideoTracks--}})});while(numAudioTracks>0||numVideoTracks>0){if(numAudioTracks>0){tracks.push({kind:"audio",wantReceive:true});numAudioTracks--}if(numVideoTracks>0){tracks.push({kind:"video",wantReceive:true});numVideoTracks--}}tracks=sortTracks(tracks);var sdp=SDPUtils.writeSessionBoilerplate();var transceivers=[];tracks.forEach(function(mline,sdpMLineIndex){var track=mline.track;var kind=mline.kind;var mid=SDPUtils.generateIdentifier();var transports=self.usingBundle&&sdpMLineIndex>0?{iceGatherer:transceivers[0].iceGatherer,iceTransport:transceivers[0].iceTransport,dtlsTransport:transceivers[0].dtlsTransport}:self._createIceAndDtlsTransports(mid,sdpMLineIndex);var localCapabilities=RTCRtpSender.getCapabilities(kind);if(edgeVersion<15019){localCapabilities.codecs=localCapabilities.codecs.filter(function(codec){return codec.name!=="rtx"})}localCapabilities.codecs.forEach(function(codec){if(codec.name==="H264"&&codec.parameters["level-asymmetry-allowed"]===undefined){codec.parameters["level-asymmetry-allowed"]="1"}});var rtpSender;var rtpReceiver;var sendEncodingParameters=[{ssrc:(2*sdpMLineIndex+1)*1001}];if(track){if(edgeVersion>=15019&&kind==="video"){sendEncodingParameters[0].rtx={ssrc:(2*sdpMLineIndex+1)*1001+1}}rtpSender=new RTCRtpSender(track,transports.dtlsTransport)}if(mline.wantReceive){rtpReceiver=new RTCRtpReceiver(transports.dtlsTransport,kind)}transceivers[sdpMLineIndex]={iceGatherer:transports.iceGatherer,iceTransport:transports.iceTransport,dtlsTransport:transports.dtlsTransport,localCapabilities:localCapabilities,remoteCapabilities:null,rtpSender:rtpSender,rtpReceiver:rtpReceiver,kind:kind,mid:mid,sendEncodingParameters:sendEncodingParameters,recvEncodingParameters:null}});if(this._config.bundlePolicy!=="max-compat"){sdp+="a=group:BUNDLE "+transceivers.map(function(t){return t.mid}).join(" ")+"\r\n"}sdp+="a=ice-options:trickle\r\n";tracks.forEach(function(mline,sdpMLineIndex){var transceiver=transceivers[sdpMLineIndex];sdp+=SDPUtils.writeMediaSection(transceiver,transceiver.localCapabilities,"offer",mline.stream);sdp+="a=rtcp-rsize\r\n"});this._pendingOffer=transceivers;var desc=new RTCSessionDescription({type:"offer",sdp:sdp});if(arguments.length&&typeof arguments[0]==="function"){window.setTimeout(arguments[0],0,desc)}return Promise.resolve(desc)};RTCPeerConnection.prototype.createAnswer=function(){var self=this;var sdp=SDPUtils.writeSessionBoilerplate();if(this.usingBundle){sdp+="a=group:BUNDLE "+this.transceivers.map(function(t){return t.mid}).join(" ")+"\r\n"}this.transceivers.forEach(function(transceiver){if(transceiver.isDatachannel){sdp+="m=application 0 DTLS/SCTP 5000\r\n"+"c=IN IP4 0.0.0.0\r\n"+"a=mid:"+transceiver.mid+"\r\n";return}var commonCapabilities=self._getCommonCapabilities(transceiver.localCapabilities,transceiver.remoteCapabilities);var hasRtx=commonCapabilities.codecs.filter(function(c){return c.name.toLowerCase()==="rtx"}).length;if(!hasRtx&&transceiver.sendEncodingParameters[0].rtx){delete transceiver.sendEncodingParameters[0].rtx}sdp+=SDPUtils.writeMediaSection(transceiver,commonCapabilities,"answer",self.localStreams[0]);if(transceiver.rtcpParameters&&transceiver.rtcpParameters.reducedSize){sdp+="a=rtcp-rsize\r\n"}});var desc=new RTCSessionDescription({type:"answer",sdp:sdp});if(arguments.length&&typeof arguments[0]==="function"){window.setTimeout(arguments[0],0,desc)}return Promise.resolve(desc)};RTCPeerConnection.prototype.addIceCandidate=function(candidate){if(!candidate){for(var j=0;j0?SDPUtils.parseCandidate(candidate.candidate):{};if(cand.protocol==="tcp"&&(cand.port===0||cand.port===9)){return Promise.resolve()}if(cand.component!=="1"){return Promise.resolve()}transceiver.iceTransport.addRemoteCandidate(cand);var sections=SDPUtils.splitSections(this.remoteDescription.sdp);sections[mLineIndex+1]+=(cand.type?candidate.candidate.trim():"a=end-of-candidates")+"\r\n";this.remoteDescription.sdp=sections.join("")}}if(arguments.length>1&&typeof arguments[1]==="function"){window.setTimeout(arguments[1],0)}return Promise.resolve()};RTCPeerConnection.prototype.getStats=function(){var promises=[];this.transceivers.forEach(function(transceiver){["rtpSender","rtpReceiver","iceGatherer","iceTransport","dtlsTransport"].forEach(function(method){if(transceiver[method]){promises.push(transceiver[method].getStats())}})});var cb=arguments.length>1&&typeof arguments[1]==="function"&&arguments[1];var fixStatsType=function(stat){return{inboundrtp:"inbound-rtp",outboundrtp:"outbound-rtp",candidatepair:"candidate-pair",localcandidate:"local-candidate",remotecandidate:"remote-candidate"}[stat.type]||stat.type};return new Promise(function(resolve){var results=new Map;Promise.all(promises).then(function(res){res.forEach(function(result){Object.keys(result).forEach(function(id){result[id].type=fixStatsType(result[id]);results.set(id,result[id])})});if(cb){window.setTimeout(cb,0,results)}resolve(results)})})};return RTCPeerConnection}},{sdp:17}],27:[function(require,module,exports){"use strict";var browserDetails=require("../utils").browserDetails;var firefoxShim={shimOnTrack:function(){if(typeof window==="object"&&window.RTCPeerConnection&&!("ontrack"in window.RTCPeerConnection.prototype)){Object.defineProperty(window.RTCPeerConnection.prototype,"ontrack",{get:function(){return this._ontrack},set:function(f){if(this._ontrack){this.removeEventListener("track",this._ontrack);this.removeEventListener("addstream",this._ontrackpoly)}this.addEventListener("track",this._ontrack=f);this.addEventListener("addstream",this._ontrackpoly=function(e){e.stream.getTracks().forEach(function(track){var event=new Event("track");event.track=track;event.receiver={track:track};event.streams=[e.stream];this.dispatchEvent(event)}.bind(this))}.bind(this))}})}},shimSourceObject:function(){if(typeof window==="object"){if(window.HTMLMediaElement&&!("srcObject"in window.HTMLMediaElement.prototype)){Object.defineProperty(window.HTMLMediaElement.prototype,"srcObject",{get:function(){return this.mozSrcObject},set:function(stream){this.mozSrcObject=stream}})}}},shimPeerConnection:function(){if(typeof window!=="object"||!(window.RTCPeerConnection||window.mozRTCPeerConnection)){return}if(!window.RTCPeerConnection){window.RTCPeerConnection=function(pcConfig,pcConstraints){if(browserDetails.version<38){if(pcConfig&&pcConfig.iceServers){var newIceServers=[];for(var i=0;i=0){return}this._streams.push(stream);var event=new Event("addstream");event.stream=e.streams[0];this.dispatchEvent(event)}.bind(this))}})}},shimGetUserMedia:function(){if(!navigator.getUserMedia){if(navigator.webkitGetUserMedia){navigator.getUserMedia=navigator.webkitGetUserMedia.bind(navigator)}else if(navigator.mediaDevices&&navigator.mediaDevices.getUserMedia){navigator.getUserMedia=function(constraints,cb,errcb){navigator.mediaDevices.getUserMedia(constraints).then(cb,errcb)}.bind(navigator)}}}};module.exports={shimOnAddStream:safariShim.shimOnAddStream,shimGetUserMedia:safariShim.shimGetUserMedia}},{}],30:[function(require,module,exports){"use strict";var logDisabled_=true;var utils={disableLog:function(bool){if(typeof bool!=="boolean"){return new Error("Argument type: "+typeof bool+". Please use a boolean.")}logDisabled_=bool;return bool?"adapter.js logging disabled":"adapter.js logging enabled"},log:function(){if(typeof window==="object"){if(logDisabled_){return}if(typeof console!=="undefined"&&typeof console.log==="function"){console.log.apply(console,arguments)}}},extractVersion:function(uastring,expr,pos){var match=uastring.match(expr);return match&&match.length>=pos&&parseInt(match[pos],10)},detectBrowser:function(){var result={};result.browser=null;result.version=null;if(typeof window==="undefined"||!window.navigator){result.browser="Not a browser.";return result}if(navigator.mozGetUserMedia){result.browser="firefox";result.version=this.extractVersion(navigator.userAgent,/Firefox\/(\d+)\./,1)}else if(navigator.webkitGetUserMedia){if(window.webkitRTCPeerConnection){result.browser="chrome";result.version=this.extractVersion(navigator.userAgent,/Chrom(e|ium)\/(\d+)\./,2)}else{if(navigator.userAgent.match(/Version\/(\d+).(\d+)/)){result.browser="safari";result.version=this.extractVersion(navigator.userAgent,/AppleWebKit\/(\d+)\./,1)}else{result.browser="Unsupported webkit-based browser "+"with GUM support but no WebRTC support.";return result}}}else if(navigator.mediaDevices&&navigator.userAgent.match(/Edge\/(\d+).(\d+)$/)){result.browser="edge";result.version=this.extractVersion(navigator.userAgent,/Edge\/(\d+).(\d+)$/,2)}else if(navigator.mediaDevices&&navigator.userAgent.match(/AppleWebKit\/(\d+)\./)){result.browser="safari";result.version=this.extractVersion(navigator.userAgent,/AppleWebKit\/(\d+)\./,1)}else{result.browser="Not a supported browser.";return result}return result},shimCreateObjectURL:function(){if(!(typeof window==="object"&&window.HTMLMediaElement&&"srcObject"in window.HTMLMediaElement.prototype)){return undefined}var nativeCreateObjectURL=URL.createObjectURL.bind(URL);var nativeRevokeObjectURL=URL.revokeObjectURL.bind(URL);var streams=new Map,newId=0;URL.createObjectURL=function(stream){if("getTracks"in stream){var url="polyblob:"+ ++newId;streams.set(url,stream);console.log("URL.createObjectURL(stream) is deprecated! "+"Use elem.srcObject = stream instead!");return url}return nativeCreateObjectURL(stream)};URL.revokeObjectURL=function(url){nativeRevokeObjectURL(url);streams.delete(url)};var dsc=Object.getOwnPropertyDescriptor(window.HTMLMediaElement.prototype,"src");Object.defineProperty(window.HTMLMediaElement.prototype,"src",{get:function(){return dsc.get.apply(this)},set:function(url){this.srcObject=streams.get(url)||null;return dsc.set.apply(this,[url])}});var nativeSetAttribute=HTMLMediaElement.prototype.setAttribute;HTMLMediaElement.prototype.setAttribute=function(){if(arguments.length===2&&(""+arguments[0]).toLowerCase()==="src"){this.srcObject=streams.get(arguments[1])||null}return nativeSetAttribute.apply(this,arguments)}}};module.exports={log:utils.log,disableLog:utils.disableLog,browserDetails:utils.detectBrowser(),extractVersion:utils.extractVersion,shimCreateObjectURL:utils.shimCreateObjectURL,detectBrowser:utils.detectBrowser.bind(utils)}},{}],31:[function(require,module,exports){module.exports=WildEmitter;function WildEmitter(){}WildEmitter.mixin=function(constructor){var prototype=constructor.prototype||constructor;prototype.isWildEmitter=true;prototype.on=function(event,groupName,fn){this.callbacks=this.callbacks||{};var hasGroup=arguments.length===3,group=hasGroup?arguments[1]:undefined,func=hasGroup?arguments[2]:arguments[1];func._groupName=group;(this.callbacks[event]=this.callbacks[event]||[]).push(func);return this};prototype.once=function(event,groupName,fn){var self=this,hasGroup=arguments.length===3,group=hasGroup?arguments[1]:undefined,func=hasGroup?arguments[2]:arguments[1];function on(){self.off(event,on);func.apply(this,arguments)}this.on(event,group,on);return this};prototype.releaseGroup=function(groupName){this.callbacks=this.callbacks||{};var item,i,len,handlers;for(item in this.callbacks){handlers=this.callbacks[item];for(i=0,len=handlers.length;inotReconnectIfNumLessThan){enabledPings=false;updateNotReconnectIfLessThan();Logger.debug("Server did not respond to ping message #"+pingNum+". Reconnecting... ");ws.reconnectWs()}}}}(pingNextNum))}else{Logger.debug("Trying to send ping, but ping is not enabled")}}function usePing(){if(!pingPongStarted){Logger.debug("Starting ping (if configured)");pingPongStarted=true;if(configuration.heartbeat!=undefined){pingInterval=setInterval(sendPing,configuration.heartbeat);sendPing()}}}this.close=function(){Logger.debug("Closing jsonRpcClient explicitly by client");if(pingInterval!=undefined){Logger.debug("Clearing ping interval");clearInterval(pingInterval)}pingPongStarted=false;enabledPings=false;if(configuration.sendCloseMessage){Logger.debug("Sending close message");this.send("closeSession",null,function(error,result){if(error){Logger.error("Error sending close message: "+JSON.stringify(error))}ws.close()})}else{ws.close()}};this.forceClose=function(millis){ws.forceClose(millis)};this.reconnect=function(){ws.reconnectWs()}}module.exports=JsonRpcClient},{"../":38,"./transports/webSocketWithReconnection":37}],36:[function(require,module,exports){var WebSocketWithReconnection=require("./webSocketWithReconnection");exports.WebSocketWithReconnection=WebSocketWithReconnection},{"./webSocketWithReconnection":37}],37:[function(require,module,exports){(function(global){"use strict";var BrowserWebSocket=global.WebSocket||global.MozWebSocket;var Logger=console;var MAX_RETRIES=2e3;var RETRY_TIME_MS=3e3;var CONNECTING=0;var OPEN=1;var CLOSING=2;var CLOSED=3;function WebSocketWithReconnection(config){var closing=false;var registerMessageHandler;var wsUri=config.uri;var useSockJS=config.useSockJS;var reconnecting=false;var forcingDisconnection=false;var ws;if(useSockJS){ws=new SockJS(wsUri)}else{ws=new WebSocket(wsUri)}ws.onopen=function(){logConnected(ws,wsUri);if(config.onconnected){config.onconnected()}};ws.onerror=function(error){Logger.error("Could not connect to "+wsUri+" (invoking onerror if defined)",error);if(config.onerror){config.onerror(error)}};function logConnected(ws,wsUri){try{Logger.debug("WebSocket connected to "+wsUri)}catch(e){Logger.error(e)}}var reconnectionOnClose=function(){if(ws.readyState===CLOSED){if(closing){Logger.debug("Connection closed by user")}else{Logger.debug("Connection closed unexpectecly. Reconnecting...");reconnectToSameUri(MAX_RETRIES,1)}}else{Logger.debug("Close callback from previous websocket. Ignoring it")}};ws.onclose=reconnectionOnClose;function reconnectToSameUri(maxRetries,numRetries){Logger.debug("reconnectToSameUri (attempt #"+numRetries+", max="+maxRetries+")");if(numRetries===1){if(reconnecting){Logger.warn("Trying to reconnectToNewUri when reconnecting... Ignoring this reconnection.");return}else{reconnecting=true}if(config.onreconnecting){config.onreconnecting()}}if(forcingDisconnection){reconnectToNewUri(maxRetries,numRetries,wsUri)}else{if(config.newWsUriOnReconnection){config.newWsUriOnReconnection(function(error,newWsUri){if(error){Logger.debug(error);setTimeout(function(){reconnectToSameUri(maxRetries,numRetries+1)},RETRY_TIME_MS)}else{reconnectToNewUri(maxRetries,numRetries,newWsUri)}})}else{reconnectToNewUri(maxRetries,numRetries,wsUri)}}}function reconnectToNewUri(maxRetries,numRetries,reconnectWsUri){Logger.debug("Reconnection attempt #"+numRetries);ws.close();wsUri=reconnectWsUri||wsUri;var newWs;if(useSockJS){newWs=new SockJS(wsUri)}else{newWs=new WebSocket(wsUri)}newWs.onopen=function(){Logger.debug("Reconnected after "+numRetries+" attempts...");logConnected(newWs,wsUri);reconnecting=false;registerMessageHandler();if(config.onreconnected()){config.onreconnected()}newWs.onclose=reconnectionOnClose};var onErrorOrClose=function(error){Logger.warn("Reconnection error: ",error);if(numRetries===maxRetries){if(config.ondisconnect){config.ondisconnect()}}else{setTimeout(function(){reconnectToSameUri(maxRetries,numRetries+1)},RETRY_TIME_MS)}};newWs.onerror=onErrorOrClose;ws=newWs}this.close=function(){closing=true;ws.close()};this.forceClose=function(millis){Logger.debug("Testing: Force WebSocket close");if(millis){Logger.debug("Testing: Change wsUri for "+millis+" millis to simulate net failure");var goodWsUri=wsUri;wsUri="wss://21.234.12.34.4:443/";forcingDisconnection=true;setTimeout(function(){Logger.debug("Testing: Recover good wsUri "+goodWsUri);wsUri=goodWsUri;forcingDisconnection=false},millis)}ws.close()};this.reconnectWs=function(){Logger.debug("reconnectWs");reconnectToSameUri(MAX_RETRIES,1,wsUri)};this.send=function(message){ws.send(message)};this.addEventListener=function(type,callback){registerMessageHandler=function(){ws.addEventListener(type,callback)};registerMessageHandler()}}module.exports=WebSocketWithReconnection}).call(this,typeof global!=="undefined"?global:typeof self!=="undefined"?self:typeof window!=="undefined"?window:{})},{}],38:[function(require,module,exports){var defineProperty_IE8=false;if(Object.defineProperty){try{Object.defineProperty({},"x",{})}catch(e){defineProperty_IE8=true}}if(!Function.prototype.bind){Function.prototype.bind=function(oThis){if(typeof this!=="function"){throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable")}var aArgs=Array.prototype.slice.call(arguments,1),fToBind=this,fNOP=function(){},fBound=function(){return fToBind.apply(this instanceof fNOP&&oThis?this:oThis,aArgs.concat(Array.prototype.slice.call(arguments)))};fNOP.prototype=this.prototype;fBound.prototype=new fNOP;return fBound}}var EventEmitter=require("events").EventEmitter;var inherits=require("inherits");var packers=require("./packers");var Mapper=require("./Mapper");var BASE_TIMEOUT=5e3;function unifyResponseMethods(responseMethods){if(!responseMethods)return{};for(var key in responseMethods){var value=responseMethods[key];if(typeof value=="string")responseMethods[key]={response:value}}return responseMethods}function unifyTransport(transport){if(!transport)return;if(transport instanceof Function)return{send:transport};if(transport.send instanceof Function)return transport;if(transport.postMessage instanceof Function){transport.send=transport.postMessage;return transport}if(transport.write instanceof Function){transport.send=transport.write;return transport}if(transport.onmessage!==undefined)return;if(transport.pause instanceof Function)return;throw new SyntaxError("Transport is not a function nor a valid object")}function RpcNotification(method,params){if(defineProperty_IE8){this.method=method;this.params=params}else{Object.defineProperty(this,"method",{value:method,enumerable:true});Object.defineProperty(this,"params",{value:params,enumerable:true})}}function RpcBuilder(packer,options,transport,onRequest){var self=this;if(!packer)throw new SyntaxError("Packer is not defined");if(!packer.pack||!packer.unpack)throw new SyntaxError("Packer is invalid");var responseMethods=unifyResponseMethods(packer.responseMethods);if(options instanceof Function){if(transport!=undefined)throw new SyntaxError("There can't be parameters after onRequest");onRequest=options;transport=undefined;options=undefined}if(options&&options.send instanceof Function){if(transport&&!(transport instanceof Function))throw new SyntaxError("Only a function can be after transport");onRequest=transport;transport=options;options=undefined}if(transport instanceof Function){if(onRequest!=undefined)throw new SyntaxError("There can't be parameters after onRequest");onRequest=transport;transport=undefined}if(transport&&transport.send instanceof Function)if(onRequest&&!(onRequest instanceof Function))throw new SyntaxError("Only a function can be after transport");options=options||{};EventEmitter.call(this);if(onRequest)this.on("request",onRequest);if(defineProperty_IE8)this.peerID=options.peerID;else Object.defineProperty(this,"peerID",{value:options.peerID});var max_retries=options.max_retries||0;function transportMessage(event){self.decode(event.data||event)}this.getTransport=function(){return transport};this.setTransport=function(value){if(transport){if(transport.removeEventListener)transport.removeEventListener("message",transportMessage);else if(transport.removeListener)transport.removeListener("data",transportMessage)}if(value){if(value.addEventListener)value.addEventListener("message",transportMessage);else if(value.addListener)value.addListener("data",transportMessage)}transport=unifyTransport(value)};if(!defineProperty_IE8)Object.defineProperty(this,"transport",{get:this.getTransport.bind(this),set:this.setTransport.bind(this)});this.setTransport(transport);var request_timeout=options.request_timeout||BASE_TIMEOUT;var ping_request_timeout=options.ping_request_timeout||request_timeout;var response_timeout=options.response_timeout||BASE_TIMEOUT;var duplicates_timeout=options.duplicates_timeout||BASE_TIMEOUT;var requestID=0;var requests=new Mapper;var responses=new Mapper;var processedResponses=new Mapper;var message2Key={};function storeResponse(message,id,dest){var response={message:message,timeout:setTimeout(function(){responses.remove(id,dest)},response_timeout)};responses.set(response,id,dest)}function storeProcessedResponse(ack,from){var timeout=setTimeout(function(){processedResponses.remove(ack,from)},duplicates_timeout);processedResponses.set(timeout,ack,from)}function RpcRequest(method,params,id,from,transport){RpcNotification.call(this,method,params);this.getTransport=function(){return transport};this.setTransport=function(value){transport=unifyTransport(value)};if(!defineProperty_IE8)Object.defineProperty(this,"transport",{get:this.getTransport.bind(this),set:this.setTransport.bind(this)});var response=responses.get(id,from);if(!(transport||self.getTransport())){if(defineProperty_IE8)this.duplicated=Boolean(response);else Object.defineProperty(this,"duplicated",{value:Boolean(response)})}var responseMethod=responseMethods[method];this.pack=packer.pack.bind(packer,this,id);this.reply=function(error,result,transport){if(error instanceof Function||error&&error.send instanceof Function){if(result!=undefined)throw new SyntaxError("There can't be parameters after callback");transport=error;result=null;error=undefined}else if(result instanceof Function||result&&result.send instanceof Function){if(transport!=undefined)throw new SyntaxError("There can't be parameters after callback");transport=result;result=null}transport=unifyTransport(transport);if(response)clearTimeout(response.timeout);if(from!=undefined){if(error)error.dest=from;if(result)result.dest=from}var message;if(error||result!=undefined){if(self.peerID!=undefined){if(error)error.from=self.peerID;else result.from=self.peerID}if(responseMethod){if(responseMethod.error==undefined&&error)message={error:error};else{var method=error?responseMethod.error:responseMethod.response;message={method:method,params:error||result}}}else message={error:error,result:result};message=packer.pack(message,id)}else if(response)message=response.message;else message=packer.pack({result:null},id);storeResponse(message,id,from);transport=transport||this.getTransport()||self.getTransport();if(transport)return transport.send(message);return message}}inherits(RpcRequest,RpcNotification);function cancel(message){var key=message2Key[message];if(!key)return;delete message2Key[message];var request=requests.pop(key.id,key.dest);if(!request)return;clearTimeout(request.timeout);storeProcessedResponse(key.id,key.dest)}this.cancel=function(message){if(message)return cancel(message);for(var message in message2Key)cancel(message)};this.close=function(){var transport=this.getTransport();if(transport&&transport.close)transport.close();this.cancel();processedResponses.forEach(clearTimeout);responses.forEach(function(response){clearTimeout(response.timeout)})};this.encode=function(method,params,dest,transport,callback){if(params instanceof Function){if(dest!=undefined)throw new SyntaxError("There can't be parameters after callback");callback=params;transport=undefined;dest=undefined;params=undefined}else if(dest instanceof Function){if(transport!=undefined)throw new SyntaxError("There can't be parameters after callback");callback=dest;transport=undefined;dest=undefined}else if(transport instanceof Function){if(callback!=undefined)throw new SyntaxError("There can't be parameters after callback");callback=transport;transport=undefined}if(self.peerID!=undefined){params=params||{};params.from=self.peerID}if(dest!=undefined){params=params||{};params.dest=dest}var message={method:method,params:params};if(callback){var id=requestID++;var retried=0;message=packer.pack(message,id);function dispatchCallback(error,result){self.cancel(message);callback(error,result)}var request={message:message,callback:dispatchCallback,responseMethods:responseMethods[method]||{}};var encode_transport=unifyTransport(transport);function sendRequest(transport){var rt=method==="ping"?ping_request_timeout:request_timeout;request.timeout=setTimeout(timeout,rt*Math.pow(2,retried++));message2Key[message]={id:id,dest:dest};requests.set(request,id,dest);transport=transport||encode_transport||self.getTransport();if(transport)return transport.send(message);return message}function retry(transport){transport=unifyTransport(transport);console.warn(retried+" retry for request message:",message);var timeout=processedResponses.pop(id,dest);clearTimeout(timeout);return sendRequest(transport)}function timeout(){if(retried0){return sdp.slice(0,n)}else{return sdp}}function getSimulcastInfo(videoStream){var videoTracks=videoStream.getVideoTracks();if(!videoTracks.length){logger.warn("No video tracks available in the video stream");return""}var lines=["a=x-google-flag:conference","a=ssrc-group:SIM 1 2 3","a=ssrc:1 cname:localVideo","a=ssrc:1 msid:"+videoStream.id+" "+videoTracks[0].id,"a=ssrc:1 mslabel:"+videoStream.id,"a=ssrc:1 label:"+videoTracks[0].id,"a=ssrc:2 cname:localVideo","a=ssrc:2 msid:"+videoStream.id+" "+videoTracks[0].id,"a=ssrc:2 mslabel:"+videoStream.id,"a=ssrc:2 label:"+videoTracks[0].id,"a=ssrc:3 cname:localVideo","a=ssrc:3 msid:"+videoStream.id+" "+videoTracks[0].id,"a=ssrc:3 mslabel:"+videoStream.id,"a=ssrc:3 label:"+videoTracks[0].id];lines.push("");return lines.join("\n")}function WebRtcPeer(mode,options,callback){if(!(this instanceof WebRtcPeer)){return new WebRtcPeer(mode,options,callback)}WebRtcPeer.super_.call(this);if(options instanceof Function){callback=options;options=undefined}options=options||{};callback=(callback||noop).bind(this);var self=this;var localVideo=options.localVideo;var remoteVideo=options.remoteVideo;var videoStream=options.videoStream;var audioStream=options.audioStream;var mediaConstraints=options.mediaConstraints;var connectionConstraints=options.connectionConstraints;var pc=options.peerConnection;var sendSource=options.sendSource||"webcam";var dataChannelConfig=options.dataChannelConfig;var useDataChannels=options.dataChannels||false;var dataChannel;var guid=uuid.v4();var configuration=recursive({iceServers:freeice()},options.configuration);var onicecandidate=options.onicecandidate;if(onicecandidate)this.on("icecandidate",onicecandidate);var oncandidategatheringdone=options.oncandidategatheringdone;if(oncandidategatheringdone){this.on("candidategatheringdone",oncandidategatheringdone)}var simulcast=options.simulcast;var multistream=options.multistream;var interop=new sdpTranslator.Interop;var candidatesQueueOut=[];var candidategatheringdone=false;Object.defineProperties(this,{peerConnection:{get:function(){return pc}},id:{value:options.id||guid,writable:false},remoteVideo:{get:function(){return remoteVideo}},localVideo:{get:function(){return localVideo}},dataChannel:{get:function(){return dataChannel}},currentFrame:{get:function(){if(!remoteVideo)return;if(remoteVideo.readyStateUnifiedPlan",dumpSDP(localDescription))}callback(null,localDescription.sdp,self.processAnswer.bind(self))}).catch(callback)};this.getLocalSessionDescriptor=function(){return pc.localDescription};this.getRemoteSessionDescriptor=function(){return pc.remoteDescription};function setRemoteVideo(){if(remoteVideo){var stream=pc.getRemoteStreams()[0];var url=stream?URL.createObjectURL(stream):"";remoteVideo.pause();remoteVideo.src=url;remoteVideo.load();logger.debug("Remote URL:",url)}}this.showLocalVideo=function(){localVideo.src=URL.createObjectURL(videoStream);localVideo.muted=true};this.send=function(data){if(dataChannel&&dataChannel.readyState==="open"){dataChannel.send(data)}else{logger.warn("Trying to send data over a non-existing or closed data channel")}};this.processAnswer=function(sdpAnswer,callback){callback=(callback||noop).bind(this);var answer=new RTCSessionDescription({type:"answer",sdp:sdpAnswer});if(multistream&&usePlanB){var planBAnswer=interop.toPlanB(answer);logger.debug("asnwer::planB",dumpSDP(planBAnswer));answer=planBAnswer}logger.debug("SDP answer received, setting remote description");if(pc.signalingState==="closed"){return callback("PeerConnection is closed")}pc.setRemoteDescription(answer,function(){setRemoteVideo();callback()},callback)};this.processOffer=function(sdpOffer,callback){callback=callback.bind(this);var offer=new RTCSessionDescription({type:"offer",sdp:sdpOffer});if(multistream&&usePlanB){var planBOffer=interop.toPlanB(offer);logger.debug("offer::planB",dumpSDP(planBOffer));offer=planBOffer}logger.debug("SDP offer received, setting remote description");if(pc.signalingState==="closed"){return callback("PeerConnection is closed")}pc.setRemoteDescription(offer).then(function(){return setRemoteVideo()}).then(function(){return pc.createAnswer()}).then(function(answer){answer=mangleSdpToAddSimulcast(answer);logger.debug("Created SDP answer");return pc.setLocalDescription(answer)}).then(function(){var localDescription=pc.localDescription;if(multistream&&usePlanB){localDescription=interop.toUnifiedPlan(localDescription);logger.debug("answer::origPlanB->UnifiedPlan",dumpSDP(localDescription))}logger.debug("Local description set",localDescription.sdp);callback(null,localDescription.sdp)}).catch(callback)};function mangleSdpToAddSimulcast(answer){if(simulcast){if(browser.name==="Chrome"||browser.name==="Chromium"){logger.debug("Adding multicast info");answer=new RTCSessionDescription({type:answer.type,sdp:removeFIDFromOffer(answer.sdp)+getSimulcastInfo(videoStream)})}else{logger.warn("Simulcast is only available in Chrome browser.")}}return answer}function start(){if(pc.signalingState==="closed"){callback('The peer connection object is in "closed" state. This is most likely due to an invocation of the dispose method before accepting in the dialogue')}if(videoStream&&localVideo){self.showLocalVideo()}if(videoStream){pc.addStream(videoStream)}if(audioStream){pc.addStream(audioStream)}var browser=parser.getBrowser();if(mode==="sendonly"&&(browser.name==="Chrome"||browser.name==="Chromium")&&browser.major===39){mode="sendrecv"}callback()}if(mode!=="recvonly"&&!videoStream&&!audioStream){function getMedia(constraints){if(constraints===undefined){constraints=MEDIA_CONSTRAINTS}navigator.mediaDevices.getUserMedia(constraints).then(function(stream){videoStream=stream;start()}).catch(callback)}if(sendSource==="webcam"){getMedia(mediaConstraints)}else{getScreenConstraints(sendSource,function(error,constraints_){if(error)return callback(error);constraints=[mediaConstraints];constraints.unshift(constraints_);getMedia(recursive.apply(undefined,constraints))},guid)}}else{setTimeout(start,0)}this.on("_dispose",function(){if(localVideo){localVideo.pause();localVideo.src="";localVideo.load();localVideo.muted=false}if(remoteVideo){remoteVideo.pause();remoteVideo.src="";remoteVideo.load()}self.removeAllListeners();if(window.cancelChooseDesktopMedia!==undefined){window.cancelChooseDesktopMedia(guid)}})}inherits(WebRtcPeer,EventEmitter);function createEnableDescriptor(type){var method="get"+type+"Tracks";return{enumerable:true,get:function(){if(!this.peerConnection)return;var streams=this.peerConnection.getLocalStreams();if(!streams.length)return;for(var i=0,stream;stream=streams[i];i++){var tracks=stream[method]();for(var j=0,track;track=tracks[j];j++)if(!track.enabled)return false}return true},set:function(value){function trackSetEnable(track){track.enabled=value}this.peerConnection.getLocalStreams().forEach(function(stream){stream[method]().forEach(trackSetEnable)})}}}Object.defineProperties(WebRtcPeer.prototype,{enabled:{enumerable:true,get:function(){return this.audioEnabled&&this.videoEnabled},set:function(value){this.audioEnabled=this.videoEnabled=value}},audioEnabled:createEnableDescriptor("Audio"),videoEnabled:createEnableDescriptor("Video")});WebRtcPeer.prototype.getLocalStream=function(index){if(this.peerConnection){return this.peerConnection.getLocalStreams()[index||0]}};WebRtcPeer.prototype.getRemoteStream=function(index){if(this.peerConnection){return this.peerConnection.getRemoteStreams()[index||0]}};WebRtcPeer.prototype.dispose=function(){logger.debug("Disposing WebRtcPeer");var pc=this.peerConnection;var dc=this.dataChannel;try{if(dc){if(dc.signalingState==="closed")return;dc.close()}if(pc){if(pc.signalingState==="closed")return;pc.getLocalStreams().forEach(streamStop);pc.close()}}catch(err){logger.warn("Exception disposing webrtc peer "+err)}this.emit("_dispose")};function WebRtcPeerRecvonly(options,callback){if(!(this instanceof WebRtcPeerRecvonly)){return new WebRtcPeerRecvonly(options,callback)}WebRtcPeerRecvonly.super_.call(this,"recvonly",options,callback)}inherits(WebRtcPeerRecvonly,WebRtcPeer);function WebRtcPeerSendonly(options,callback){if(!(this instanceof WebRtcPeerSendonly)){return new WebRtcPeerSendonly(options,callback)}WebRtcPeerSendonly.super_.call(this,"sendonly",options,callback)}inherits(WebRtcPeerSendonly,WebRtcPeer);function WebRtcPeerSendrecv(options,callback){if(!(this instanceof WebRtcPeerSendrecv)){return new WebRtcPeerSendrecv(options,callback)}WebRtcPeerSendrecv.super_.call(this,"sendrecv",options,callback)}inherits(WebRtcPeerSendrecv,WebRtcPeer);function harkUtils(stream,options){return hark(stream,options)}exports.bufferizeCandidates=bufferizeCandidates;exports.WebRtcPeerRecvonly=WebRtcPeerRecvonly;exports.WebRtcPeerSendonly=WebRtcPeerSendonly;exports.WebRtcPeerSendrecv=WebRtcPeerSendrecv;exports.hark=harkUtils},{events:1,freeice:2,hark:5,inherits:6,merge:7,"sdp-translator":14,"ua-parser-js":18,uuid:20}],43:[function(require,module,exports){var WebRtcPeer=require("./WebRtcPeer");exports.WebRtcPeer=WebRtcPeer},{"./WebRtcPeer":42}],44:[function(require,module,exports){"use strict";Object.defineProperty(exports,"__esModule",{value:true});var OpenVidu_1=require("./OpenVidu");if(window){window["OpenVidu"]=OpenVidu_1.OpenVidu}},{"./OpenVidu":45}],45:[function(require,module,exports){"use strict";Object.defineProperty(exports,"__esModule",{value:true});var OpenViduInternal_1=require("../OpenViduInternal/OpenViduInternal");var Session_1=require("./Session");var Publisher_1=require("./Publisher");var adapter=require("webrtc-adapter");if(window){window["adapter"]=adapter}var OpenVidu=function(){function OpenVidu(){this.openVidu=new OpenViduInternal_1.OpenViduInternal;console.info("'OpenVidu' initialized")}OpenVidu.prototype.initSession=function(param1,param2){if(this.checkSystemRequirements()){if(typeof param2=="string"){return new Session_1.Session(this.openVidu.initSession(param2),this)}else{return new Session_1.Session(this.openVidu.initSession(param1),this)}}else{alert("Browser not supported")}};OpenVidu.prototype.initPublisher=function(parentId,cameraOptions,callback){if(this.checkSystemRequirements()){if(cameraOptions!=null){var cameraOptionsAux={sendAudio:cameraOptions.audio!=null?cameraOptions.audio:true,sendVideo:cameraOptions.video!=null?cameraOptions.video:true,activeAudio:cameraOptions.activeAudio!=null?cameraOptions.activeAudio:true,activeVideo:cameraOptions.activeVideo!=null?cameraOptions.activeVideo:true,data:true,mediaConstraints:this.openVidu.generateMediaConstraints(cameraOptions)};cameraOptions=cameraOptionsAux}else{cameraOptions={sendAudio:true,sendVideo:true,activeAudio:true,activeVideo:true,data:true,mediaConstraints:{audio:true,video:{width:{ideal:1280}}}}}var publisher=new Publisher_1.Publisher(this.openVidu.initPublisherTagged(parentId,cameraOptions,callback),parentId);console.info("'Publisher' initialized");return publisher}else{alert("Browser not supported")}};OpenVidu.prototype.checkSystemRequirements=function(){var browser=adapter.browserDetails.browser;var version=adapter.browserDetails.version;if(browser=="firefox"&&version==null){return 1}if(browser=="chrome"&&version>=28||browser=="edge"&&version>=12||browser=="firefox"&&version>=22){return 1}else{return 0}};OpenVidu.prototype.getDevices=function(callback){navigator.mediaDevices.enumerateDevices().then(function(deviceInfos){callback(null,deviceInfos)}).catch(function(error){console.error("Error getting devices",error);callback(error,null)})};OpenVidu.prototype.enableProdMode=function(){console.log=function(){};console.debug=function(){};console.info=function(){};console.warn=function(){}};return OpenVidu}();exports.OpenVidu=OpenVidu},{"../OpenViduInternal/OpenViduInternal":50,"./Publisher":46,"./Session":47,"webrtc-adapter":21}],46:[function(require,module,exports){"use strict";Object.defineProperty(exports,"__esModule",{value:true});var EventEmitter=require("wolfy87-eventemitter");var Publisher=function(){function Publisher(stream,parentId){var _this=this;this.ee=new EventEmitter;this.accessAllowed=false;this.stream=stream;this.stream.addEventListener("camera-access-changed",function(event){_this.accessAllowed=event.accessAllowed;if(_this.accessAllowed){_this.ee.emitEvent("accessAllowed")}else{_this.ee.emitEvent("accessDenied")}});if(document.getElementById(parentId)!=null){this.element=document.getElementById(parentId)}}Publisher.prototype.publishAudio=function(value){this.stream.getWebRtcPeer().audioEnabled=value};Publisher.prototype.publishVideo=function(value){this.stream.getWebRtcPeer().videoEnabled=value};Publisher.prototype.destroy=function(){this.session.unpublish(this);this.stream.dispose();this.stream.removeVideo(this.element);return this};Publisher.prototype.subscribeToRemote=function(){this.stream.subscribeToMyRemote()};Publisher.prototype.on=function(eventName,callback){var _this=this;this.ee.addListener(eventName,function(event){if(event){console.info("Event '"+eventName+"' triggered by 'Publisher'",event)}else{console.info("Event '"+eventName+"' triggered by 'Publisher'")}callback(event)});if(eventName=="videoElementCreated"){if(this.stream.isVideoELementCreated){this.ee.emitEvent("videoElementCreated",[{element:this.stream.getVideoElement()}])}else{this.stream.addOnceEventListener("video-element-created-by-stream",function(element){_this.id=element.id;_this.ee.emitEvent("videoElementCreated",[{element:element.element}])})}}if(eventName=="videoPlaying"){var video=this.stream.getVideoElement();if(!this.stream.displayMyRemote()&&video&&video.currentTime>0&&video.paused==false&&video.ended==false&&video.readyState==4){this.ee.emitEvent("videoPlaying",[{element:this.stream.getVideoElement()}])}else{this.stream.addOnceEventListener("video-is-playing",function(element){_this.ee.emitEvent("videoPlaying",[{element:element.element}])})}}if(eventName=="remoteVideoPlaying"){var video=this.stream.getVideoElement();if(this.stream.displayMyRemote()&&video&&video.currentTime>0&&video.paused==false&&video.ended==false&&video.readyState==4){this.ee.emitEvent("remoteVideoPlaying",[{element:this.stream.getVideoElement()}])}else{this.stream.addOnceEventListener("remote-video-is-playing",function(element){_this.ee.emitEvent("remoteVideoPlaying",[{element:element.element}])})}}if(eventName=="accessAllowed"){if(this.stream.accessIsAllowed){this.ee.emitEvent("accessAllowed")}else{this.stream.addEventListener("access-allowed-by-publisher",function(){_this.ee.emitEvent("accessAllowed")})}}if(eventName=="accessDenied"){if(this.stream.accessIsDenied){this.ee.emitEvent("accessDenied")}else{this.stream.addEventListener("access-denied-by-publisher",function(){_this.ee.emitEvent("accessDenied")})}}};return Publisher}();exports.Publisher=Publisher},{"wolfy87-eventemitter":32}],47:[function(require,module,exports){"use strict";Object.defineProperty(exports,"__esModule",{value:true});var Subscriber_1=require("./Subscriber");var EventEmitter=require("wolfy87-eventemitter");var Session=function(){function Session(session,openVidu){var _this=this;this.session=session;this.openVidu=openVidu;this.ee=new EventEmitter;this.sessionId=session.getSessionId();this.session.addEventListener("stream-destroyed-default",function(event){event.stream.removeVideo()});this.session.addEventListener("session-disconnected-default",function(){var s;for(var _i=0,_a=_this.openVidu.openVidu.getRemoteStreams();_i<_a.length;_i++){s=_a[_i];s.removeVideo()}if(_this.connection){for(var streamId in _this.connection.getStreams()){_this.connection.getStreams()[streamId].removeVideo()}}});this.session.addEventListener("update-connection-object",function(event){_this.connection=event.connection})}Session.prototype.connect=function(param1,param2,param3){if(param3){this.session.configure({sessionId:this.session.getSessionId(),participantId:param1,metadata:this.session.stringClientMetadata(param2),subscribeToStreams:false});this.session.connect(param1,param3)}else{this.session.configure({sessionId:this.session.getSessionId(),participantId:param1,metadata:"",subscribeToStreams:false});this.session.connect(param1,param2)}};Session.prototype.disconnect=function(){var _this=this;this.openVidu.openVidu.close(false);this.session.emitEvent("sessionDisconnected",[{preventDefault:function(){_this.session.removeEvent("session-disconnected-default")}}]);this.session.emitEvent("session-disconnected-default",[{}])};Session.prototype.publish=function(publisher){publisher.session=this;publisher.stream.publish()};Session.prototype.unpublish=function(publisher){this.session.unpublish(publisher.stream)};Session.prototype.on=function(eventName,callback){this.session.addEventListener(eventName,function(event){if(event){console.info("Event '"+eventName+"' triggered by 'Session'",event)}else{console.info("Event '"+eventName+"' triggered by 'Session'")}callback(event)})};Session.prototype.once=function(eventName,callback){this.session.addOnceEventListener(eventName,function(event){callback(event)})};Session.prototype.off=function(eventName,eventHandler){this.session.removeListener(eventName,eventHandler)};Session.prototype.subscribe=function(param1,param2,param3){this.session.subscribe(param1);var subscriber=new Subscriber_1.Subscriber(param1,param2);param1.playOnlyVideo(param2,null);return subscriber};Session.prototype.unsubscribe=function(subscriber){this.session.unsuscribe(subscriber.stream);subscriber.stream.removeVideo()};Session.prototype.onStreamCreated=function(callback){this.session.addEventListener("streamCreated",function(streamEvent){callback(streamEvent.stream)})};Session.prototype.onStreamDestroyed=function(callback){this.session.addEventListener("streamDestroyed",function(streamEvent){callback(streamEvent.stream)})};Session.prototype.onParticipantJoined=function(callback){this.session.addEventListener("participant-joined",function(participantEvent){callback(participantEvent.connection)})};Session.prototype.onParticipantLeft=function(callback){this.session.addEventListener("participant-left",function(participantEvent){callback(participantEvent.connection)})};Session.prototype.onParticipantPublished=function(callback){this.session.addEventListener("participant-published",function(participantEvent){callback(participantEvent.connection)})};Session.prototype.onParticipantEvicted=function(callback){this.session.addEventListener("participant-evicted",function(participantEvent){callback(participantEvent.connection)})};Session.prototype.onRoomClosed=function(callback){this.session.addEventListener("room-closed",function(roomEvent){callback(roomEvent.room)})};Session.prototype.onLostConnection=function(callback){this.session.addEventListener("lost-connection",function(roomEvent){callback(roomEvent.room)})};Session.prototype.onMediaError=function(callback){this.session.addEventListener("error-media",function(errorEvent){callback(errorEvent.error)})};return Session}();exports.Session=Session},{"./Subscriber":48,"wolfy87-eventemitter":32}],48:[function(require,module,exports){"use strict";Object.defineProperty(exports,"__esModule",{value:true});var EventEmitter=require("wolfy87-eventemitter");var Subscriber=function(){function Subscriber(stream,parentId){this.ee=new EventEmitter;this.stream=stream;if(document.getElementById(parentId)!=null){this.element=document.getElementById(parentId)}}Subscriber.prototype.on=function(eventName,callback){var _this=this;this.ee.addListener(eventName,function(event){if(event){console.info("Event '"+eventName+"' triggered by 'Subscriber'",event)}else{console.info("Event '"+eventName+"' triggered by 'Subscriber'")}callback(event)});if(eventName=="videoElementCreated"){if(this.stream.isVideoELementCreated){this.ee.emitEvent("videoElementCreated",[{element:this.stream.getVideoElement()}])}else{this.stream.addOnceEventListener("video-element-created-by-stream",function(element){console.warn("Subscriber emitting videoElementCreated");_this.id=element.id;_this.ee.emitEvent("videoElementCreated",[{element:element}])})}}if(eventName=="videoPlaying"){var video=this.stream.getVideoElement();if(!this.stream.displayMyRemote()&&video&&video.currentTime>0&&video.paused==false&&video.ended==false&&video.readyState==4){this.ee.emitEvent("videoPlaying",[{element:this.stream.getVideoElement()}])}else{this.stream.addOnceEventListener("video-is-playing",function(element){_this.ee.emitEvent("videoPlaying",[{element:element.element}])})}}};return Subscriber}();exports.Subscriber=Subscriber},{"wolfy87-eventemitter":32}],49:[function(require,module,exports){"use strict";Object.defineProperty(exports,"__esModule",{value:true});var Stream_1=require("./Stream");var Connection=function(){function Connection(openVidu,local,room,options){this.openVidu=openVidu;this.local=local;this.room=room;this.options=options;this.streams={};this.streamsOpts=[];console.info("'Connection' created ("+(local?"local":"remote")+")"+(local?"":", with 'connectionId' ["+(options?options.id:"")+"] "));if(options){this.connectionId=options.id;this.data=options.metadata;if(options.streams){this.initStreams(options)}}}Connection.prototype.addStream=function(stream){this.streams[stream.getIdInParticipant()]=stream;this.room.getStreams()[stream.getIdInParticipant()]=stream};Connection.prototype.getStreams=function(){return this.streams};Connection.prototype.dispose=function(){for(var key in this.streams){this.streams[key].dispose()}};Connection.prototype.sendIceCandidate=function(candidate){console.debug(this.local?"Local":"Remote","candidate for",this.connectionId,JSON.stringify(candidate));this.openVidu.sendRequest("onIceCandidate",{endpointName:this.connectionId,candidate:candidate.candidate,sdpMid:candidate.sdpMid,sdpMLineIndex:candidate.sdpMLineIndex},function(error,response){if(error){console.error("Error sending ICE candidate: "+JSON.stringify(error))}})};Connection.prototype.initStreams=function(options){for(var _i=0,_a=options.streams;_i<_a.length;_i++){var streamOptions=_a[_i];var streamOpts={id:streamOptions.id,connection:this,sendAudio:streamOptions.sendAudio,sendVideo:streamOptions.sendVideo,recvAudio:streamOptions.audioActive==undefined?true:streamOptions.audioActive,recvVideo:streamOptions.videoActive==undefined?true:streamOptions.videoActive,activeAudio:streamOptions.activeAudio,activeVideo:streamOptions.activeVideo,data:streamOptions.data,mediaConstraints:streamOptions.mediaConstraints};var stream=new Stream_1.Stream(this.openVidu,false,this.room,streamOpts);this.addStream(stream);this.streamsOpts.push(streamOpts)}console.info("Remote 'Connection' with 'connectionId' ["+this.connectionId+"] is now configured for receiving Streams with options: ",this.streamsOpts)};return Connection}();exports.Connection=Connection},{"./Stream":52}],50:[function(require,module,exports){"use strict";Object.defineProperty(exports,"__esModule",{value:true});var SessionInternal_1=require("./SessionInternal");var Stream_1=require("./Stream");var RpcBuilder=require("../KurentoUtils/kurento-jsonrpc");var OpenViduInternal=function(){function OpenViduInternal(){this.remoteStreams=[]}OpenViduInternal.prototype.initSession=function(sessionId){console.info("'Session' initialized with 'sessionId' ["+sessionId+"]");this.session=new SessionInternal_1.SessionInternal(this,sessionId);return this.session};OpenViduInternal.prototype.initPublisherTagged=function(parentId,cameraOptions,callback){var _this=this;this.getCamera(cameraOptions);if(callback==null){this.camera.requestCameraAccess(function(error,camera){if(error){console.error("Error accessing the camera",error)}else{_this.camera.setVideoElement(_this.cameraReady(camera,parentId))}});return this.camera}else{this.camera.requestCameraAccess(function(error,camera){if(error){callback(error)}else{_this.camera.setVideoElement(_this.cameraReady(camera,parentId));callback(undefined)}});return this.camera}};OpenViduInternal.prototype.cameraReady=function(camera,parentId){this.camera=camera;var videoElement=this.camera.playOnlyVideo(parentId,null);this.camera.emitStreamReadyEvent();return videoElement};OpenViduInternal.prototype.initPublisher=function(cameraOptions,callback){this.getCamera(cameraOptions);this.camera.requestCameraAccess(function(error,camera){if(error)callback(error);else callback(undefined)})};OpenViduInternal.prototype.getLocalStream=function(){return this.camera};OpenViduInternal.prototype.getRemoteStreams=function(){return this.remoteStreams};OpenViduInternal.prototype.getWsUri=function(){return this.wsUri};OpenViduInternal.prototype.setWsUri=function(wsUri){this.wsUri=wsUri};OpenViduInternal.prototype.getSecret=function(){return this.secret};OpenViduInternal.prototype.setSecret=function(secret){this.secret=secret};OpenViduInternal.prototype.getOpenViduServerURL=function(){return"https://"+this.wsUri.split("wss://")[1].split("/room")[0]};OpenViduInternal.prototype.getRoom=function(){return this.session};OpenViduInternal.prototype.connect=function(callback){this.callback=callback;this.initJsonRpcClient(this.wsUri)};OpenViduInternal.prototype.initJsonRpcClient=function(wsUri){var config={heartbeat:3e3,sendCloseMessage:false,ws:{uri:wsUri,useSockJS:false,onconnected:this.connectCallback.bind(this),ondisconnect:this.disconnectCallback.bind(this),onreconnecting:this.reconnectingCallback.bind(this),onreconnected:this.reconnectedCallback.bind(this)},rpc:{requestTimeout:15e3,participantJoined:this.onParticipantJoined.bind(this),participantPublished:this.onParticipantPublished.bind(this),participantUnpublished:this.onParticipantLeft.bind(this),participantLeft:this.onParticipantLeft.bind(this),participantEvicted:this.onParticipantEvicted.bind(this),sendMessage:this.onNewMessage.bind(this),iceCandidate:this.iceCandidateEvent.bind(this),mediaError:this.onMediaError.bind(this),custonNotification:this.customNotification.bind(this)}};this.jsonRpcClient=new RpcBuilder.clients.JsonRpcClient(config)};OpenViduInternal.prototype.customNotification=function(params){if(this.isRoomAvailable()){this.session.emitEvent("custom-message-received",[{params:params}])}};OpenViduInternal.prototype.connectCallback=function(error){if(error){this.callback(error)}else{this.callback(null)}};OpenViduInternal.prototype.isRoomAvailable=function(){if(this.session!==undefined&&this.session instanceof SessionInternal_1.SessionInternal){return true}else{console.warn("Room instance not found");return false}};OpenViduInternal.prototype.disconnectCallback=function(){console.warn("Websocket connection lost");if(this.isRoomAvailable()){this.session.onLostConnection()}else{alert("Connection error. Please reload page.")}};OpenViduInternal.prototype.reconnectingCallback=function(){console.warn("Websocket connection lost (reconnecting)");if(this.isRoomAvailable()){this.session.onLostConnection()}else{alert("Connection error. Please reload page.")}};OpenViduInternal.prototype.reconnectedCallback=function(){console.warn("Websocket reconnected")};OpenViduInternal.prototype.onParticipantJoined=function(params){if(this.isRoomAvailable()){this.session.onParticipantJoined(params)}};OpenViduInternal.prototype.onParticipantPublished=function(params){if(this.isRoomAvailable()){this.session.onParticipantPublished(params)}};OpenViduInternal.prototype.onParticipantLeft=function(params){if(this.isRoomAvailable()){this.session.onParticipantLeft(params)}};OpenViduInternal.prototype.onParticipantEvicted=function(params){if(this.isRoomAvailable()){this.session.onParticipantEvicted(params)}};OpenViduInternal.prototype.onNewMessage=function(params){if(this.isRoomAvailable()){this.session.onNewMessage(params)}};OpenViduInternal.prototype.iceCandidateEvent=function(params){if(this.isRoomAvailable()){this.session.recvIceCandidate(params)}};OpenViduInternal.prototype.onRoomClosed=function(params){if(this.isRoomAvailable()){this.session.onRoomClosed(params)}};OpenViduInternal.prototype.onMediaError=function(params){if(this.isRoomAvailable()){this.session.onMediaError(params)}};OpenViduInternal.prototype.setRpcParams=function(params){this.rpcParams=params};OpenViduInternal.prototype.sendRequest=function(method,params,callback){if(params&¶ms instanceof Function){callback=params;params=undefined}params=params||{};if(this.rpcParams&&this.rpcParams!==null&&this.rpcParams!==undefined){for(var index in this.rpcParams){if(this.rpcParams.hasOwnProperty(index)){params[index]=this.rpcParams[index];console.debug("RPC param added to request {"+index+": "+this.rpcParams[index]+"}")}}}console.debug('Sending request: {method:"'+method+'", params: '+JSON.stringify(params)+"}");this.jsonRpcClient.send(method,params,callback)};OpenViduInternal.prototype.close=function(forced){if(this.isRoomAvailable()){this.session.leave(forced,this.jsonRpcClient)}};OpenViduInternal.prototype.disconnectParticipant=function(stream){if(this.isRoomAvailable()){this.session.disconnect(stream)}};OpenViduInternal.prototype.getCamera=function(options){if(this.camera){return this.camera}options=options||{sendAudio:true,sendVideo:true,activeAudio:true,activeVideo:true,data:true,mediaConstraints:{audio:true,video:{width:{ideal:1280}}}};options.connection=this.session.getLocalParticipant();this.camera=new Stream_1.Stream(this,true,this.session,options);return this.camera};OpenViduInternal.prototype.sendMessage=function(room,user,message){this.sendRequest("sendMessage",{message:message,userMessage:user,roomMessage:room},function(error,response){if(error){console.error(error)}})};OpenViduInternal.prototype.sendCustomRequest=function(params,callback){this.sendRequest("customRequest",params,callback)};OpenViduInternal.prototype.toggleLocalVideoTrack=function(activate){this.getCamera().getWebRtcPeer().videoEnabled=activate};OpenViduInternal.prototype.toggleLocalAudioTrack=function(activate){this.getCamera().getWebRtcPeer().audioEnabled=activate};OpenViduInternal.prototype.publishLocalVideoAudio=function(){this.toggleLocalVideoTrack(true);this.toggleLocalAudioTrack(true)};OpenViduInternal.prototype.unpublishLocalVideoAudio=function(){this.toggleLocalVideoTrack(false);this.toggleLocalAudioTrack(false)};OpenViduInternal.prototype.generateMediaConstraints=function(cameraOptions){var mediaConstraints={audio:cameraOptions.audio,video:{}};if(!cameraOptions.video){mediaConstraints.video=false}else{var w=void 0,h=void 0;switch(cameraOptions.quality){case"LOW":w=320;h=240;break;case"MEDIUM":w=640;h=480;break;case"HIGH":w=1280;h=720;break;default:w=640;h=480}mediaConstraints.video["width"]={exact:w};mediaConstraints.video["height"]={exact:h}}return mediaConstraints};return OpenViduInternal}();exports.OpenViduInternal=OpenViduInternal},{"../KurentoUtils/kurento-jsonrpc":38,"./SessionInternal":51,"./Stream":52}],51:[function(require,module,exports){"use strict";Object.defineProperty(exports,"__esModule",{value:true});var Connection_1=require("./Connection");var EventEmitter=require("wolfy87-eventemitter");var SECRET_PARAM="?secret=";var SessionInternal=function(){function SessionInternal(openVidu,sessionId){this.openVidu=openVidu;this.ee=new EventEmitter;this.streams={};this.participants={};this.participantsSpeaking=[];this.connected=false;this.sessionId=this.getUrlWithoutSecret(sessionId);this.localParticipant=new Connection_1.Connection(this.openVidu,true,this);if(!this.openVidu.getWsUri()){this.processOpenViduUrl(sessionId)}}SessionInternal.prototype.processOpenViduUrl=function(url){this.openVidu.setSecret(this.getSecretFromUrl(url));this.openVidu.setWsUri(this.getFinalUrl(url))};SessionInternal.prototype.getSecretFromUrl=function(url){var secret="";if(url.indexOf(SECRET_PARAM)!==-1){secret=url.substring(url.lastIndexOf(SECRET_PARAM)+SECRET_PARAM.length,url.length)}return secret};SessionInternal.prototype.getUrlWithoutSecret=function(url){if(url.indexOf(SECRET_PARAM)!==-1){url=url.substring(0,url.lastIndexOf(SECRET_PARAM))}return url};SessionInternal.prototype.getFinalUrl=function(url){url=this.getUrlWithoutSecret(url).substring(0,url.lastIndexOf("/"))+"/room";if(url.indexOf(".ngrok.io")!==-1){url=url.replace("ws://","wss://");var regex=/\.ngrok\.io:\d+/;url=url.replace(regex,".ngrok.io")}else if(url.indexOf("localhost")!==-1||url.indexOf("127.0.0.1")!=-1){}return url};SessionInternal.prototype.connect=function(token,callback){var _this=this;this.openVidu.connect(function(error){if(error){callback("ERROR CONNECTING TO OPENVIDU")}else{if(!token){token=_this.randomToken()}var joinParams={token:token,session:_this.sessionId,metadata:_this.options.metadata,secret:_this.openVidu.getSecret(),dataChannels:false};if(_this.localParticipant){if(Object.keys(_this.localParticipant.getStreams()).some(function(streamId){return _this.streams[streamId].isDataChannelEnabled()})){joinParams.dataChannels=true}}_this.openVidu.sendRequest("joinRoom",joinParams,function(error,response){if(error){callback(error)}else{_this.connected=true;var exParticipants=response.value;_this.localParticipant.connectionId=response.id;_this.participants[response.id]=_this.localParticipant;var roomEvent={participants:new Array,streams:new Array};var length_1=exParticipants.length;for(var i=0;i0){_this.ee.emitEvent("update-main-speaker",[{participantId:_this.participantsSpeaking[_this.participantsSpeaking.length-1]}])}},this.updateSpeakerInterval)};SessionInternal.prototype.getLocalParticipant=function(){return this.localParticipant};SessionInternal.prototype.addEventListener=function(eventName,listener){this.ee.on(eventName,listener)};SessionInternal.prototype.addOnceEventListener=function(eventName,listener){this.ee.once(eventName,listener)};SessionInternal.prototype.removeListener=function(eventName,listener){this.ee.off(eventName,listener)};SessionInternal.prototype.removeEvent=function(eventName){this.ee.removeEvent(eventName)};SessionInternal.prototype.emitEvent=function(eventName,eventsArray){this.ee.emitEvent(eventName,eventsArray)};SessionInternal.prototype.subscribe=function(stream){stream.subscribe()};SessionInternal.prototype.unsuscribe=function(stream){console.info("Unsubscribing from "+stream.getId());this.openVidu.sendRequest("unsubscribeFromVideo",{sender:stream.getId()},function(error,response){if(error){console.error("Error unsubscribing from Subscriber",error)}else{console.info("Unsubscribed correctly from "+stream.getId())}})};SessionInternal.prototype.onParticipantPublished=function(options){var connection=this.participants[options.id];if(connection){options.metadata=connection.data;connection.options=options;connection.initStreams(options)}else{connection=new Connection_1.Connection(this.openVidu,false,this,options)}var pid=connection.connectionId;if(!(pid in this.participants)){console.debug("Remote Connection not found in connections list by its id ["+pid+"]")}else{console.debug("Remote Connection found in connections list by its id ["+pid+"]")}this.participants[pid]=connection;this.ee.emitEvent("participant-published",[{connection:connection}]);var streams=connection.getStreams();for(var key in streams){console.log("");var stream=streams[key];this.ee.emitEvent("streamCreated",[{stream:stream}]);if(this.subscribeToStreams){stream.subscribe()}this.openVidu.getRemoteStreams().push(stream)}};SessionInternal.prototype.onParticipantJoined=function(msg){var connection=new Connection_1.Connection(this.openVidu,false,this,msg);connection.creationTime=(new Date).getTime();var pid=connection.connectionId;if(!(pid in this.participants)){this.participants[pid]=connection}else{console.warn("Connection already exists in connections list with "+"the same connectionId, old:",this.participants[pid],", joined now:",connection);connection=this.participants[pid]}this.ee.emitEvent("participant-joined",[{connection:connection}]);this.ee.emitEvent("connectionCreated",[{connection:connection}])};SessionInternal.prototype.onParticipantLeft=function(msg){var _this=this;var connection=this.participants[msg.name];if(connection!==undefined){delete this.participants[msg.name];this.ee.emitEvent("participant-left",[{connection:connection}]);var streams=connection.getStreams();for(var key in streams){this.ee.emitEvent("streamDestroyed",[{stream:streams[key],preventDefault:function(){_this.ee.removeEvent("stream-destroyed-default")}}]);this.ee.emitEvent("stream-destroyed-default",[{stream:streams[key]}]);var index=this.openVidu.getRemoteStreams().indexOf(streams[key]);this.openVidu.getRemoteStreams().splice(index,1)}connection.dispose();this.ee.emitEvent("connectionDestroyed",[{connection:connection}])}else{console.warn("Participant "+msg.name+" unknown. Participants: "+JSON.stringify(this.participants))}};SessionInternal.prototype.onParticipantEvicted=function(msg){this.ee.emitEvent("participant-evicted",[{localParticipant:this.localParticipant}])};SessionInternal.prototype.onNewMessage=function(msg){console.info("New message: "+JSON.stringify(msg));var room=msg.room;var user=msg.user;var message=msg.message;if(user!==undefined){this.ee.emitEvent("newMessage",[{room:room,user:user,message:message}])}else{console.warn("User undefined in new message:",msg)}};SessionInternal.prototype.recvIceCandidate=function(msg){var candidate={candidate:msg.candidate,sdpMid:msg.sdpMid,sdpMLineIndex:msg.sdpMLineIndex};var connection=this.participants[msg.endpointName];if(!connection){console.error("Participant not found for endpoint "+msg.endpointName+". Ice candidate will be ignored.",candidate);return}var streams=connection.getStreams();var _loop_1=function(key){var stream=streams[key];stream.getWebRtcPeer().addIceCandidate(candidate,function(error){if(error){console.error("Error adding candidate for "+key+" stream of endpoint "+msg.endpointName+": "+error)}})};for(var key in streams){_loop_1(key)}};SessionInternal.prototype.onRoomClosed=function(msg){console.info("Room closed: "+JSON.stringify(msg));var room=msg.room;if(room!==undefined){this.ee.emitEvent("room-closed",[{room:room}])}else{console.warn("Room undefined in on room closed",msg)}};SessionInternal.prototype.onLostConnection=function(){if(!this.connected){console.warn("Not connected to room: if you are not debugging, this is probably a certificate error");if(window.confirm('If you are not debugging, this is probably a certificate error at "'+this.openVidu.getOpenViduServerURL()+'"\n\nClick OK to navigate and accept it')){location.assign(this.openVidu.getOpenViduServerURL()+"/accept-certificate")}return}console.warn("Lost connection in Session "+this.id);var room=this.id;if(room!==undefined){this.ee.emitEvent("lost-connection",[{room:room}])}else{console.warn("Room undefined when lost connection")}};SessionInternal.prototype.onMediaError=function(params){console.error("Media error: "+JSON.stringify(params));var error=params.error;if(error){this.ee.emitEvent("error-media",[{error:error}])}else{console.warn("Received undefined media error. Params:",params)}};SessionInternal.prototype.leave=function(forced,jsonRpcClient){forced=!!forced;console.info("Leaving Session (forced="+forced+")");if(this.connected&&!forced){this.openVidu.sendRequest("leaveRoom",function(error,response){if(error){console.error(error)}jsonRpcClient.close()})}else{jsonRpcClient.close()}this.connected=false;if(this.participants){for(var pid in this.participants){this.participants[pid].dispose();delete this.participants[pid]}}};SessionInternal.prototype.disconnect=function(stream){var connection=stream.getParticipant();if(!connection){console.error("Stream to disconnect has no participant",stream);return}delete this.participants[connection.connectionId];connection.dispose();if(connection===this.localParticipant){console.info("Unpublishing my media (I'm "+connection.connectionId+")");delete this.localParticipant;this.openVidu.sendRequest("unpublishVideo",function(error,response){if(error){console.error(error)}else{console.info("Media unpublished correctly")}})}else{this.unsuscribe(stream)}};SessionInternal.prototype.unpublish=function(stream){var connection=stream.getParticipant();if(!connection){console.error("Stream to disconnect has no participant",stream);return}if(connection===this.localParticipant){delete this.participants[connection.connectionId];connection.dispose();console.info("Unpublishing my media (I'm "+connection.connectionId+")");delete this.localParticipant;this.openVidu.sendRequest("unpublishVideo",function(error,response){if(error){console.error(error)}else{console.info("Media unpublished correctly")}})}};SessionInternal.prototype.getStreams=function(){return this.streams};SessionInternal.prototype.addParticipantSpeaking=function(participantId){this.participantsSpeaking.push(participantId)};SessionInternal.prototype.removeParticipantSpeaking=function(participantId){var pos=-1;for(var i=0;i=16){userName=userName.substring(0,16)+"..."}name.appendChild(document.createTextNode(userName));name.id="name-"+this.getId();name.className="name";name.title=this.getId();this.showSpinner(thumbnailId);return this.playOnlyVideo(container,thumbnailId)};Stream.prototype.getIdInParticipant=function(){return this.id};Stream.prototype.getParticipant=function(){return this.connection};Stream.prototype.getId=function(){return this.connection.connectionId+"_"+this.id};Stream.prototype.getRTCPeerConnection=function(){return this.getWebRtcPeer().peerConnection};Stream.prototype.requestCameraAccess=function(callback){var _this=this;this.connection.addStream(this);var constraints=this.mediaConstraints;this.userMediaHasVideo(function(hasVideo){if(!hasVideo){constraints.video=false;_this.sendVideo=false;_this.requestCameraAccesAux(constraints,callback)}else{_this.requestCameraAccesAux(constraints,callback)}})};Stream.prototype.requestCameraAccesAux=function(constraints,callback){var _this=this;navigator.mediaDevices.getUserMedia(constraints).then(function(userStream){_this.cameraAccessSuccess(userStream,callback)}).catch(function(error){_this.accessIsDenied=true;_this.accessIsAllowed=false;_this.ee.emitEvent("access-denied-by-publisher");console.error("Access denied",error);callback(error,_this)})};Stream.prototype.cameraAccessSuccess=function(userStream,callback){this.accessIsAllowed=true;this.accessIsDenied=false;this.ee.emitEvent("access-allowed-by-publisher");if(userStream.getAudioTracks()[0]!=null){userStream.getAudioTracks()[0].enabled=this.activeAudio}if(userStream.getVideoTracks()[0]!=null){userStream.getVideoTracks()[0].enabled=this.activeVideo}this.wrStream=userStream;this.emitSrcEvent(this.wrStream);callback(undefined,this)};Stream.prototype.userMediaHasVideo=function(callback){navigator.mediaDevices.enumerateDevices().then(function(mediaDevices){var videoInput=mediaDevices.filter(function(deviceInfo){return deviceInfo.kind==="videoinput"})[0];callback(videoInput!=null)})};Stream.prototype.publishVideoCallback=function(error,sdpOfferParam,wp){var _this=this;if(error){return console.error("(publish) SDP offer error: "+JSON.stringify(error))}console.debug("Sending SDP offer to publish as "+this.getId(),sdpOfferParam);this.openVidu.sendRequest("publishVideo",{sdpOffer:sdpOfferParam,doLoopback:this.displayMyRemote()||false,audioActive:this.sendAudio,videoActive:this.sendVideo},function(error,response){if(error){console.error("Error on publishVideo: "+JSON.stringify(error))}else{_this.processSdpAnswer(response.sdpAnswer);console.info("'Publisher' succesfully published to session")}})};Stream.prototype.startVideoCallback=function(error,sdpOfferParam,wp){var _this=this;if(error){return console.error("(subscribe) SDP offer error: "+JSON.stringify(error))}console.debug("Sending SDP offer to subscribe to "+this.getId(),sdpOfferParam);this.openVidu.sendRequest("receiveVideoFrom",{sender:this.getId(),sdpOffer:sdpOfferParam},function(error,response){if(error){console.error("Error on recvVideoFrom: "+JSON.stringify(error))}else{_this.processSdpAnswer(response.sdpAnswer)}})};Stream.prototype.initWebRtcPeer=function(sdpOfferCallback){var _this=this;if(this.local){var userMediaConstraints={audio:this.sendAudio,video:this.sendVideo};var options={videoStream:this.wrStream,mediaConstraints:userMediaConstraints,onicecandidate:this.connection.sendIceCandidate.bind(this.connection)};if(this.dataChannel){options.dataChannelConfig={id:this.getChannelName(),onopen:this.onDataChannelOpen,onclose:this.onDataChannelClosed};options.dataChannels=true}if(this.displayMyRemote()){this.wp=kurentoUtils.WebRtcPeer.WebRtcPeerSendrecv(options,function(error){if(error){return console.error(error)}_this.wp.generateOffer(sdpOfferCallback.bind(_this))})}else{this.wp=kurentoUtils.WebRtcPeer.WebRtcPeerSendonly(options,function(error){if(error){return console.error(error)}_this.wp.generateOffer(sdpOfferCallback.bind(_this))})}}else{var offerConstraints={audio:this.recvAudio,video:this.recvVideo};console.debug("'Session.subscribe(Stream)' called. Constraints of generate SDP offer",offerConstraints);var options={onicecandidate:this.connection.sendIceCandidate.bind(this.connection),mediaConstraints:offerConstraints};this.wp=kurentoUtils.WebRtcPeer.WebRtcPeerRecvonly(options,function(error){if(error){return console.error(error)}_this.wp.generateOffer(sdpOfferCallback.bind(_this))})}console.debug("Waiting for SDP offer to be generated ("+(this.local?"local":"remote")+" 'Stream': "+this.getId()+")")};Stream.prototype.publish=function(){var _this=this;if(this.isReady){this.initWebRtcPeer(this.publishVideoCallback)}else{this.ee.once("stream-ready",function(streamEvent){_this.publish()})}};Stream.prototype.subscribe=function(){this.initWebRtcPeer(this.startVideoCallback)};Stream.prototype.processSdpAnswer=function(sdpAnswer){var _this=this;var answer=new RTCSessionDescription({type:"answer",sdp:sdpAnswer});console.debug(this.getId()+": set peer connection with recvd SDP answer",sdpAnswer);var participantId=this.getId();var pc=this.wp.peerConnection;pc.setRemoteDescription(answer,function(){if(!_this.local||_this.displayMyRemote()){_this.wrStream=pc.getRemoteStreams()[0];console.debug("Peer remote stream",_this.wrStream);if(_this.wrStream!=undefined){_this.emitSrcEvent(_this.wrStream);if(_this.wrStream.getAudioTracks()[0]!=null){_this.speechEvent=kurentoUtils.WebRtcPeer.hark(_this.wrStream,{threshold:_this.room.thresholdSpeaker});_this.speechEvent.on("speaking",function(){_this.room.addParticipantSpeaking(participantId);_this.room.emitEvent("stream-speaking",[{participantId:participantId}])});_this.speechEvent.on("stopped_speaking",function(){_this.room.removeParticipantSpeaking(participantId);_this.room.emitEvent("stream-stopped-speaking",[{participantId:participantId}])})}}for(var _i=0,_a=_this.videoElements;_i<_a.length;_i++){var videoElement=_a[_i];var thumbnailId=videoElement.thumb;var video=videoElement.video;video.srcObject=_this.wrStream;video.onplaying=function(){if(_this.local&&_this.displayMyRemote()){console.info("Your own remote 'Stream' with id ["+_this.getId()+"] video is now playing");_this.ee.emitEvent("remote-video-is-playing",[{element:_this.video}])}else if(!_this.local&&!_this.displayMyRemote()){console.info("Remote 'Stream' with id ["+_this.getId()+"] video is now playing");_this.ee.emitEvent("video-is-playing",[{element:_this.video}])}}}_this.room.emitEvent("stream-subscribed",[{stream:_this}])}},function(error){console.error(_this.getId()+": Error setting SDP to the peer connection: "+JSON.stringify(error))})};Stream.prototype.unpublish=function(){if(this.wp){this.wp.dispose()}else{if(this.wrStream){this.wrStream.getAudioTracks().forEach(function(track){track.stop&&track.stop()});this.wrStream.getVideoTracks().forEach(function(track){track.stop&&track.stop()})}}if(this.speechEvent){this.speechEvent.stop()}console.info(this.getId()+": Stream '"+this.id+"' unpublished")};Stream.prototype.dispose=function(){function disposeElement(element){if(element&&element.parentNode){element.parentNode.removeChild(element)}}this.elements.forEach(function(e){return disposeElement(e)});disposeElement("progress-"+this.getId());if(this.wp){this.wp.dispose()}else{if(this.wrStream){this.wrStream.getAudioTracks().forEach(function(track){track.stop&&track.stop()});this.wrStream.getVideoTracks().forEach(function(track){track.stop&&track.stop()})}}if(this.speechEvent){this.speechEvent.stop()}console.info((this.local?"Local ":"Remote ")+"'Stream' with id ["+this.getId()+"]' has been succesfully disposed")};return Stream}();exports.Stream=Stream},{"../KurentoUtils/kurento-utils-js":43,"webrtc-adapter":21,"wolfy87-eventemitter":32}]},{},[44]); \ No newline at end of file diff --git a/openvidu-browser/static/js/openvidu-browser-1.1.1-dev.min.js.map b/openvidu-browser/static/js/openvidu-browser-1.1.1-dev.min.js.map index d2cb098e..479eb484 100644 --- a/openvidu-browser/static/js/openvidu-browser-1.1.1-dev.min.js.map +++ b/openvidu-browser/static/js/openvidu-browser-1.1.1-dev.min.js.map @@ -1 +1 @@ -{"version":3,"sources":["../../node_modules/browser-pack/_prelude.js","../../node_modules/events/events.js","../../node_modules/freeice/index.js","../../node_modules/freeice/stun.json","../../node_modules/freeice/turn.json","../../node_modules/hark/hark.js","../../node_modules/inherits/inherits_browser.js","../../node_modules/merge/merge.js","../../node_modules/normalice/index.js","../../node_modules/rtcpeerconnection-shim/rtcpeerconnection.js","../../node_modules/sdp-transform/lib/grammar.js","../../node_modules/sdp-transform/lib/index.js","../../node_modules/sdp-transform/lib/parser.js","../../node_modules/sdp-transform/lib/writer.js","../../node_modules/sdp-translator/lib/array-equals.js","../../node_modules/sdp-translator/lib/index.js","../../node_modules/sdp-translator/lib/interop.js","../../node_modules/sdp-translator/lib/transform.js","../../node_modules/sdp/sdp.js","../../node_modules/ua-parser-js/src/ua-parser.js","../../node_modules/uuid/rng-browser.js","../../node_modules/uuid/uuid.js","../../node_modules/webrtc-adapter/src/js/adapter_core.js","../../node_modules/webrtc-adapter/src/js/adapter_factory.js","../../node_modules/webrtc-adapter/src/js/chrome/chrome_shim.js","../../node_modules/webrtc-adapter/src/js/chrome/getusermedia.js","../../node_modules/webrtc-adapter/src/js/common_shim.js","../../node_modules/webrtc-adapter/src/js/edge/edge_shim.js","../../node_modules/webrtc-adapter/src/js/edge/getusermedia.js","../../node_modules/webrtc-adapter/src/js/firefox/firefox_shim.js","../../node_modules/webrtc-adapter/src/js/firefox/getusermedia.js","../../node_modules/webrtc-adapter/src/js/safari/safari_shim.js","../../node_modules/webrtc-adapter/src/js/utils.js","../../node_modules/wildemitter/wildemitter.js","../../node_modules/wolfy87-eventemitter/EventEmitter.js","../KurentoUtils/kurento-jsonrpc/Mapper.js","../KurentoUtils/kurento-jsonrpc/clients/index.js","../KurentoUtils/kurento-jsonrpc/clients/jsonrpcclient.js","../KurentoUtils/kurento-jsonrpc/clients/transports/index.js","../KurentoUtils/kurento-jsonrpc/clients/transports/webSocketWithReconnection.js","../KurentoUtils/kurento-jsonrpc/index.js","../KurentoUtils/kurento-jsonrpc/packers/JsonRPC.js","../KurentoUtils/kurento-jsonrpc/packers/XmlRPC.js","../KurentoUtils/kurento-jsonrpc/packers/index.js","../KurentoUtils/kurento-utils-js/WebRtcPeer.js","../KurentoUtils/kurento-utils-js/index.js","Main.ts","OpenVidu.ts","Publisher.ts","Session.ts","Subscriber.ts","../OpenViduInternal/Connection.ts","../OpenViduInternal/OpenViduInternal.ts","../OpenViduInternal/SessionInternal.ts","../OpenViduInternal/Stream.ts"],"names":["e","t","n","r","s","o","u","a","require","i","f","Error","code","l","exports","call","length","1","module","EventEmitter","this","_events","_maxListeners","undefined","prototype","defaultMaxListeners","setMaxListeners","isNumber","isNaN","TypeError","emit","type","er","handler","len","args","listeners","error","isObject","arguments","err","context","isUndefined","isFunction","Array","slice","apply","addListener","listener","m","newListener","push","warned","console","trace","on","once","fired","g","removeListener","list","position","splice","removeAllListeners","key","ret","listenerCount","evlistener","emitter","arg","normalice","freeice","opts","servers","stun","turn","stunCount","turnCount","selected","getServers","count","out","input","concat","idx","Math","random","map","url","String","WildEmitter","getMaxVolume","analyser","fftBins","maxVolume","Infinity","getFloatFrequencyData","ii","audioContextType","window","AudioContext","webkitAudioContext","audioContext","stream","options","harker","smoothing","interval","threshold","play","history","running","sourceNode","createAnalyser","fftSize","smoothingTimeConstant","Float32Array","jquery","HTMLAudioElement","HTMLVideoElement","createMediaElementSource","createMediaStreamSource","connect","destination","speaking","setThreshold","setInterval","stop","speakingHistory","looper","setTimeout","currentVolume","shift","Object","create","inherits","ctor","superCtor","super_","constructor","value","enumerable","writable","configurable","TempCtor","isNode","Public","clone","merge","publicName","recursive","output","typeOf","index","size","merge_recursive","base","extend","argv","result","item","sitem","toString","toLowerCase","protocols","protocol","parts","trim","indexOf","split","username","credential","urls","SDPUtils","writeMediaSection","transceiver","caps","dtlsRole","sdp","writeRtpDescription","kind","writeIceParameters","iceGatherer","getLocalParameters","writeDtlsParameters","dtlsTransport","mid","direction","rtpSender","rtpReceiver","msid","id","track","sendEncodingParameters","ssrc","rtx","localCName","filterIceServers","iceServers","edgeVersion","hasTurn","JSON","parse","stringify","filter","server","warn","isString","validTurn","getCommonCapabilities","localCapabilities","remoteCapabilities","commonCapabilities","codecs","headerExtensions","fecMechanisms","findCodecByPayloadType","pt","parseInt","payloadType","preferredPayloadType","rtxCapabilityMatches","lRtx","rRtx","lCodecs","rCodecs","lCodec","parameters","apt","rCodec","name","forEach","clockRate","numChannels","min","rtcpFeedback","fb","j","parameter","lHeaderExtension","rHeaderExtension","uri","isActionAllowedInSignalingState","action","signalingState","offer","setLocalDescription","setRemoteDescription","answer","maybeAddCandidate","iceTransport","candidate","alreadyAdded","getRemoteCandidates","find","remoteCandidate","foundation","ip","port","priority","addRemoteCandidate","RTCPeerConnection","config","self","_eventTarget","document","createDocumentFragment","method","bind","onicecandidate","onaddstream","ontrack","onremovestream","onsignalingstatechange","oniceconnectionstatechange","onicegatheringstatechange","onnegotiationneeded","ondatachannel","canTrickleIceCandidates","needNegotiation","localStreams","remoteStreams","localDescription","remoteDescription","iceConnectionState","iceGatheringState","usingBundle","bundlePolicy","rtcpMuxPolicy","iceTransportPolicy","_iceGatherers","iceCandidatePoolSize","RTCIceGatherer","gatherPolicy","_config","transceivers","_sdpSessionId","generateSessionId","_sdpSessionVersion","_dtlsRole","_emitGatheringStateChange","event","Event","dispatchEvent","getConfiguration","getLocalStreams","getRemoteStreams","_createTransceiver","hasBundleTransport","recvEncodingParameters","wantReceive","transports","_createIceAndDtlsTransports","addTrack","_maybeFireNegotiationNeeded","RTCRtpSender","addStream","getTracks","clonedStream","clonedTrack","addEventListener","enabled","removeStream","getSenders","getReceivers","_createIceGatherer","sdpMLineIndex","defineProperty","candidates","bufferCandidates","end","keys","state","_gather","onlocalcandidate","removeEventListener","evt","sdpMid","cand","component","writeCandidate","sections","splitSections","join","complete","every","RTCIceTransport","onicestatechange","_updateConnectionState","RTCDtlsTransport","ondtlsstatechange","onerror","_disposeIceAndDtlsTransports","_transceive","send","recv","params","encodings","rtcp","cname","compound","rtcpParameters","p","receive","description","Promise","resolve","reject","sessionpart","mediaSection","parseRtpParameters","isIceLite","matchPrefix","rejected","isRejected","isDatachannel","remoteIceParameters","getIceParameters","remoteDtlsParameters","getDtlsParameters","role","start","_updateSignalingState","cb","streams","receiverList","iceOptions","substr","lines","splitLines","getKind","getDirection","remoteMsid","parseMsid","getMid","generateIdentifier","parseRtpEncodingParameters","parseRtcpParameters","isComplete","cands","parseCandidate","setTransport","setRemoteCandidates","RTCRtpReceiver","getCapabilities","codec","isNewTrack","MediaStream","get","default","sid","receiver","trackEvent","close","newState","states","new","closed","connecting","checking","connected","completed","disconnected","failed","createOffer","offerOptions","numAudioTracks","numVideoTracks","mandatory","optional","offerToReceiveAudio","offerToReceiveVideo","writeSessionBoilerplate","getLocalCandidates","desc","RTCSessionDescription","createAnswer","mediaSectionsInOffer","localTrack","getAudioTracks","getVideoTracks","hasRtx","c","reducedSize","addIceCandidate","candidateString","getStats","promises","fixStatsType","stat","inboundrtp","outboundrtp","candidatepair","localcandidate","remotecandidate","results","Map","all","then","res","set","grammar","v","reg","names","format","z","b","rate","address","subtype","sessionConfig","str","raddr","tcptype","generation","objs","obj","parser","writer","write","parseFmtpConfig","parsePayloads","parseRemoteCandidates","toIntIfInt","Number","attachProperties","match","location","rawName","parseReg","content","needsBlank","keyLocation","validLine","RegExp","test","session","media","rtp","fmtp","fmtpReducer","acc","expr","reduce","formatRegExp","formatStr","replace","x","makeLine","Function","defaultOuterOrder","defaultInnerOrder","version","mLine","payloads","outerOrder","innerOrder","el","arrayEquals","array","Interop","transform","cache","mlB2UMap","mlU2BMap","candidateToUnifiedPlan","RTCIceCandidate","candidateToPlanB","getFirstSendingIndexFromAnswer","isArray","toPlanB","rewrite","uLine","type2bl","types","rtcpMux","sources","ssrcGroups","bundleOnly","unshift","groups","some","group","mids","msidSemantic","semantic","token","resStr","addSetupAttr","setup","toUnifiedPlan","hasBundle","sort","mustBeBundle","cached","recvonlySsrcs","audio","video","mid2ul","bIdx","uIdx","sources2ul","iceUfrag","icePwd","fingerprint","rtcpFb","bLine","hash","ssrc2group","ssrcGroup","ssrcs","ssrc2ml","related","done","source","attribute","blob","line","part","prefix","substring","relatedAddress","relatedPort","tcpType","ufrag","usernameFragment","toUpperCase","parseIceOptions","parseRtpMap","parsed","writeRtpMap","parseExtmap","writeExtmap","headerExtension","preferredId","parseFmtp","kv","writeFmtp","param","parseRtcpFb","writeRtcpFb","parseSsrcMedia","sp","colon","parseFingerprint","algorithm","fingerprints","setupType","fp","iceParameters","password","mline","rtpmapline","fmtps","maxptime","extension","encodingParameters","hasRed","hasUlpfec","primarySsrc","secondarySsrc","flows","encParam","codecPayloadType","fec","mechanism","bandwidth","maxBitrate","remoteSsrc","rsize","mux","spec","planB","sessId","sessVer","sessionId","parseMLine","fmt","LIBVERSION","EMPTY","UNKNOWN","FUNC_TYPE","UNDEF_TYPE","OBJ_TYPE","STR_TYPE","MAJOR","MODEL","NAME","TYPE","VENDOR","VERSION","ARCHITECTURE","CONSOLE","MOBILE","TABLET","SMARTTV","WEARABLE","EMBEDDED","util","regexes","extensions","margedRegexes","has","str1","str2","lowerize","major","mapper","rgx","ua","arrays","k","q","matches","regex","props","exec","maps","browser","oldsafari","1.0","1.2","1.3","2.0","2.0.2","2.0.3","2.0.4","?","device","amazon","model","Fire Phone","sprint","Evo Shift 4G","vendor","HTC","Sprint","os","windows","ME","NT 3.11","NT 4.0","2000","XP","Vista","7","8","8.1","10","RT","cpu","engine","Browser","CPU","arch","Device","Engine","OS","UAParser","uastring","getResult","navigator","userAgent","rgxmap","getBrowser","getCPU","getDevice","getEngine","getOS","getUA","setUA","BROWSER","DEVICE","ENGINE","define","amd","$","jQuery","Zepto","prop","rng","crypto","global","msCrypto","getRandomValues","_rnds8","Uint8Array","whatwgRNG","_rnds","_rng","_byteToHex","_hexToByte","buf","offset","oct","unparse","bth","_seedBytes","_nodeId","_clockseq","_lastMSecs","_lastNSecs","v1","clockseq","msecs","Date","getTime","nsecs","dt","tl","tmh","node","v4","rnds","uuid","adapterFactory","utils","dependencies","shimChrome","shimFirefox","shimEdge","shimSafari","hasOwnProperty","logging","log","browserDetails","detectBrowser","adapter","extractVersion","disableLog","disableWarnings","chromeShim","edgeShim","firefoxShim","safariShim","commonShim","shimPeerConnection","browserShim","shimCreateObjectURL","shimGetUserMedia","shimMediaStream","shimSourceObject","shimOnTrack","shimAddTrackRemoveTrack","shimGetSendersWithDtmf","shimRTCIceCandidate","shimReplaceTrack","shimRTCIceServerUrls","shimCallbacksAPI","shimLocalStreamsAPI","shimRemoteStreamsAPI","shimTrackEventTransceiver","webkitMediaStream","_ontrack","origSetRemoteDescription","pc","_ontrackpoly","te","shimSenderWithDtmf","dtmf","_dtmf","createDTMFSender","_pc","_senders","origAddTrack","sender","origRemoveTrack","removeTrack","origAddStream","origRemoveStream","_streams","origGetSenders","senders","URL","HTMLMediaElement","_srcObject","src","revokeObjectURL","createObjectURL","origGetLocalStreams","nativeStreams","_reverseStreams","alreadyExists","DOMException","newStream","oldStream","replaceInternalStreamId","internalId","externalStream","internalStream","replaceExternalStreamId","nativeMethod","isLegacyCall","origSetLocalDescription","origLocalDescription","getOwnPropertyDescriptor","isLocal","streamid","hasTrack","pcConfig","pcConstraints","iceTransports","webkitRTCPeerConnection","generateCertificate","OrigPeerConnection","newIceServers","deprecated","origGetStats","selector","successCallback","errorCallback","fixChromeStats_","response","standardReport","reports","report","standardStats","timestamp","makeMapStats","stats","successCallbackWrapper_","promise","nativeAddIceCandidate","constraintsToChrome_","cc","ideal","exact","max","oldname_","charAt","oc","mix","advanced","shimConstraints_","constraints","func","remap","face","facingMode","getSupportedFacingModeLies","mediaDevices","getSupportedConstraints","enumerateDevices","devices","d","dev","label","deviceId","shimError_","PermissionDeniedError","InvalidStateError","DevicesNotFoundError","ConstraintNotSatisfiedError","TrackStartError","MediaDeviceFailedDueToShutdown","MediaDeviceKillSwitchOn","message","constraint","constraintName","getUserMedia_","onSuccess","onError","webkitGetUserMedia","getUserMedia","getUserMediaPromise_","kinds","MediaStreamTrack","getSources","groupId","echoCancellation","frameRate","height","width","origGetUserMedia","cs","wrapPeerConnectionEvent","eventNameToWrap","wrapper","proto","nativeAddEventListener","nativeEventName","wrappedCallback","_eventMap","nativeRemoveEventListener","unwrappedCb","NativeRTCIceCandidate","nativeCandidate","parsedCandidate","augmentedCandidate","assign","toJSON","nativeCreateObjectURL","nativeRevokeObjectURL","newId","delete","dsc","srcObject","nativeSetAttribute","setAttribute","shimRTCPeerConnection","origMSTEnabled","ev","RTCDtmfSender","replaceTrack","setTrack","catch","RTCTrackEvent","mozSrcObject","mozRTCPeerConnection","newServer","mozRTCSessionDescription","mozRTCIceCandidate","modernStatsTypes","nativeGetStats","onSucc","onErr","InternalError","NotSupportedError","SecurityError","The operation is insecure.","constraintsToFF37_","mozGetUserMedia","infos","orgEnumerateDevices","nativeGetUserMedia","getSettings","nativeGetSettings","applyConstraints","nativeApplyConstraints","_localStreams","getStreamById","_remoteStreams","_addTrack","tracks","_onaddstream","_onaddstreampoly","failureCallback","withCallback","errcb","RTCTransceiver","logDisabled_","deprecationWarnings_","bool","oldMethod","newMethod","pos","mixin","isWildEmitter","groupName","fn","callbacks","hasGroup","_groupName","off","releaseGroup","handlers","specialCallbacks","getWildcardCallbacks","eventName","originalGlobalValue","indexOfListener","alias","aliasClosure","getListeners","events","_getEvents","flattenListeners","flatListeners","getListenersAsObject","listenerIsWrapped","addOnceListener","defineEvent","defineEvents","evts","addListeners","manipulateListeners","removeListeners","remove","single","multiple","removeEvent","emitEvent","_getOnceReturnValue","trigger","setOnceReturnValue","_onceReturnValue","noConflict","Mapper","callback","key2","ids","pop","JsonRpcClient","RpcBuilder","WebSocketWithReconnection","now","PING_INTERVAL","RECONNECTING","CONNECTED","DISCONNECTED","Logger","configuration","wsConfig","ws","notReconnectIfNumLessThan","pingNextNum","enabledPings","pingPongStarted","pingInterval","status","onreconnecting","onreconnected","onconnected","rpc","pull","request","reply","debug","updateNotReconnectIfLessThan","usePing","rpcBuilderOptions","request_timeout","requestTimeout","ping_request_timeout","heartbeatRequestTimeout","packers","JsonRPC","requestTime","encode","data","sendPing","heartbeat","pingNum","reconnectWs","clearInterval","sendCloseMessage","forceClose","millis","reconnect","BrowserWebSocket","WebSocket","MozWebSocket","MAX_RETRIES","RETRY_TIME_MS","CONNECTING","OPEN","CLOSING","CLOSED","closing","registerMessageHandler","wsUri","useSockJS","reconnecting","forcingDisconnection","SockJS","onopen","logConnected","reconnectionOnClose","readyState","reconnectToSameUri","onclose","maxRetries","numRetries","reconnectToNewUri","newWsUriOnReconnection","newWsUri","reconnectWsUri","newWs","onErrorOrClose","ondisconnect","goodWsUri","defineProperty_IE8","oThis","aArgs","fToBind","fNOP","fBound","BASE_TIMEOUT","unifyResponseMethods","responseMethods","unifyTransport","transport","postMessage","onmessage","pause","SyntaxError","RpcNotification","packer","onRequest","pack","unpack","peerID","max_retries","transportMessage","decode","getTransport","response_timeout","duplicates_timeout","requestID","requests","responses","processedResponses","message2Key","storeResponse","dest","timeout","storeProcessedResponse","ack","from","RpcRequest","duplicated","Boolean","responseMethod","clearTimeout","cancel","retried","dispatchCallback","encode_transport","sendRequest","rt","pow","retry","notification","processRequest","idAck","processResponse","duplicatedResponse","processed","clients","jsonrpc","result_defined","error_defined","XmlRPC","hark","sdpTranslator","logger","MEDIA_CONSTRAINTS","framerate","usePlanB","noop","trackStop","streamStop","dumpSDP","bufferizeCandidates","candidatesQueue","entry","removeFIDFromOffer","getSimulcastInfo","videoStream","videoTracks","WebRtcPeer","mode","localVideo","remoteVideo","audioStream","mediaConstraints","connectionConstraints","peerConnection","sendSource","dataChannelConfig","useDataChannels","dataChannels","dataChannel","guid","oncandidategatheringdone","simulcast","multistream","interop","candidatesQueueOut","candidategatheringdone","defineProperties","currentFrame","HAVE_CURRENT_DATA","canvas","createElement","videoWidth","videoHeight","getContext","drawImage","dcId","dcOptions","createDataChannel","onbufferedamountlow","iceCandidate","generateOffer","offerAudio","offerVideo","browserDependantConstraints","mangleSdpToAddSimulcast","processAnswer","getLocalSessionDescriptor","getRemoteSessionDescriptor","setRemoteVideo","load","showLocalVideo","muted","sdpAnswer","planBAnswer","processOffer","sdpOffer","planBOffer","getMedia","getScreenConstraints","constraints_","cancelChooseDesktopMedia","createEnableDescriptor","trackSetEnable","audioEnabled","videoEnabled","getLocalStream","getRemoteStream","dispose","dc","WebRtcPeerRecvonly","WebRtcPeerSendonly","WebRtcPeerSendrecv","harkUtils","OpenVidu_1","OpenVidu","OpenViduInternal_1","Session_1","Publisher_1","openVidu","OpenViduInternal","info","initSession","param1","param2","checkSystemRequirements","Session","alert","initPublisher","parentId","cameraOptions","cameraOptionsAux","sendAudio","sendVideo","activeAudio","activeVideo","generateMediaConstraints","publisher","Publisher","initPublisherTagged","getDevices","deviceInfos","enableProdMode","_this","ee","accessAllowed","getElementById","element","publishAudio","getWebRtcPeer","publishVideo","destroy","unpublish","removeVideo","subscribeToRemote","subscribeToMyRemote","isVideoELementCreated","getVideoElement","addOnceEventListener","displayMyRemote","currentTime","paused","ended","isReady","accessIsAllowed","accessIsDenied","Subscriber_1","getSessionId","_i","_a","connection","streamId","getStreams","param3","configure","participantId","metadata","stringClientMetadata","subscribeToStreams","disconnect","preventDefault","publish","eventHandler","subscribe","subscriber","Subscriber","playOnlyVideo","unsubscribe","unsuscribe","onStreamCreated","streamEvent","onStreamDestroyed","onParticipantJoined","participantEvent","onParticipantLeft","onParticipantPublished","onParticipantEvicted","onRoomClosed","roomEvent","room","onLostConnection","onMediaError","errorEvent","Stream_1","Connection","local","streamsOpts","connectionId","initStreams","getIdInParticipant","sendIceCandidate","endpointName","streamOptions","streamOpts","recvAudio","audioActive","recvVideo","videoActive","Stream","SessionInternal_1","SessionInternal","getCamera","camera","requestCameraAccess","setVideoElement","cameraReady","videoElement","emitStreamReadyEvent","getWsUri","setWsUri","getSecret","secret","setSecret","getOpenViduServerURL","getRoom","initJsonRpcClient","connectCallback","disconnectCallback","reconnectingCallback","reconnectedCallback","participantJoined","participantPublished","participantUnpublished","participantLeft","participantEvicted","sendMessage","onNewMessage","iceCandidateEvent","mediaError","custonNotification","customNotification","jsonRpcClient","isRoomAvailable","recvIceCandidate","setRpcParams","rpcParams","forced","leave","disconnectParticipant","getLocalParticipant","user","userMessage","roomMessage","sendCustomRequest","toggleLocalVideoTrack","activate","toggleLocalAudioTrack","publishLocalVideoAudio","unpublishLocalVideoAudio","w","h","quality","Connection_1","SECRET_PARAM","participants","participantsSpeaking","getUrlWithoutSecret","localParticipant","processOpenViduUrl","getSecretFromUrl","getFinalUrl","lastIndexOf","randomToken","joinParams","isDataChannelEnabled","exParticipants","length_1","creationTime","_b","_c","updateSpeakerInterval","thresholdSpeaker","activateUpdateMainSpeaker","getId","eventsArray","pid","msg","confirm","getParticipant","addParticipantSpeaking","removeParticipantSpeaking","kurentoUtils","jq","show","style","display","hide","videoElements","elements","showMyRemote","localMirrored","chanId","dataChannelOpened","srcEvent","videoSrcObject","emitSrcEvent","wrstream","getVideoSrcObject","parentElement","removeChild","Element","getRecvVideo","getRecvAudio","mirrorLocalStream","wr","wrStream","isLocalMirrored","getChannelName","isDataChannelOpened","onDataChannelOpen","onDataChannelClosed","sendData","wp","getWrStream","showSpinner","spinnerParentId","progress","background","spinnerParent","appendChild","hideSpinner","spinnerId","thumbnailId","autoplay","controls","thumb","onplaying","title","parentElementDom","playThumbnail","container","className","thumbnail","userName","createTextNode","getRTCPeerConnection","userMediaHasVideo","hasVideo","requestCameraAccesAux","userStream","cameraAccessSuccess","videoInput","deviceInfo","publishVideoCallback","sdpOfferParam","doLoopback","processSdpAnswer","startVideoCallback","initWebRtcPeer","sdpOfferCallback","userMediaConstraints","offerConstraints","speechEvent","disposeElement","parentNode"],"mappings":"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","sourcesContent":["(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require==\"function\"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error(\"Cannot find module '\"+o+\"'\");throw f.code=\"MODULE_NOT_FOUND\",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require==\"function\"&&require;for(var o=0;o 0 && this._events[type].length > m) {\n this._events[type].warned = true;\n console.error('(node) warning: possible EventEmitter memory ' +\n 'leak detected. %d listeners added. ' +\n 'Use emitter.setMaxListeners() to increase limit.',\n this._events[type].length);\n if (typeof console.trace === 'function') {\n // not supported in IE 10\n console.trace();\n }\n }\n }\n\n return this;\n};\n\nEventEmitter.prototype.on = EventEmitter.prototype.addListener;\n\nEventEmitter.prototype.once = function(type, listener) {\n if (!isFunction(listener))\n throw TypeError('listener must be a function');\n\n var fired = false;\n\n function g() {\n this.removeListener(type, g);\n\n if (!fired) {\n fired = true;\n listener.apply(this, arguments);\n }\n }\n\n g.listener = listener;\n this.on(type, g);\n\n return this;\n};\n\n// emits a 'removeListener' event iff the listener was removed\nEventEmitter.prototype.removeListener = function(type, listener) {\n var list, position, length, i;\n\n if (!isFunction(listener))\n throw TypeError('listener must be a function');\n\n if (!this._events || !this._events[type])\n return this;\n\n list = this._events[type];\n length = list.length;\n position = -1;\n\n if (list === listener ||\n (isFunction(list.listener) && list.listener === listener)) {\n delete this._events[type];\n if (this._events.removeListener)\n this.emit('removeListener', type, listener);\n\n } else if (isObject(list)) {\n for (i = length; i-- > 0;) {\n if (list[i] === listener ||\n (list[i].listener && list[i].listener === listener)) {\n position = i;\n break;\n }\n }\n\n if (position < 0)\n return this;\n\n if (list.length === 1) {\n list.length = 0;\n delete this._events[type];\n } else {\n list.splice(position, 1);\n }\n\n if (this._events.removeListener)\n this.emit('removeListener', type, listener);\n }\n\n return this;\n};\n\nEventEmitter.prototype.removeAllListeners = function(type) {\n var key, listeners;\n\n if (!this._events)\n return this;\n\n // not listening for removeListener, no need to emit\n if (!this._events.removeListener) {\n if (arguments.length === 0)\n this._events = {};\n else if (this._events[type])\n delete this._events[type];\n return this;\n }\n\n // emit removeListener for all listeners on all events\n if (arguments.length === 0) {\n for (key in this._events) {\n if (key === 'removeListener') continue;\n this.removeAllListeners(key);\n }\n this.removeAllListeners('removeListener');\n this._events = {};\n return this;\n }\n\n listeners = this._events[type];\n\n if (isFunction(listeners)) {\n this.removeListener(type, listeners);\n } else if (listeners) {\n // LIFO order\n while (listeners.length)\n this.removeListener(type, listeners[listeners.length - 1]);\n }\n delete this._events[type];\n\n return this;\n};\n\nEventEmitter.prototype.listeners = function(type) {\n var ret;\n if (!this._events || !this._events[type])\n ret = [];\n else if (isFunction(this._events[type]))\n ret = [this._events[type]];\n else\n ret = this._events[type].slice();\n return ret;\n};\n\nEventEmitter.prototype.listenerCount = function(type) {\n if (this._events) {\n var evlistener = this._events[type];\n\n if (isFunction(evlistener))\n return 1;\n else if (evlistener)\n return evlistener.length;\n }\n return 0;\n};\n\nEventEmitter.listenerCount = function(emitter, type) {\n return emitter.listenerCount(type);\n};\n\nfunction isFunction(arg) {\n return typeof arg === 'function';\n}\n\nfunction isNumber(arg) {\n return typeof arg === 'number';\n}\n\nfunction isObject(arg) {\n return typeof arg === 'object' && arg !== null;\n}\n\nfunction isUndefined(arg) {\n return arg === void 0;\n}\n","/* jshint node: true */\n'use strict';\n\nvar normalice = require('normalice');\n\n/**\n # freeice\n\n The `freeice` module is a simple way of getting random STUN or TURN server\n for your WebRTC application. The list of servers (just STUN at this stage)\n were sourced from this [gist](https://gist.github.com/zziuni/3741933).\n\n ## Example Use\n\n The following demonstrates how you can use `freeice` with\n [rtc-quickconnect](https://github.com/rtc-io/rtc-quickconnect):\n\n <<< examples/quickconnect.js\n\n As the `freeice` module generates ice servers in a list compliant with the\n WebRTC spec you will be able to use it with raw `RTCPeerConnection`\n constructors and other WebRTC libraries.\n\n ## Hey, don't use my STUN/TURN server!\n\n If for some reason your free STUN or TURN server ends up in the\n list of servers ([stun](https://github.com/DamonOehlman/freeice/blob/master/stun.json) or\n [turn](https://github.com/DamonOehlman/freeice/blob/master/turn.json))\n that is used in this module, you can feel\n free to open an issue on this repository and those servers will be removed\n within 24 hours (or sooner). This is the quickest and probably the most\n polite way to have something removed (and provides us some visibility\n if someone opens a pull request requesting that a server is added).\n\n ## Please add my server!\n\n If you have a server that you wish to add to the list, that's awesome! I'm\n sure I speak on behalf of a whole pile of WebRTC developers who say thanks.\n To get it into the list, feel free to either open a pull request or if you\n find that process a bit daunting then just create an issue requesting\n the addition of the server (make sure you provide all the details, and if\n you have a Terms of Service then including that in the PR/issue would be\n awesome).\n\n ## I know of a free server, can I add it?\n\n Sure, if you do your homework and make sure it is ok to use (I'm currently\n in the process of reviewing the terms of those STUN servers included from\n the original list). If it's ok to go, then please see the previous entry\n for how to add it.\n\n ## Current List of Servers\n\n * current as at the time of last `README.md` file generation\n\n ### STUN\n\n <<< stun.json\n\n ### TURN\n\n <<< turn.json\n\n**/\n\nvar freeice = module.exports = function(opts) {\n // if a list of servers has been provided, then use it instead of defaults\n var servers = {\n stun: (opts || {}).stun || require('./stun.json'),\n turn: (opts || {}).turn || require('./turn.json')\n };\n\n var stunCount = (opts || {}).stunCount || 2;\n var turnCount = (opts || {}).turnCount || 0;\n var selected;\n\n function getServers(type, count) {\n var out = [];\n var input = [].concat(servers[type]);\n var idx;\n\n while (input.length && out.length < count) {\n idx = (Math.random() * input.length) | 0;\n out = out.concat(input.splice(idx, 1));\n }\n\n return out.map(function(url) {\n //If it's a not a string, don't try to \"normalice\" it otherwise using type:url will screw it up\n if ((typeof url !== 'string') && (! (url instanceof String))) {\n return url;\n } else {\n return normalice(type + ':' + url);\n }\n });\n }\n\n // add stun servers\n selected = [].concat(getServers('stun', stunCount));\n\n if (turnCount) {\n selected = selected.concat(getServers('turn', turnCount));\n }\n\n return selected;\n};\n","module.exports=[\n \"stun.l.google.com:19302\",\n \"stun1.l.google.com:19302\",\n \"stun2.l.google.com:19302\",\n \"stun3.l.google.com:19302\",\n \"stun4.l.google.com:19302\",\n \"stun.ekiga.net\",\n \"stun.ideasip.com\",\n \"stun.schlund.de\",\n \"stun.stunprotocol.org:3478\",\n \"stun.voiparound.com\",\n \"stun.voipbuster.com\",\n \"stun.voipstunt.com\",\n \"stun.voxgratia.org\",\n \"stun.services.mozilla.com\"\n]\n","module.exports=[]\n","var WildEmitter = require('wildemitter');\n\nfunction getMaxVolume (analyser, fftBins) {\n var maxVolume = -Infinity;\n analyser.getFloatFrequencyData(fftBins);\n\n for(var i=4, ii=fftBins.length; i < ii; i++) {\n if (fftBins[i] > maxVolume && fftBins[i] < 0) {\n maxVolume = fftBins[i];\n }\n };\n\n return maxVolume;\n}\n\n\nvar audioContextType = window.AudioContext || window.webkitAudioContext;\n// use a single audio context due to hardware limits\nvar audioContext = null;\nmodule.exports = function(stream, options) {\n var harker = new WildEmitter();\n\n\n // make it not break in non-supported browsers\n if (!audioContextType) return harker;\n\n //Config\n var options = options || {},\n smoothing = (options.smoothing || 0.1),\n interval = (options.interval || 50),\n threshold = options.threshold,\n play = options.play,\n history = options.history || 10,\n running = true;\n\n //Setup Audio Context\n if (!audioContext) {\n audioContext = new audioContextType();\n }\n var sourceNode, fftBins, analyser;\n\n analyser = audioContext.createAnalyser();\n analyser.fftSize = 512;\n analyser.smoothingTimeConstant = smoothing;\n fftBins = new Float32Array(analyser.fftSize);\n\n if (stream.jquery) stream = stream[0];\n if (stream instanceof HTMLAudioElement || stream instanceof HTMLVideoElement) {\n //Audio Tag\n sourceNode = audioContext.createMediaElementSource(stream);\n if (typeof play === 'undefined') play = true;\n threshold = threshold || -50;\n } else {\n //WebRTC Stream\n sourceNode = audioContext.createMediaStreamSource(stream);\n threshold = threshold || -50;\n }\n\n sourceNode.connect(analyser);\n if (play) analyser.connect(audioContext.destination);\n\n harker.speaking = false;\n\n harker.setThreshold = function(t) {\n threshold = t;\n };\n\n harker.setInterval = function(i) {\n interval = i;\n };\n \n harker.stop = function() {\n running = false;\n harker.emit('volume_change', -100, threshold);\n if (harker.speaking) {\n harker.speaking = false;\n harker.emit('stopped_speaking');\n }\n };\n harker.speakingHistory = [];\n for (var i = 0; i < history; i++) {\n harker.speakingHistory.push(0);\n }\n\n // Poll the analyser node to determine if speaking\n // and emit events if changed\n var looper = function() {\n setTimeout(function() {\n \n //check if stop has been called\n if(!running) {\n return;\n }\n \n var currentVolume = getMaxVolume(analyser, fftBins);\n\n harker.emit('volume_change', currentVolume, threshold);\n\n var history = 0;\n if (currentVolume > threshold && !harker.speaking) {\n // trigger quickly, short history\n for (var i = harker.speakingHistory.length - 3; i < harker.speakingHistory.length; i++) {\n history += harker.speakingHistory[i];\n }\n if (history >= 2) {\n harker.speaking = true;\n harker.emit('speaking');\n }\n } else if (currentVolume < threshold && harker.speaking) {\n for (var i = 0; i < harker.speakingHistory.length; i++) {\n history += harker.speakingHistory[i];\n }\n if (history == 0) {\n harker.speaking = false;\n harker.emit('stopped_speaking');\n }\n }\n harker.speakingHistory.shift();\n harker.speakingHistory.push(0 + (currentVolume > threshold));\n\n looper();\n }, interval);\n };\n looper();\n\n\n return harker;\n}\n","if (typeof Object.create === 'function') {\n // implementation from standard node.js 'util' module\n module.exports = function inherits(ctor, superCtor) {\n ctor.super_ = superCtor\n ctor.prototype = Object.create(superCtor.prototype, {\n constructor: {\n value: ctor,\n enumerable: false,\n writable: true,\n configurable: true\n }\n });\n };\n} else {\n // old school shim for old browsers\n module.exports = function inherits(ctor, superCtor) {\n ctor.super_ = superCtor\n var TempCtor = function () {}\n TempCtor.prototype = superCtor.prototype\n ctor.prototype = new TempCtor()\n ctor.prototype.constructor = ctor\n }\n}\n","/*!\r\n * @name JavaScript/NodeJS Merge v1.2.0\r\n * @author yeikos\r\n * @repository https://github.com/yeikos/js.merge\r\n\r\n * Copyright 2014 yeikos - MIT license\r\n * https://raw.github.com/yeikos/js.merge/master/LICENSE\r\n */\r\n\r\n;(function(isNode) {\r\n\r\n\t/**\r\n\t * Merge one or more objects \r\n\t * @param bool? clone\r\n\t * @param mixed,... arguments\r\n\t * @return object\r\n\t */\r\n\r\n\tvar Public = function(clone) {\r\n\r\n\t\treturn merge(clone === true, false, arguments);\r\n\r\n\t}, publicName = 'merge';\r\n\r\n\t/**\r\n\t * Merge two or more objects recursively \r\n\t * @param bool? clone\r\n\t * @param mixed,... arguments\r\n\t * @return object\r\n\t */\r\n\r\n\tPublic.recursive = function(clone) {\r\n\r\n\t\treturn merge(clone === true, true, arguments);\r\n\r\n\t};\r\n\r\n\t/**\r\n\t * Clone the input removing any reference\r\n\t * @param mixed input\r\n\t * @return mixed\r\n\t */\r\n\r\n\tPublic.clone = function(input) {\r\n\r\n\t\tvar output = input,\r\n\t\t\ttype = typeOf(input),\r\n\t\t\tindex, size;\r\n\r\n\t\tif (type === 'array') {\r\n\r\n\t\t\toutput = [];\r\n\t\t\tsize = input.length;\r\n\r\n\t\t\tfor (index=0;index 1) {\n url = parts[1];\n parts = parts[0].split(':');\n\n // add the output credential and username\n output.username = parts[0];\n output.credential = (input || {}).credential || parts[1] || '';\n }\n\n output.url = protocol + url;\n output.urls = [ output.url ];\n\n return output;\n};\n","/*\n * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.\n *\n * Use of this source code is governed by a BSD-style license\n * that can be found in the LICENSE file in the root of the source\n * tree.\n */\n /* eslint-env node */\n'use strict';\n\nvar SDPUtils = require('sdp');\n\nfunction writeMediaSection(transceiver, caps, type, stream, dtlsRole) {\n var sdp = SDPUtils.writeRtpDescription(transceiver.kind, caps);\n\n // Map ICE parameters (ufrag, pwd) to SDP.\n sdp += SDPUtils.writeIceParameters(\n transceiver.iceGatherer.getLocalParameters());\n\n // Map DTLS parameters to SDP.\n sdp += SDPUtils.writeDtlsParameters(\n transceiver.dtlsTransport.getLocalParameters(),\n type === 'offer' ? 'actpass' : dtlsRole || 'active');\n\n sdp += 'a=mid:' + transceiver.mid + '\\r\\n';\n\n if (transceiver.direction) {\n sdp += 'a=' + transceiver.direction + '\\r\\n';\n } else if (transceiver.rtpSender && transceiver.rtpReceiver) {\n sdp += 'a=sendrecv\\r\\n';\n } else if (transceiver.rtpSender) {\n sdp += 'a=sendonly\\r\\n';\n } else if (transceiver.rtpReceiver) {\n sdp += 'a=recvonly\\r\\n';\n } else {\n sdp += 'a=inactive\\r\\n';\n }\n\n if (transceiver.rtpSender) {\n // spec.\n var msid = 'msid:' + stream.id + ' ' +\n transceiver.rtpSender.track.id + '\\r\\n';\n sdp += 'a=' + msid;\n\n // for Chrome.\n sdp += 'a=ssrc:' + transceiver.sendEncodingParameters[0].ssrc +\n ' ' + msid;\n if (transceiver.sendEncodingParameters[0].rtx) {\n sdp += 'a=ssrc:' + transceiver.sendEncodingParameters[0].rtx.ssrc +\n ' ' + msid;\n sdp += 'a=ssrc-group:FID ' +\n transceiver.sendEncodingParameters[0].ssrc + ' ' +\n transceiver.sendEncodingParameters[0].rtx.ssrc +\n '\\r\\n';\n }\n }\n // FIXME: this should be written by writeRtpDescription.\n sdp += 'a=ssrc:' + transceiver.sendEncodingParameters[0].ssrc +\n ' cname:' + SDPUtils.localCName + '\\r\\n';\n if (transceiver.rtpSender && transceiver.sendEncodingParameters[0].rtx) {\n sdp += 'a=ssrc:' + transceiver.sendEncodingParameters[0].rtx.ssrc +\n ' cname:' + SDPUtils.localCName + '\\r\\n';\n }\n return sdp;\n}\n\n// Edge does not like\n// 1) stun: filtered after 14393 unless ?transport=udp is present\n// 2) turn: that does not have all of turn:host:port?transport=udp\n// 3) turn: with ipv6 addresses\n// 4) turn: occurring muliple times\nfunction filterIceServers(iceServers, edgeVersion) {\n var hasTurn = false;\n iceServers = JSON.parse(JSON.stringify(iceServers));\n return iceServers.filter(function(server) {\n if (server && (server.urls || server.url)) {\n var urls = server.urls || server.url;\n if (server.url && !server.urls) {\n console.warn('RTCIceServer.url is deprecated! Use urls instead.');\n }\n var isString = typeof urls === 'string';\n if (isString) {\n urls = [urls];\n }\n urls = urls.filter(function(url) {\n var validTurn = url.indexOf('turn:') === 0 &&\n url.indexOf('transport=udp') !== -1 &&\n url.indexOf('turn:[') === -1 &&\n !hasTurn;\n\n if (validTurn) {\n hasTurn = true;\n return true;\n }\n return url.indexOf('stun:') === 0 && edgeVersion >= 14393 &&\n url.indexOf('?transport=udp') === -1;\n });\n\n delete server.url;\n server.urls = isString ? urls[0] : urls;\n return !!urls.length;\n }\n return false;\n });\n}\n\n// Determines the intersection of local and remote capabilities.\nfunction getCommonCapabilities(localCapabilities, remoteCapabilities) {\n var commonCapabilities = {\n codecs: [],\n headerExtensions: [],\n fecMechanisms: []\n };\n\n var findCodecByPayloadType = function(pt, codecs) {\n pt = parseInt(pt, 10);\n for (var i = 0; i < codecs.length; i++) {\n if (codecs[i].payloadType === pt ||\n codecs[i].preferredPayloadType === pt) {\n return codecs[i];\n }\n }\n };\n\n var rtxCapabilityMatches = function(lRtx, rRtx, lCodecs, rCodecs) {\n var lCodec = findCodecByPayloadType(lRtx.parameters.apt, lCodecs);\n var rCodec = findCodecByPayloadType(rRtx.parameters.apt, rCodecs);\n return lCodec && rCodec &&\n lCodec.name.toLowerCase() === rCodec.name.toLowerCase();\n };\n\n localCapabilities.codecs.forEach(function(lCodec) {\n for (var i = 0; i < remoteCapabilities.codecs.length; i++) {\n var rCodec = remoteCapabilities.codecs[i];\n if (lCodec.name.toLowerCase() === rCodec.name.toLowerCase() &&\n lCodec.clockRate === rCodec.clockRate) {\n if (lCodec.name.toLowerCase() === 'rtx' &&\n lCodec.parameters && rCodec.parameters.apt) {\n // for RTX we need to find the local rtx that has a apt\n // which points to the same local codec as the remote one.\n if (!rtxCapabilityMatches(lCodec, rCodec,\n localCapabilities.codecs, remoteCapabilities.codecs)) {\n continue;\n }\n }\n rCodec = JSON.parse(JSON.stringify(rCodec)); // deepcopy\n // number of channels is the highest common number of channels\n rCodec.numChannels = Math.min(lCodec.numChannels,\n rCodec.numChannels);\n // push rCodec so we reply with offerer payload type\n commonCapabilities.codecs.push(rCodec);\n\n // determine common feedback mechanisms\n rCodec.rtcpFeedback = rCodec.rtcpFeedback.filter(function(fb) {\n for (var j = 0; j < lCodec.rtcpFeedback.length; j++) {\n if (lCodec.rtcpFeedback[j].type === fb.type &&\n lCodec.rtcpFeedback[j].parameter === fb.parameter) {\n return true;\n }\n }\n return false;\n });\n // FIXME: also need to determine .parameters\n // see https://github.com/openpeer/ortc/issues/569\n break;\n }\n }\n });\n\n localCapabilities.headerExtensions.forEach(function(lHeaderExtension) {\n for (var i = 0; i < remoteCapabilities.headerExtensions.length;\n i++) {\n var rHeaderExtension = remoteCapabilities.headerExtensions[i];\n if (lHeaderExtension.uri === rHeaderExtension.uri) {\n commonCapabilities.headerExtensions.push(rHeaderExtension);\n break;\n }\n }\n });\n\n // FIXME: fecMechanisms\n return commonCapabilities;\n}\n\n// is action=setLocalDescription with type allowed in signalingState\nfunction isActionAllowedInSignalingState(action, type, signalingState) {\n return {\n offer: {\n setLocalDescription: ['stable', 'have-local-offer'],\n setRemoteDescription: ['stable', 'have-remote-offer']\n },\n answer: {\n setLocalDescription: ['have-remote-offer', 'have-local-pranswer'],\n setRemoteDescription: ['have-local-offer', 'have-remote-pranswer']\n }\n }[type][action].indexOf(signalingState) !== -1;\n}\n\nfunction maybeAddCandidate(iceTransport, candidate) {\n // Edge's internal representation adds some fields therefore\n // not all fieldѕ are taken into account.\n var alreadyAdded = iceTransport.getRemoteCandidates()\n .find(function(remoteCandidate) {\n return candidate.foundation === remoteCandidate.foundation &&\n candidate.ip === remoteCandidate.ip &&\n candidate.port === remoteCandidate.port &&\n candidate.priority === remoteCandidate.priority &&\n candidate.protocol === remoteCandidate.protocol &&\n candidate.type === remoteCandidate.type;\n });\n if (!alreadyAdded) {\n iceTransport.addRemoteCandidate(candidate);\n }\n return !alreadyAdded;\n}\n\nmodule.exports = function(window, edgeVersion) {\n var RTCPeerConnection = function(config) {\n var self = this;\n\n var _eventTarget = document.createDocumentFragment();\n ['addEventListener', 'removeEventListener', 'dispatchEvent']\n .forEach(function(method) {\n self[method] = _eventTarget[method].bind(_eventTarget);\n });\n\n this.onicecandidate = null;\n this.onaddstream = null;\n this.ontrack = null;\n this.onremovestream = null;\n this.onsignalingstatechange = null;\n this.oniceconnectionstatechange = null;\n this.onicegatheringstatechange = null;\n this.onnegotiationneeded = null;\n this.ondatachannel = null;\n this.canTrickleIceCandidates = null;\n\n this.needNegotiation = false;\n\n this.localStreams = [];\n this.remoteStreams = [];\n\n this.localDescription = null;\n this.remoteDescription = null;\n\n this.signalingState = 'stable';\n this.iceConnectionState = 'new';\n this.iceGatheringState = 'new';\n\n config = JSON.parse(JSON.stringify(config || {}));\n\n this.usingBundle = config.bundlePolicy === 'max-bundle';\n if (config.rtcpMuxPolicy === 'negotiate') {\n var e = new Error('rtcpMuxPolicy \\'negotiate\\' is not supported');\n e.name = 'NotSupportedError';\n throw(e);\n } else if (!config.rtcpMuxPolicy) {\n config.rtcpMuxPolicy = 'require';\n }\n\n switch (config.iceTransportPolicy) {\n case 'all':\n case 'relay':\n break;\n default:\n config.iceTransportPolicy = 'all';\n break;\n }\n\n switch (config.bundlePolicy) {\n case 'balanced':\n case 'max-compat':\n case 'max-bundle':\n break;\n default:\n config.bundlePolicy = 'balanced';\n break;\n }\n\n config.iceServers = filterIceServers(config.iceServers || [], edgeVersion);\n\n this._iceGatherers = [];\n if (config.iceCandidatePoolSize) {\n for (var i = config.iceCandidatePoolSize; i > 0; i--) {\n this._iceGatherers = new window.RTCIceGatherer({\n iceServers: config.iceServers,\n gatherPolicy: config.iceTransportPolicy\n });\n }\n } else {\n config.iceCandidatePoolSize = 0;\n }\n\n this._config = config;\n\n // per-track iceGathers, iceTransports, dtlsTransports, rtpSenders, ...\n // everything that is needed to describe a SDP m-line.\n this.transceivers = [];\n\n this._sdpSessionId = SDPUtils.generateSessionId();\n this._sdpSessionVersion = 0;\n\n this._dtlsRole = undefined; // role for a=setup to use in answers.\n };\n\n RTCPeerConnection.prototype._emitGatheringStateChange = function() {\n var event = new Event('icegatheringstatechange');\n this.dispatchEvent(event);\n if (typeof this.onicegatheringstatechange === 'function') {\n this.onicegatheringstatechange(event);\n }\n };\n\n RTCPeerConnection.prototype.getConfiguration = function() {\n return this._config;\n };\n\n RTCPeerConnection.prototype.getLocalStreams = function() {\n return this.localStreams;\n };\n\n RTCPeerConnection.prototype.getRemoteStreams = function() {\n return this.remoteStreams;\n };\n\n // internal helper to create a transceiver object.\n // (whih is not yet the same as the WebRTC 1.0 transceiver)\n RTCPeerConnection.prototype._createTransceiver = function(kind) {\n var hasBundleTransport = this.transceivers.length > 0;\n var transceiver = {\n track: null,\n iceGatherer: null,\n iceTransport: null,\n dtlsTransport: null,\n localCapabilities: null,\n remoteCapabilities: null,\n rtpSender: null,\n rtpReceiver: null,\n kind: kind,\n mid: null,\n sendEncodingParameters: null,\n recvEncodingParameters: null,\n stream: null,\n wantReceive: true\n };\n if (this.usingBundle && hasBundleTransport) {\n transceiver.iceTransport = this.transceivers[0].iceTransport;\n transceiver.dtlsTransport = this.transceivers[0].dtlsTransport;\n } else {\n var transports = this._createIceAndDtlsTransports();\n transceiver.iceTransport = transports.iceTransport;\n transceiver.dtlsTransport = transports.dtlsTransport;\n }\n this.transceivers.push(transceiver);\n return transceiver;\n };\n\n RTCPeerConnection.prototype.addTrack = function(track, stream) {\n var transceiver;\n for (var i = 0; i < this.transceivers.length; i++) {\n if (!this.transceivers[i].track &&\n this.transceivers[i].kind === track.kind) {\n transceiver = this.transceivers[i];\n }\n }\n if (!transceiver) {\n transceiver = this._createTransceiver(track.kind);\n }\n\n this._maybeFireNegotiationNeeded();\n\n if (this.localStreams.indexOf(stream) === -1) {\n this.localStreams.push(stream);\n }\n\n transceiver.track = track;\n transceiver.stream = stream;\n transceiver.rtpSender = new window.RTCRtpSender(track,\n transceiver.dtlsTransport);\n return transceiver.rtpSender;\n };\n\n RTCPeerConnection.prototype.addStream = function(stream) {\n var self = this;\n if (edgeVersion >= 15025) {\n stream.getTracks().forEach(function(track) {\n self.addTrack(track, stream);\n });\n } else {\n // Clone is necessary for local demos mostly, attaching directly\n // to two different senders does not work (build 10547).\n // Fixed in 15025 (or earlier)\n var clonedStream = stream.clone();\n stream.getTracks().forEach(function(track, idx) {\n var clonedTrack = clonedStream.getTracks()[idx];\n track.addEventListener('enabled', function(event) {\n clonedTrack.enabled = event.enabled;\n });\n });\n clonedStream.getTracks().forEach(function(track) {\n self.addTrack(track, clonedStream);\n });\n }\n };\n\n RTCPeerConnection.prototype.removeStream = function(stream) {\n var idx = this.localStreams.indexOf(stream);\n if (idx > -1) {\n this.localStreams.splice(idx, 1);\n this._maybeFireNegotiationNeeded();\n }\n };\n\n RTCPeerConnection.prototype.getSenders = function() {\n return this.transceivers.filter(function(transceiver) {\n return !!transceiver.rtpSender;\n })\n .map(function(transceiver) {\n return transceiver.rtpSender;\n });\n };\n\n RTCPeerConnection.prototype.getReceivers = function() {\n return this.transceivers.filter(function(transceiver) {\n return !!transceiver.rtpReceiver;\n })\n .map(function(transceiver) {\n return transceiver.rtpReceiver;\n });\n };\n\n\n RTCPeerConnection.prototype._createIceGatherer = function(sdpMLineIndex,\n usingBundle) {\n var self = this;\n if (usingBundle && sdpMLineIndex > 0) {\n return this.transceivers[0].iceGatherer;\n } else if (this._iceGatherers.length) {\n return this._iceGatherers.shift();\n }\n var iceGatherer = new window.RTCIceGatherer({\n iceServers: this._config.iceServers,\n gatherPolicy: this._config.iceTransportPolicy\n });\n Object.defineProperty(iceGatherer, 'state',\n {value: 'new', writable: true}\n );\n\n this.transceivers[sdpMLineIndex].candidates = [];\n this.transceivers[sdpMLineIndex].bufferCandidates = function(event) {\n var end = !event.candidate || Object.keys(event.candidate).length === 0;\n // polyfill since RTCIceGatherer.state is not implemented in\n // Edge 10547 yet.\n iceGatherer.state = end ? 'completed' : 'gathering';\n if (self.transceivers[sdpMLineIndex].candidates !== null) {\n self.transceivers[sdpMLineIndex].candidates.push(event.candidate);\n }\n };\n iceGatherer.addEventListener('localcandidate',\n this.transceivers[sdpMLineIndex].bufferCandidates);\n return iceGatherer;\n };\n\n // start gathering from an RTCIceGatherer.\n RTCPeerConnection.prototype._gather = function(mid, sdpMLineIndex) {\n var self = this;\n var iceGatherer = this.transceivers[sdpMLineIndex].iceGatherer;\n if (iceGatherer.onlocalcandidate) {\n return;\n }\n var candidates = this.transceivers[sdpMLineIndex].candidates;\n this.transceivers[sdpMLineIndex].candidates = null;\n iceGatherer.removeEventListener('localcandidate',\n this.transceivers[sdpMLineIndex].bufferCandidates);\n iceGatherer.onlocalcandidate = function(evt) {\n if (self.usingBundle && sdpMLineIndex > 0) {\n // if we know that we use bundle we can drop candidates with\n // ѕdpMLineIndex > 0. If we don't do this then our state gets\n // confused since we dispose the extra ice gatherer.\n return;\n }\n var event = new Event('icecandidate');\n event.candidate = {sdpMid: mid, sdpMLineIndex: sdpMLineIndex};\n\n var cand = evt.candidate;\n // Edge emits an empty object for RTCIceCandidateComplete‥\n var end = !cand || Object.keys(cand).length === 0;\n if (end) {\n // polyfill since RTCIceGatherer.state is not implemented in\n // Edge 10547 yet.\n if (iceGatherer.state === 'new' || iceGatherer.state === 'gathering') {\n iceGatherer.state = 'completed';\n }\n } else {\n if (iceGatherer.state === 'new') {\n iceGatherer.state = 'gathering';\n }\n // RTCIceCandidate doesn't have a component, needs to be added\n cand.component = 1;\n event.candidate.candidate = SDPUtils.writeCandidate(cand);\n }\n\n // update local description.\n var sections = SDPUtils.splitSections(self.localDescription.sdp);\n if (!end) {\n sections[event.candidate.sdpMLineIndex + 1] +=\n 'a=' + event.candidate.candidate + '\\r\\n';\n } else {\n sections[event.candidate.sdpMLineIndex + 1] +=\n 'a=end-of-candidates\\r\\n';\n }\n self.localDescription.sdp = sections.join('');\n var complete = self.transceivers.every(function(transceiver) {\n return transceiver.iceGatherer &&\n transceiver.iceGatherer.state === 'completed';\n });\n\n if (self.iceGatheringState !== 'gathering') {\n self.iceGatheringState = 'gathering';\n self._emitGatheringStateChange();\n }\n\n // Emit candidate. Also emit null candidate when all gatherers are\n // complete.\n if (!end) {\n self.dispatchEvent(event);\n if (typeof self.onicecandidate === 'function') {\n self.onicecandidate(event);\n }\n }\n if (complete) {\n self.dispatchEvent(new Event('icecandidate'));\n if (typeof self.onicecandidate === 'function') {\n self.onicecandidate(new Event('icecandidate'));\n }\n self.iceGatheringState = 'complete';\n self._emitGatheringStateChange();\n }\n };\n\n // emit already gathered candidates.\n window.setTimeout(function() {\n candidates.forEach(function(candidate) {\n var e = new Event('RTCIceGatherEvent');\n e.candidate = candidate;\n iceGatherer.onlocalcandidate(e);\n });\n }, 0);\n };\n\n // Create ICE transport and DTLS transport.\n RTCPeerConnection.prototype._createIceAndDtlsTransports = function() {\n var self = this;\n var iceTransport = new window.RTCIceTransport(null);\n iceTransport.onicestatechange = function() {\n self._updateConnectionState();\n };\n\n var dtlsTransport = new window.RTCDtlsTransport(iceTransport);\n dtlsTransport.ondtlsstatechange = function() {\n self._updateConnectionState();\n };\n dtlsTransport.onerror = function() {\n // onerror does not set state to failed by itself.\n Object.defineProperty(dtlsTransport, 'state',\n {value: 'failed', writable: true});\n self._updateConnectionState();\n };\n\n return {\n iceTransport: iceTransport,\n dtlsTransport: dtlsTransport\n };\n };\n\n // Destroy ICE gatherer, ICE transport and DTLS transport.\n // Without triggering the callbacks.\n RTCPeerConnection.prototype._disposeIceAndDtlsTransports = function(\n sdpMLineIndex) {\n var iceGatherer = this.transceivers[sdpMLineIndex].iceGatherer;\n if (iceGatherer) {\n delete iceGatherer.onlocalcandidate;\n delete this.transceivers[sdpMLineIndex].iceGatherer;\n }\n var iceTransport = this.transceivers[sdpMLineIndex].iceTransport;\n if (iceTransport) {\n delete iceTransport.onicestatechange;\n delete this.transceivers[sdpMLineIndex].iceTransport;\n }\n var dtlsTransport = this.transceivers[sdpMLineIndex].dtlsTransport;\n if (dtlsTransport) {\n delete dtlsTransport.ondtlsstatechange;\n delete dtlsTransport.onerror;\n delete this.transceivers[sdpMLineIndex].dtlsTransport;\n }\n };\n\n // Start the RTP Sender and Receiver for a transceiver.\n RTCPeerConnection.prototype._transceive = function(transceiver,\n send, recv) {\n var params = getCommonCapabilities(transceiver.localCapabilities,\n transceiver.remoteCapabilities);\n if (send && transceiver.rtpSender) {\n params.encodings = transceiver.sendEncodingParameters;\n params.rtcp = {\n cname: SDPUtils.localCName,\n compound: transceiver.rtcpParameters.compound\n };\n if (transceiver.recvEncodingParameters.length) {\n params.rtcp.ssrc = transceiver.recvEncodingParameters[0].ssrc;\n }\n transceiver.rtpSender.send(params);\n }\n if (recv && transceiver.rtpReceiver && params.codecs.length > 0) {\n // remove RTX field in Edge 14942\n if (transceiver.kind === 'video'\n && transceiver.recvEncodingParameters\n && edgeVersion < 15019) {\n transceiver.recvEncodingParameters.forEach(function(p) {\n delete p.rtx;\n });\n }\n params.encodings = transceiver.recvEncodingParameters;\n params.rtcp = {\n cname: transceiver.rtcpParameters.cname,\n compound: transceiver.rtcpParameters.compound\n };\n if (transceiver.sendEncodingParameters.length) {\n params.rtcp.ssrc = transceiver.sendEncodingParameters[0].ssrc;\n }\n transceiver.rtpReceiver.receive(params);\n }\n };\n\n RTCPeerConnection.prototype.setLocalDescription = function(description) {\n var self = this;\n var args = arguments;\n\n if (!isActionAllowedInSignalingState('setLocalDescription',\n description.type, this.signalingState)) {\n return new Promise(function(resolve, reject) {\n var e = new Error('Can not set local ' + description.type +\n ' in state ' + self.signalingState);\n e.name = 'InvalidStateError';\n if (args.length > 2 && typeof args[2] === 'function') {\n args[2].apply(null, [e]);\n }\n reject(e);\n });\n }\n\n var sections;\n var sessionpart;\n if (description.type === 'offer') {\n // VERY limited support for SDP munging. Limited to:\n // * changing the order of codecs\n sections = SDPUtils.splitSections(description.sdp);\n sessionpart = sections.shift();\n sections.forEach(function(mediaSection, sdpMLineIndex) {\n var caps = SDPUtils.parseRtpParameters(mediaSection);\n self.transceivers[sdpMLineIndex].localCapabilities = caps;\n });\n\n this.transceivers.forEach(function(transceiver, sdpMLineIndex) {\n self._gather(transceiver.mid, sdpMLineIndex);\n });\n } else if (description.type === 'answer') {\n sections = SDPUtils.splitSections(self.remoteDescription.sdp);\n sessionpart = sections.shift();\n var isIceLite = SDPUtils.matchPrefix(sessionpart,\n 'a=ice-lite').length > 0;\n sections.forEach(function(mediaSection, sdpMLineIndex) {\n var transceiver = self.transceivers[sdpMLineIndex];\n var iceGatherer = transceiver.iceGatherer;\n var iceTransport = transceiver.iceTransport;\n var dtlsTransport = transceiver.dtlsTransport;\n var localCapabilities = transceiver.localCapabilities;\n var remoteCapabilities = transceiver.remoteCapabilities;\n\n // treat bundle-only as not-rejected.\n var rejected = SDPUtils.isRejected(mediaSection) &&\n !SDPUtils.matchPrefix(mediaSection, 'a=bundle-only').length === 1;\n\n if (!rejected && !transceiver.isDatachannel) {\n var remoteIceParameters = SDPUtils.getIceParameters(\n mediaSection, sessionpart);\n var remoteDtlsParameters = SDPUtils.getDtlsParameters(\n mediaSection, sessionpart);\n if (isIceLite) {\n remoteDtlsParameters.role = 'server';\n }\n\n if (!self.usingBundle || sdpMLineIndex === 0) {\n self._gather(transceiver.mid, sdpMLineIndex);\n if (iceTransport.state === 'new') {\n iceTransport.start(iceGatherer, remoteIceParameters,\n isIceLite ? 'controlling' : 'controlled');\n }\n if (dtlsTransport.state === 'new') {\n dtlsTransport.start(remoteDtlsParameters);\n }\n }\n\n // Calculate intersection of capabilities.\n var params = getCommonCapabilities(localCapabilities,\n remoteCapabilities);\n\n // Start the RTCRtpSender. The RTCRtpReceiver for this\n // transceiver has already been started in setRemoteDescription.\n self._transceive(transceiver,\n params.codecs.length > 0,\n false);\n }\n });\n }\n\n this.localDescription = {\n type: description.type,\n sdp: description.sdp\n };\n switch (description.type) {\n case 'offer':\n this._updateSignalingState('have-local-offer');\n break;\n case 'answer':\n this._updateSignalingState('stable');\n break;\n default:\n throw new TypeError('unsupported type \"' + description.type +\n '\"');\n }\n\n // If a success callback was provided, emit ICE candidates after it\n // has been executed. Otherwise, emit callback after the Promise is\n // resolved.\n var cb = arguments.length > 1 && typeof arguments[1] === 'function' &&\n arguments[1];\n return new Promise(function(resolve) {\n if (cb) {\n cb.apply(null);\n }\n resolve();\n });\n };\n\n RTCPeerConnection.prototype.setRemoteDescription = function(description) {\n var self = this;\n var args = arguments;\n\n if (!isActionAllowedInSignalingState('setRemoteDescription',\n description.type, this.signalingState)) {\n return new Promise(function(resolve, reject) {\n var e = new Error('Can not set remote ' + description.type +\n ' in state ' + self.signalingState);\n e.name = 'InvalidStateError';\n if (args.length > 2 && typeof args[2] === 'function') {\n args[2].apply(null, [e]);\n }\n reject(e);\n });\n }\n\n var streams = {};\n this.remoteStreams.forEach(function(stream) {\n streams[stream.id] = stream;\n });\n var receiverList = [];\n var sections = SDPUtils.splitSections(description.sdp);\n var sessionpart = sections.shift();\n var isIceLite = SDPUtils.matchPrefix(sessionpart,\n 'a=ice-lite').length > 0;\n var usingBundle = SDPUtils.matchPrefix(sessionpart,\n 'a=group:BUNDLE ').length > 0;\n this.usingBundle = usingBundle;\n var iceOptions = SDPUtils.matchPrefix(sessionpart,\n 'a=ice-options:')[0];\n if (iceOptions) {\n this.canTrickleIceCandidates = iceOptions.substr(14).split(' ')\n .indexOf('trickle') >= 0;\n } else {\n this.canTrickleIceCandidates = false;\n }\n\n sections.forEach(function(mediaSection, sdpMLineIndex) {\n var lines = SDPUtils.splitLines(mediaSection);\n var kind = SDPUtils.getKind(mediaSection);\n // treat bundle-only as not-rejected.\n var rejected = SDPUtils.isRejected(mediaSection) &&\n !SDPUtils.matchPrefix(mediaSection, 'a=bundle-only').length === 1;\n var protocol = lines[0].substr(2).split(' ')[2];\n\n var direction = SDPUtils.getDirection(mediaSection, sessionpart);\n var remoteMsid = SDPUtils.parseMsid(mediaSection);\n\n var mid = SDPUtils.getMid(mediaSection) || SDPUtils.generateIdentifier();\n\n // Reject datachannels which are not implemented yet.\n if (kind === 'application' && protocol === 'DTLS/SCTP') {\n self.transceivers[sdpMLineIndex] = {\n mid: mid,\n isDatachannel: true\n };\n return;\n }\n\n var transceiver;\n var iceGatherer;\n var iceTransport;\n var dtlsTransport;\n var rtpReceiver;\n var sendEncodingParameters;\n var recvEncodingParameters;\n var localCapabilities;\n\n var track;\n // FIXME: ensure the mediaSection has rtcp-mux set.\n var remoteCapabilities = SDPUtils.parseRtpParameters(mediaSection);\n var remoteIceParameters;\n var remoteDtlsParameters;\n if (!rejected) {\n remoteIceParameters = SDPUtils.getIceParameters(mediaSection,\n sessionpart);\n remoteDtlsParameters = SDPUtils.getDtlsParameters(mediaSection,\n sessionpart);\n remoteDtlsParameters.role = 'client';\n }\n recvEncodingParameters =\n SDPUtils.parseRtpEncodingParameters(mediaSection);\n\n var rtcpParameters = SDPUtils.parseRtcpParameters(mediaSection);\n\n var isComplete = SDPUtils.matchPrefix(mediaSection,\n 'a=end-of-candidates', sessionpart).length > 0;\n var cands = SDPUtils.matchPrefix(mediaSection, 'a=candidate:')\n .map(function(cand) {\n return SDPUtils.parseCandidate(cand);\n })\n .filter(function(cand) {\n return cand.component === 1;\n });\n\n // Check if we can use BUNDLE and dispose transports.\n if ((description.type === 'offer' || description.type === 'answer') &&\n !rejected && usingBundle && sdpMLineIndex > 0 &&\n self.transceivers[sdpMLineIndex]) {\n self._disposeIceAndDtlsTransports(sdpMLineIndex);\n self.transceivers[sdpMLineIndex].iceGatherer =\n self.transceivers[0].iceGatherer;\n self.transceivers[sdpMLineIndex].iceTransport =\n self.transceivers[0].iceTransport;\n self.transceivers[sdpMLineIndex].dtlsTransport =\n self.transceivers[0].dtlsTransport;\n if (self.transceivers[sdpMLineIndex].rtpSender) {\n self.transceivers[sdpMLineIndex].rtpSender.setTransport(\n self.transceivers[0].dtlsTransport);\n }\n if (self.transceivers[sdpMLineIndex].rtpReceiver) {\n self.transceivers[sdpMLineIndex].rtpReceiver.setTransport(\n self.transceivers[0].dtlsTransport);\n }\n }\n if (description.type === 'offer' && !rejected) {\n transceiver = self.transceivers[sdpMLineIndex] ||\n self._createTransceiver(kind);\n transceiver.mid = mid;\n\n if (!transceiver.iceGatherer) {\n transceiver.iceGatherer = self._createIceGatherer(sdpMLineIndex,\n usingBundle);\n }\n\n if (cands.length && transceiver.iceTransport.state === 'new') {\n if (isComplete && (!usingBundle || sdpMLineIndex === 0)) {\n transceiver.iceTransport.setRemoteCandidates(cands);\n } else {\n cands.forEach(function(candidate) {\n maybeAddCandidate(transceiver.iceTransport, candidate);\n });\n }\n }\n\n localCapabilities = window.RTCRtpReceiver.getCapabilities(kind);\n\n // filter RTX until additional stuff needed for RTX is implemented\n // in adapter.js\n if (edgeVersion < 15019) {\n localCapabilities.codecs = localCapabilities.codecs.filter(\n function(codec) {\n return codec.name !== 'rtx';\n });\n }\n\n sendEncodingParameters = transceiver.sendEncodingParameters || [{\n ssrc: (2 * sdpMLineIndex + 2) * 1001\n }];\n\n var isNewTrack = false;\n if (direction === 'sendrecv' || direction === 'sendonly') {\n isNewTrack = !transceiver.rtpReceiver;\n rtpReceiver = transceiver.rtpReceiver ||\n new window.RTCRtpReceiver(transceiver.dtlsTransport, kind);\n\n if (isNewTrack) {\n var stream;\n track = rtpReceiver.track;\n // FIXME: does not work with Plan B.\n if (remoteMsid) {\n if (!streams[remoteMsid.stream]) {\n streams[remoteMsid.stream] = new window.MediaStream();\n Object.defineProperty(streams[remoteMsid.stream], 'id', {\n get: function() {\n return remoteMsid.stream;\n }\n });\n }\n Object.defineProperty(track, 'id', {\n get: function() {\n return remoteMsid.track;\n }\n });\n stream = streams[remoteMsid.stream];\n } else {\n if (!streams.default) {\n streams.default = new window.MediaStream();\n }\n stream = streams.default;\n }\n stream.addTrack(track);\n receiverList.push([track, rtpReceiver, stream]);\n }\n }\n\n transceiver.localCapabilities = localCapabilities;\n transceiver.remoteCapabilities = remoteCapabilities;\n transceiver.rtpReceiver = rtpReceiver;\n transceiver.rtcpParameters = rtcpParameters;\n transceiver.sendEncodingParameters = sendEncodingParameters;\n transceiver.recvEncodingParameters = recvEncodingParameters;\n\n // Start the RTCRtpReceiver now. The RTPSender is started in\n // setLocalDescription.\n self._transceive(self.transceivers[sdpMLineIndex],\n false,\n isNewTrack);\n } else if (description.type === 'answer' && !rejected) {\n transceiver = self.transceivers[sdpMLineIndex];\n iceGatherer = transceiver.iceGatherer;\n iceTransport = transceiver.iceTransport;\n dtlsTransport = transceiver.dtlsTransport;\n rtpReceiver = transceiver.rtpReceiver;\n sendEncodingParameters = transceiver.sendEncodingParameters;\n localCapabilities = transceiver.localCapabilities;\n\n self.transceivers[sdpMLineIndex].recvEncodingParameters =\n recvEncodingParameters;\n self.transceivers[sdpMLineIndex].remoteCapabilities =\n remoteCapabilities;\n self.transceivers[sdpMLineIndex].rtcpParameters = rtcpParameters;\n\n if (cands.length && iceTransport.state === 'new') {\n if ((isIceLite || isComplete) &&\n (!usingBundle || sdpMLineIndex === 0)) {\n iceTransport.setRemoteCandidates(cands);\n } else {\n cands.forEach(function(candidate) {\n maybeAddCandidate(transceiver.iceTransport, candidate);\n });\n }\n }\n\n if (!usingBundle || sdpMLineIndex === 0) {\n if (iceTransport.state === 'new') {\n iceTransport.start(iceGatherer, remoteIceParameters,\n 'controlling');\n }\n if (dtlsTransport.state === 'new') {\n dtlsTransport.start(remoteDtlsParameters);\n }\n }\n\n self._transceive(transceiver,\n direction === 'sendrecv' || direction === 'recvonly',\n direction === 'sendrecv' || direction === 'sendonly');\n\n if (rtpReceiver &&\n (direction === 'sendrecv' || direction === 'sendonly')) {\n track = rtpReceiver.track;\n if (remoteMsid) {\n if (!streams[remoteMsid.stream]) {\n streams[remoteMsid.stream] = new window.MediaStream();\n }\n streams[remoteMsid.stream].addTrack(track);\n receiverList.push([track, rtpReceiver, streams[remoteMsid.stream]]);\n } else {\n if (!streams.default) {\n streams.default = new window.MediaStream();\n }\n streams.default.addTrack(track);\n receiverList.push([track, rtpReceiver, streams.default]);\n }\n } else {\n // FIXME: actually the receiver should be created later.\n delete transceiver.rtpReceiver;\n }\n }\n });\n\n if (this._dtlsRole === undefined) {\n this._dtlsRole = description.type === 'offer' ? 'active' : 'passive';\n }\n\n this.remoteDescription = {\n type: description.type,\n sdp: description.sdp\n };\n switch (description.type) {\n case 'offer':\n this._updateSignalingState('have-remote-offer');\n break;\n case 'answer':\n this._updateSignalingState('stable');\n break;\n default:\n throw new TypeError('unsupported type \"' + description.type +\n '\"');\n }\n Object.keys(streams).forEach(function(sid) {\n var stream = streams[sid];\n if (stream.getTracks().length) {\n if (self.remoteStreams.indexOf(stream) === -1) {\n self.remoteStreams.push(stream);\n var event = new Event('addstream');\n event.stream = stream;\n window.setTimeout(function() {\n self.dispatchEvent(event);\n if (typeof self.onaddstream === 'function') {\n self.onaddstream(event);\n }\n });\n }\n\n receiverList.forEach(function(item) {\n var track = item[0];\n var receiver = item[1];\n if (stream.id !== item[2].id) {\n return;\n }\n var trackEvent = new Event('track');\n trackEvent.track = track;\n trackEvent.receiver = receiver;\n trackEvent.transceiver = {receiver: receiver};\n trackEvent.streams = [stream];\n window.setTimeout(function() {\n self.dispatchEvent(trackEvent);\n if (typeof self.ontrack === 'function') {\n self.ontrack(trackEvent);\n }\n });\n });\n }\n });\n\n // check whether addIceCandidate({}) was called within four seconds after\n // setRemoteDescription.\n window.setTimeout(function() {\n if (!(self && self.transceivers)) {\n return;\n }\n self.transceivers.forEach(function(transceiver) {\n if (transceiver.iceTransport &&\n transceiver.iceTransport.state === 'new' &&\n transceiver.iceTransport.getRemoteCandidates().length > 0) {\n console.warn('Timeout for addRemoteCandidate. Consider sending ' +\n 'an end-of-candidates notification');\n transceiver.iceTransport.addRemoteCandidate({});\n }\n });\n }, 4000);\n\n return new Promise(function(resolve) {\n if (args.length > 1 && typeof args[1] === 'function') {\n args[1].apply(null);\n }\n resolve();\n });\n };\n\n RTCPeerConnection.prototype.close = function() {\n this.transceivers.forEach(function(transceiver) {\n /* not yet\n if (transceiver.iceGatherer) {\n transceiver.iceGatherer.close();\n }\n */\n if (transceiver.iceTransport) {\n transceiver.iceTransport.stop();\n }\n if (transceiver.dtlsTransport) {\n transceiver.dtlsTransport.stop();\n }\n if (transceiver.rtpSender) {\n transceiver.rtpSender.stop();\n }\n if (transceiver.rtpReceiver) {\n transceiver.rtpReceiver.stop();\n }\n });\n // FIXME: clean up tracks, local streams, remote streams, etc\n this._updateSignalingState('closed');\n };\n\n // Update the signaling state.\n RTCPeerConnection.prototype._updateSignalingState = function(newState) {\n this.signalingState = newState;\n var event = new Event('signalingstatechange');\n this.dispatchEvent(event);\n if (typeof this.onsignalingstatechange === 'function') {\n this.onsignalingstatechange(event);\n }\n };\n\n // Determine whether to fire the negotiationneeded event.\n RTCPeerConnection.prototype._maybeFireNegotiationNeeded = function() {\n var self = this;\n if (this.signalingState !== 'stable' || this.needNegotiation === true) {\n return;\n }\n this.needNegotiation = true;\n window.setTimeout(function() {\n if (self.needNegotiation === false) {\n return;\n }\n self.needNegotiation = false;\n var event = new Event('negotiationneeded');\n self.dispatchEvent(event);\n if (typeof self.onnegotiationneeded === 'function') {\n self.onnegotiationneeded(event);\n }\n }, 0);\n };\n\n // Update the connection state.\n RTCPeerConnection.prototype._updateConnectionState = function() {\n var newState;\n var states = {\n 'new': 0,\n closed: 0,\n connecting: 0,\n checking: 0,\n connected: 0,\n completed: 0,\n disconnected: 0,\n failed: 0\n };\n this.transceivers.forEach(function(transceiver) {\n states[transceiver.iceTransport.state]++;\n states[transceiver.dtlsTransport.state]++;\n });\n // ICETransport.completed and connected are the same for this purpose.\n states.connected += states.completed;\n\n newState = 'new';\n if (states.failed > 0) {\n newState = 'failed';\n } else if (states.connecting > 0 || states.checking > 0) {\n newState = 'connecting';\n } else if (states.disconnected > 0) {\n newState = 'disconnected';\n } else if (states.new > 0) {\n newState = 'new';\n } else if (states.connected > 0 || states.completed > 0) {\n newState = 'connected';\n }\n\n if (newState !== this.iceConnectionState) {\n this.iceConnectionState = newState;\n var event = new Event('iceconnectionstatechange');\n this.dispatchEvent(event);\n if (typeof this.oniceconnectionstatechange === 'function') {\n this.oniceconnectionstatechange(event);\n }\n }\n };\n\n RTCPeerConnection.prototype.createOffer = function() {\n var self = this;\n var args = arguments;\n\n var offerOptions;\n if (arguments.length === 1 && typeof arguments[0] !== 'function') {\n offerOptions = arguments[0];\n } else if (arguments.length === 3) {\n offerOptions = arguments[2];\n }\n\n var numAudioTracks = this.transceivers.filter(function(t) {\n return t.kind === 'audio';\n }).length;\n var numVideoTracks = this.transceivers.filter(function(t) {\n return t.kind === 'video';\n }).length;\n\n // Determine number of audio and video tracks we need to send/recv.\n if (offerOptions) {\n // Reject Chrome legacy constraints.\n if (offerOptions.mandatory || offerOptions.optional) {\n throw new TypeError(\n 'Legacy mandatory/optional constraints not supported.');\n }\n if (offerOptions.offerToReceiveAudio !== undefined) {\n if (offerOptions.offerToReceiveAudio === true) {\n numAudioTracks = 1;\n } else if (offerOptions.offerToReceiveAudio === false) {\n numAudioTracks = 0;\n } else {\n numAudioTracks = offerOptions.offerToReceiveAudio;\n }\n }\n if (offerOptions.offerToReceiveVideo !== undefined) {\n if (offerOptions.offerToReceiveVideo === true) {\n numVideoTracks = 1;\n } else if (offerOptions.offerToReceiveVideo === false) {\n numVideoTracks = 0;\n } else {\n numVideoTracks = offerOptions.offerToReceiveVideo;\n }\n }\n }\n\n this.transceivers.forEach(function(transceiver) {\n if (transceiver.kind === 'audio') {\n numAudioTracks--;\n if (numAudioTracks < 0) {\n transceiver.wantReceive = false;\n }\n } else if (transceiver.kind === 'video') {\n numVideoTracks--;\n if (numVideoTracks < 0) {\n transceiver.wantReceive = false;\n }\n }\n });\n\n // Create M-lines for recvonly streams.\n while (numAudioTracks > 0 || numVideoTracks > 0) {\n if (numAudioTracks > 0) {\n this._createTransceiver('audio');\n numAudioTracks--;\n }\n if (numVideoTracks > 0) {\n this._createTransceiver('video');\n numVideoTracks--;\n }\n }\n\n var sdp = SDPUtils.writeSessionBoilerplate(this._sdpSessionId,\n this._sdpSessionVersion++);\n this.transceivers.forEach(function(transceiver, sdpMLineIndex) {\n // For each track, create an ice gatherer, ice transport,\n // dtls transport, potentially rtpsender and rtpreceiver.\n var track = transceiver.track;\n var kind = transceiver.kind;\n var mid = SDPUtils.generateIdentifier();\n transceiver.mid = mid;\n\n if (!transceiver.iceGatherer) {\n transceiver.iceGatherer = self._createIceGatherer(sdpMLineIndex,\n self.usingBundle);\n }\n\n var localCapabilities = window.RTCRtpSender.getCapabilities(kind);\n // filter RTX until additional stuff needed for RTX is implemented\n // in adapter.js\n if (edgeVersion < 15019) {\n localCapabilities.codecs = localCapabilities.codecs.filter(\n function(codec) {\n return codec.name !== 'rtx';\n });\n }\n localCapabilities.codecs.forEach(function(codec) {\n // work around https://bugs.chromium.org/p/webrtc/issues/detail?id=6552\n // by adding level-asymmetry-allowed=1\n if (codec.name === 'H264' &&\n codec.parameters['level-asymmetry-allowed'] === undefined) {\n codec.parameters['level-asymmetry-allowed'] = '1';\n }\n });\n\n // generate an ssrc now, to be used later in rtpSender.send\n var sendEncodingParameters = transceiver.sendEncodingParameters || [{\n ssrc: (2 * sdpMLineIndex + 1) * 1001\n }];\n if (track) {\n // add RTX\n if (edgeVersion >= 15019 && kind === 'video' &&\n !sendEncodingParameters[0].rtx) {\n sendEncodingParameters[0].rtx = {\n ssrc: sendEncodingParameters[0].ssrc + 1\n };\n }\n }\n\n if (transceiver.wantReceive) {\n transceiver.rtpReceiver = new window.RTCRtpReceiver(\n transceiver.dtlsTransport, kind);\n }\n\n transceiver.localCapabilities = localCapabilities;\n transceiver.sendEncodingParameters = sendEncodingParameters;\n });\n\n // always offer BUNDLE and dispose on return if not supported.\n if (this._config.bundlePolicy !== 'max-compat') {\n sdp += 'a=group:BUNDLE ' + this.transceivers.map(function(t) {\n return t.mid;\n }).join(' ') + '\\r\\n';\n }\n sdp += 'a=ice-options:trickle\\r\\n';\n\n this.transceivers.forEach(function(transceiver, sdpMLineIndex) {\n sdp += writeMediaSection(transceiver, transceiver.localCapabilities,\n 'offer', transceiver.stream, self._dtlsRole);\n sdp += 'a=rtcp-rsize\\r\\n';\n\n if (transceiver.iceGatherer && self.iceGatheringState !== 'new' &&\n (sdpMLineIndex === 0 || !self.usingBundle)) {\n transceiver.iceGatherer.getLocalCandidates().forEach(function(cand) {\n cand.component = 1;\n sdp += 'a=' + SDPUtils.writeCandidate(cand) + '\\r\\n';\n });\n\n if (transceiver.iceGatherer.state === 'completed') {\n sdp += 'a=end-of-candidates\\r\\n';\n }\n }\n });\n\n var desc = new window.RTCSessionDescription({\n type: 'offer',\n sdp: sdp\n });\n return new Promise(function(resolve) {\n if (args.length > 0 && typeof args[0] === 'function') {\n args[0].apply(null, [desc]);\n resolve();\n return;\n }\n resolve(desc);\n });\n };\n\n RTCPeerConnection.prototype.createAnswer = function() {\n var self = this;\n var args = arguments;\n\n var sdp = SDPUtils.writeSessionBoilerplate(this._sdpSessionId,\n this._sdpSessionVersion++);\n if (this.usingBundle) {\n sdp += 'a=group:BUNDLE ' + this.transceivers.map(function(t) {\n return t.mid;\n }).join(' ') + '\\r\\n';\n }\n var mediaSectionsInOffer = SDPUtils.splitSections(\n this.remoteDescription.sdp).length - 1;\n this.transceivers.forEach(function(transceiver, sdpMLineIndex) {\n if (sdpMLineIndex + 1 > mediaSectionsInOffer) {\n return;\n }\n if (transceiver.isDatachannel) {\n sdp += 'm=application 0 DTLS/SCTP 5000\\r\\n' +\n 'c=IN IP4 0.0.0.0\\r\\n' +\n 'a=mid:' + transceiver.mid + '\\r\\n';\n return;\n }\n\n // FIXME: look at direction.\n if (transceiver.stream) {\n var localTrack;\n if (transceiver.kind === 'audio') {\n localTrack = transceiver.stream.getAudioTracks()[0];\n } else if (transceiver.kind === 'video') {\n localTrack = transceiver.stream.getVideoTracks()[0];\n }\n if (localTrack) {\n // add RTX\n if (edgeVersion >= 15019 && transceiver.kind === 'video' &&\n !transceiver.sendEncodingParameters[0].rtx) {\n transceiver.sendEncodingParameters[0].rtx = {\n ssrc: transceiver.sendEncodingParameters[0].ssrc + 1\n };\n }\n }\n }\n\n // Calculate intersection of capabilities.\n var commonCapabilities = getCommonCapabilities(\n transceiver.localCapabilities,\n transceiver.remoteCapabilities);\n\n var hasRtx = commonCapabilities.codecs.filter(function(c) {\n return c.name.toLowerCase() === 'rtx';\n }).length;\n if (!hasRtx && transceiver.sendEncodingParameters[0].rtx) {\n delete transceiver.sendEncodingParameters[0].rtx;\n }\n\n sdp += writeMediaSection(transceiver, commonCapabilities,\n 'answer', transceiver.stream, self._dtlsRole);\n if (transceiver.rtcpParameters &&\n transceiver.rtcpParameters.reducedSize) {\n sdp += 'a=rtcp-rsize\\r\\n';\n }\n });\n\n var desc = new window.RTCSessionDescription({\n type: 'answer',\n sdp: sdp\n });\n return new Promise(function(resolve) {\n if (args.length > 0 && typeof args[0] === 'function') {\n args[0].apply(null, [desc]);\n resolve();\n return;\n }\n resolve(desc);\n });\n };\n\n RTCPeerConnection.prototype.addIceCandidate = function(candidate) {\n var err;\n var sections;\n if (!candidate || candidate.candidate === '') {\n for (var j = 0; j < this.transceivers.length; j++) {\n if (this.transceivers[j].isDatachannel) {\n continue;\n }\n this.transceivers[j].iceTransport.addRemoteCandidate({});\n sections = SDPUtils.splitSections(this.remoteDescription.sdp);\n sections[j + 1] += 'a=end-of-candidates\\r\\n';\n this.remoteDescription.sdp = sections.join('');\n if (this.usingBundle) {\n break;\n }\n }\n } else if (!(candidate.sdpMLineIndex !== undefined || candidate.sdpMid)) {\n throw new TypeError('sdpMLineIndex or sdpMid required');\n } else if (!this.remoteDescription) {\n err = new Error('Can not add ICE candidate without ' +\n 'a remote description');\n err.name = 'InvalidStateError';\n } else {\n var sdpMLineIndex = candidate.sdpMLineIndex;\n if (candidate.sdpMid) {\n for (var i = 0; i < this.transceivers.length; i++) {\n if (this.transceivers[i].mid === candidate.sdpMid) {\n sdpMLineIndex = i;\n break;\n }\n }\n }\n var transceiver = this.transceivers[sdpMLineIndex];\n if (transceiver) {\n if (transceiver.isDatachannel) {\n return Promise.resolve();\n }\n var cand = Object.keys(candidate.candidate).length > 0 ?\n SDPUtils.parseCandidate(candidate.candidate) : {};\n // Ignore Chrome's invalid candidates since Edge does not like them.\n if (cand.protocol === 'tcp' && (cand.port === 0 || cand.port === 9)) {\n return Promise.resolve();\n }\n // Ignore RTCP candidates, we assume RTCP-MUX.\n if (cand.component && cand.component !== 1) {\n return Promise.resolve();\n }\n // when using bundle, avoid adding candidates to the wrong\n // ice transport. And avoid adding candidates added in the SDP.\n if (sdpMLineIndex === 0 || (sdpMLineIndex > 0 &&\n transceiver.iceTransport !== this.transceivers[0].iceTransport)) {\n if (!maybeAddCandidate(transceiver.iceTransport, cand)) {\n err = new Error('Can not add ICE candidate');\n err.name = 'OperationError';\n }\n }\n\n if (!err) {\n // update the remoteDescription.\n var candidateString = candidate.candidate.trim();\n if (candidateString.indexOf('a=') === 0) {\n candidateString = candidateString.substr(2);\n }\n sections = SDPUtils.splitSections(this.remoteDescription.sdp);\n sections[sdpMLineIndex + 1] += 'a=' +\n (cand.type ? candidateString : 'end-of-candidates')\n + '\\r\\n';\n this.remoteDescription.sdp = sections.join('');\n }\n } else {\n err = new Error('Can not add ICE candidate');\n err.name = 'OperationError';\n }\n }\n var args = arguments;\n return new Promise(function(resolve, reject) {\n if (err) {\n if (args.length > 2 && typeof args[2] === 'function') {\n args[2].apply(null, [err]);\n }\n reject(err);\n } else {\n if (args.length > 1 && typeof args[1] === 'function') {\n args[1].apply(null);\n }\n resolve();\n }\n });\n };\n\n RTCPeerConnection.prototype.getStats = function() {\n var promises = [];\n this.transceivers.forEach(function(transceiver) {\n ['rtpSender', 'rtpReceiver', 'iceGatherer', 'iceTransport',\n 'dtlsTransport'].forEach(function(method) {\n if (transceiver[method]) {\n promises.push(transceiver[method].getStats());\n }\n });\n });\n var cb = arguments.length > 1 && typeof arguments[1] === 'function' &&\n arguments[1];\n var fixStatsType = function(stat) {\n return {\n inboundrtp: 'inbound-rtp',\n outboundrtp: 'outbound-rtp',\n candidatepair: 'candidate-pair',\n localcandidate: 'local-candidate',\n remotecandidate: 'remote-candidate'\n }[stat.type] || stat.type;\n };\n return new Promise(function(resolve) {\n // shim getStats with maplike support\n var results = new Map();\n Promise.all(promises).then(function(res) {\n res.forEach(function(result) {\n Object.keys(result).forEach(function(id) {\n result[id].type = fixStatsType(result[id]);\n results.set(id, result[id]);\n });\n });\n if (cb) {\n cb.apply(null, results);\n }\n resolve(results);\n });\n });\n };\n return RTCPeerConnection;\n};\n","var grammar = module.exports = {\n v: [{\n name: 'version',\n reg: /^(\\d*)$/\n }],\n o: [{ //o=- 20518 0 IN IP4 203.0.113.1\n // NB: sessionId will be a String in most cases because it is huge\n name: 'origin',\n reg: /^(\\S*) (\\d*) (\\d*) (\\S*) IP(\\d) (\\S*)/,\n names: ['username', 'sessionId', 'sessionVersion', 'netType', 'ipVer', 'address'],\n format: \"%s %s %d %s IP%d %s\"\n }],\n // default parsing of these only (though some of these feel outdated)\n s: [{ name: 'name' }],\n i: [{ name: 'description' }],\n u: [{ name: 'uri' }],\n e: [{ name: 'email' }],\n p: [{ name: 'phone' }],\n z: [{ name: 'timezones' }], // TODO: this one can actually be parsed properly..\n r: [{ name: 'repeats' }], // TODO: this one can also be parsed properly\n //k: [{}], // outdated thing ignored\n t: [{ //t=0 0\n name: 'timing',\n reg: /^(\\d*) (\\d*)/,\n names: ['start', 'stop'],\n format: \"%d %d\"\n }],\n c: [{ //c=IN IP4 10.47.197.26\n name: 'connection',\n reg: /^IN IP(\\d) (\\S*)/,\n names: ['version', 'ip'],\n format: \"IN IP%d %s\"\n }],\n b: [{ //b=AS:4000\n push: 'bandwidth',\n reg: /^(TIAS|AS|CT|RR|RS):(\\d*)/,\n names: ['type', 'limit'],\n format: \"%s:%s\"\n }],\n m: [{ //m=video 51744 RTP/AVP 126 97 98 34 31\n // NB: special - pushes to session\n // TODO: rtp/fmtp should be filtered by the payloads found here?\n reg: /^(\\w*) (\\d*) ([\\w\\/]*)(?: (.*))?/,\n names: ['type', 'port', 'protocol', 'payloads'],\n format: \"%s %d %s %s\"\n }],\n a: [\n { //a=rtpmap:110 opus/48000/2\n push: 'rtp',\n reg: /^rtpmap:(\\d*) ([\\w\\-]*)(?:\\s*\\/(\\d*)(?:\\s*\\/(\\S*))?)?/,\n names: ['payload', 'codec', 'rate', 'encoding'],\n format: function (o) {\n return (o.encoding) ?\n \"rtpmap:%d %s/%s/%s\":\n o.rate ?\n \"rtpmap:%d %s/%s\":\n \"rtpmap:%d %s\";\n }\n },\n {\n //a=fmtp:108 profile-level-id=24;object=23;bitrate=64000\n //a=fmtp:111 minptime=10; useinbandfec=1\n push: 'fmtp',\n reg: /^fmtp:(\\d*) ([\\S| ]*)/,\n names: ['payload', 'config'],\n format: \"fmtp:%d %s\"\n },\n { //a=control:streamid=0\n name: 'control',\n reg: /^control:(.*)/,\n format: \"control:%s\"\n },\n { //a=rtcp:65179 IN IP4 193.84.77.194\n name: 'rtcp',\n reg: /^rtcp:(\\d*)(?: (\\S*) IP(\\d) (\\S*))?/,\n names: ['port', 'netType', 'ipVer', 'address'],\n format: function (o) {\n return (o.address != null) ?\n \"rtcp:%d %s IP%d %s\":\n \"rtcp:%d\";\n }\n },\n { //a=rtcp-fb:98 trr-int 100\n push: 'rtcpFbTrrInt',\n reg: /^rtcp-fb:(\\*|\\d*) trr-int (\\d*)/,\n names: ['payload', 'value'],\n format: \"rtcp-fb:%d trr-int %d\"\n },\n { //a=rtcp-fb:98 nack rpsi\n push: 'rtcpFb',\n reg: /^rtcp-fb:(\\*|\\d*) ([\\w-_]*)(?: ([\\w-_]*))?/,\n names: ['payload', 'type', 'subtype'],\n format: function (o) {\n return (o.subtype != null) ?\n \"rtcp-fb:%s %s %s\":\n \"rtcp-fb:%s %s\";\n }\n },\n { //a=extmap:2 urn:ietf:params:rtp-hdrext:toffset\n //a=extmap:1/recvonly URI-gps-string\n push: 'ext',\n reg: /^extmap:([\\w_\\/]*) (\\S*)(?: (\\S*))?/,\n names: ['value', 'uri', 'config'], // value may include \"/direction\" suffix\n format: function (o) {\n return (o.config != null) ?\n \"extmap:%s %s %s\":\n \"extmap:%s %s\";\n }\n },\n {\n //a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:PS1uQCVeeCFCanVmcjkpPywjNWhcYD0mXXtxaVBR|2^20|1:32\n push: 'crypto',\n reg: /^crypto:(\\d*) ([\\w_]*) (\\S*)(?: (\\S*))?/,\n names: ['id', 'suite', 'config', 'sessionConfig'],\n format: function (o) {\n return (o.sessionConfig != null) ?\n \"crypto:%d %s %s %s\":\n \"crypto:%d %s %s\";\n }\n },\n { //a=setup:actpass\n name: 'setup',\n reg: /^setup:(\\w*)/,\n format: \"setup:%s\"\n },\n { //a=mid:1\n name: 'mid',\n reg: /^mid:([^\\s]*)/,\n format: \"mid:%s\"\n },\n { //a=msid:0c8b064d-d807-43b4-b434-f92a889d8587 98178685-d409-46e0-8e16-7ef0db0db64a\n name: 'msid',\n reg: /^msid:(.*)/,\n format: \"msid:%s\"\n },\n { //a=ptime:20\n name: 'ptime',\n reg: /^ptime:(\\d*)/,\n format: \"ptime:%d\"\n },\n { //a=maxptime:60\n name: 'maxptime',\n reg: /^maxptime:(\\d*)/,\n format: \"maxptime:%d\"\n },\n { //a=sendrecv\n name: 'direction',\n reg: /^(sendrecv|recvonly|sendonly|inactive)/\n },\n { //a=ice-lite\n name: 'icelite',\n reg: /^(ice-lite)/\n },\n { //a=ice-ufrag:F7gI\n name: 'iceUfrag',\n reg: /^ice-ufrag:(\\S*)/,\n format: \"ice-ufrag:%s\"\n },\n { //a=ice-pwd:x9cml/YzichV2+XlhiMu8g\n name: 'icePwd',\n reg: /^ice-pwd:(\\S*)/,\n format: \"ice-pwd:%s\"\n },\n { //a=fingerprint:SHA-1 00:11:22:33:44:55:66:77:88:99:AA:BB:CC:DD:EE:FF:00:11:22:33\n name: 'fingerprint',\n reg: /^fingerprint:(\\S*) (\\S*)/,\n names: ['type', 'hash'],\n format: \"fingerprint:%s %s\"\n },\n {\n //a=candidate:0 1 UDP 2113667327 203.0.113.1 54400 typ host\n //a=candidate:1162875081 1 udp 2113937151 192.168.34.75 60017 typ host generation 0\n //a=candidate:3289912957 2 udp 1845501695 193.84.77.194 60017 typ srflx raddr 192.168.34.75 rport 60017 generation 0\n //a=candidate:229815620 1 tcp 1518280447 192.168.150.19 60017 typ host tcptype active generation 0\n //a=candidate:3289912957 2 tcp 1845501695 193.84.77.194 60017 typ srflx raddr 192.168.34.75 rport 60017 tcptype passive generation 0\n push:'candidates',\n reg: /^candidate:(\\S*) (\\d*) (\\S*) (\\d*) (\\S*) (\\d*) typ (\\S*)(?: raddr (\\S*) rport (\\d*))?(?: tcptype (\\S*))?(?: generation (\\d*))?/,\n names: ['foundation', 'component', 'transport', 'priority', 'ip', 'port', 'type', 'raddr', 'rport', 'tcptype', 'generation'],\n format: function (o) {\n var str = \"candidate:%s %d %s %d %s %d typ %s\";\n\n str += (o.raddr != null) ? \" raddr %s rport %d\" : \"%v%v\";\n\n // NB: candidate has three optional chunks, so %void middles one if it's missing\n str += (o.tcptype != null) ? \" tcptype %s\" : \"%v\";\n\n if (o.generation != null) {\n str += \" generation %d\";\n }\n return str;\n }\n },\n { //a=end-of-candidates (keep after the candidates line for readability)\n name: 'endOfCandidates',\n reg: /^(end-of-candidates)/\n },\n { //a=remote-candidates:1 203.0.113.1 54400 2 203.0.113.1 54401 ...\n name: 'remoteCandidates',\n reg: /^remote-candidates:(.*)/,\n format: \"remote-candidates:%s\"\n },\n { //a=ice-options:google-ice\n name: 'iceOptions',\n reg: /^ice-options:(\\S*)/,\n format: \"ice-options:%s\"\n },\n { //a=ssrc:2566107569 cname:t9YU8M1UxTF8Y1A1\n push: \"ssrcs\",\n reg: /^ssrc:(\\d*) ([\\w_]*):(.*)/,\n names: ['id', 'attribute', 'value'],\n format: \"ssrc:%d %s:%s\"\n },\n { //a=ssrc-group:FEC 1 2\n push: \"ssrcGroups\",\n reg: /^ssrc-group:(\\w*) (.*)/,\n names: ['semantics', 'ssrcs'],\n format: \"ssrc-group:%s %s\"\n },\n { //a=msid-semantic: WMS Jvlam5X3SX1OP6pn20zWogvaKJz5Hjf9OnlV\n name: \"msidSemantic\",\n reg: /^msid-semantic:\\s?(\\w*) (\\S*)/,\n names: ['semantic', 'token'],\n format: \"msid-semantic: %s %s\" // space after \":\" is not accidental\n },\n { //a=group:BUNDLE audio video\n push: 'groups',\n reg: /^group:(\\w*) (.*)/,\n names: ['type', 'mids'],\n format: \"group:%s %s\"\n },\n { //a=rtcp-mux\n name: 'rtcpMux',\n reg: /^(rtcp-mux)/\n },\n { //a=rtcp-rsize\n name: 'rtcpRsize',\n reg: /^(rtcp-rsize)/\n },\n { // any a= that we don't understand is kepts verbatim on media.invalid\n push: 'invalid',\n names: [\"value\"]\n }\n ]\n};\n\n// set sensible defaults to avoid polluting the grammar with boring details\nObject.keys(grammar).forEach(function (key) {\n var objs = grammar[key];\n objs.forEach(function (obj) {\n if (!obj.reg) {\n obj.reg = /(.*)/;\n }\n if (!obj.format) {\n obj.format = \"%s\";\n }\n });\n});\n","var parser = require('./parser');\nvar writer = require('./writer');\n\nexports.write = writer;\nexports.parse = parser.parse;\nexports.parseFmtpConfig = parser.parseFmtpConfig;\nexports.parsePayloads = parser.parsePayloads;\nexports.parseRemoteCandidates = parser.parseRemoteCandidates;\n","var toIntIfInt = function (v) {\n return String(Number(v)) === v ? Number(v) : v;\n};\n\nvar attachProperties = function (match, location, names, rawName) {\n if (rawName && !names) {\n location[rawName] = toIntIfInt(match[1]);\n }\n else {\n for (var i = 0; i < names.length; i += 1) {\n if (match[i+1] != null) {\n location[names[i]] = toIntIfInt(match[i+1]);\n }\n }\n }\n};\n\nvar parseReg = function (obj, location, content) {\n var needsBlank = obj.name && obj.names;\n if (obj.push && !location[obj.push]) {\n location[obj.push] = [];\n }\n else if (needsBlank && !location[obj.name]) {\n location[obj.name] = {};\n }\n var keyLocation = obj.push ?\n {} : // blank object that will be pushed\n needsBlank ? location[obj.name] : location; // otherwise, named location or root\n\n attachProperties(content.match(obj.reg), keyLocation, obj.names, obj.name);\n\n if (obj.push) {\n location[obj.push].push(keyLocation);\n }\n};\n\nvar grammar = require('./grammar');\nvar validLine = RegExp.prototype.test.bind(/^([a-z])=(.*)/);\n\nexports.parse = function (sdp) {\n var session = {}\n , media = []\n , location = session; // points at where properties go under (one of the above)\n\n // parse lines we understand\n sdp.split(/(\\r\\n|\\r|\\n)/).filter(validLine).forEach(function (l) {\n var type = l[0];\n var content = l.slice(2);\n if (type === 'm') {\n media.push({rtp: [], fmtp: []});\n location = media[media.length-1]; // point at latest media line\n }\n\n for (var j = 0; j < (grammar[type] || []).length; j += 1) {\n var obj = grammar[type][j];\n if (obj.reg.test(content)) {\n return parseReg(obj, location, content);\n }\n }\n });\n\n session.media = media; // link it up\n return session;\n};\n\nvar fmtpReducer = function (acc, expr) {\n var s = expr.split('=');\n if (s.length === 2) {\n acc[s[0]] = toIntIfInt(s[1]);\n }\n return acc;\n};\n\nexports.parseFmtpConfig = function (str) {\n return str.split(/\\;\\s?/).reduce(fmtpReducer, {});\n};\n\nexports.parsePayloads = function (str) {\n return str.split(' ').map(Number);\n};\n\nexports.parseRemoteCandidates = function (str) {\n var candidates = [];\n var parts = str.split(' ').map(toIntIfInt);\n for (var i = 0; i < parts.length; i += 3) {\n candidates.push({\n component: parts[i],\n ip: parts[i + 1],\n port: parts[i + 2]\n });\n }\n return candidates;\n};\n","var grammar = require('./grammar');\n\n// customized util.format - discards excess arguments and can void middle ones\nvar formatRegExp = /%[sdv%]/g;\nvar format = function (formatStr) {\n var i = 1;\n var args = arguments;\n var len = args.length;\n return formatStr.replace(formatRegExp, function (x) {\n if (i >= len) {\n return x; // missing argument\n }\n var arg = args[i];\n i += 1;\n switch (x) {\n case '%%':\n return '%';\n case '%s':\n return String(arg);\n case '%d':\n return Number(arg);\n case '%v':\n return '';\n }\n });\n // NB: we discard excess arguments - they are typically undefined from makeLine\n};\n\nvar makeLine = function (type, obj, location) {\n var str = obj.format instanceof Function ?\n (obj.format(obj.push ? location : location[obj.name])) :\n obj.format;\n\n var args = [type + '=' + str];\n if (obj.names) {\n for (var i = 0; i < obj.names.length; i += 1) {\n var n = obj.names[i];\n if (obj.name) {\n args.push(location[obj.name][n]);\n }\n else { // for mLine and push attributes\n args.push(location[obj.names[i]]);\n }\n }\n }\n else {\n args.push(location[obj.name]);\n }\n return format.apply(null, args);\n};\n\n// RFC specified order\n// TODO: extend this with all the rest\nvar defaultOuterOrder = [\n 'v', 'o', 's', 'i',\n 'u', 'e', 'p', 'c',\n 'b', 't', 'r', 'z', 'a'\n];\nvar defaultInnerOrder = ['i', 'c', 'b', 'a'];\n\n\nmodule.exports = function (session, opts) {\n opts = opts || {};\n // ensure certain properties exist\n if (session.version == null) {\n session.version = 0; // \"v=0\" must be there (only defined version atm)\n }\n if (session.name == null) {\n session.name = \" \"; // \"s= \" must be there if no meaningful name set\n }\n session.media.forEach(function (mLine) {\n if (mLine.payloads == null) {\n mLine.payloads = \"\";\n }\n });\n\n var outerOrder = opts.outerOrder || defaultOuterOrder;\n var innerOrder = opts.innerOrder || defaultInnerOrder;\n var sdp = [];\n\n // loop through outerOrder for matching properties on session\n outerOrder.forEach(function (type) {\n grammar[type].forEach(function (obj) {\n if (obj.name in session && session[obj.name] != null) {\n sdp.push(makeLine(type, obj, session));\n }\n else if (obj.push in session && session[obj.push] != null) {\n session[obj.push].forEach(function (el) {\n sdp.push(makeLine(type, obj, el));\n });\n }\n });\n });\n\n // then for each media line, follow the innerOrder\n session.media.forEach(function (mLine) {\n sdp.push(makeLine('m', grammar.m[0], mLine));\n\n innerOrder.forEach(function (type) {\n grammar[type].forEach(function (obj) {\n if (obj.name in mLine && mLine[obj.name] != null) {\n sdp.push(makeLine(type, obj, mLine));\n }\n else if (obj.push in mLine && mLine[obj.push] != null) {\n mLine[obj.push].forEach(function (el) {\n sdp.push(makeLine(type, obj, el));\n });\n }\n });\n });\n });\n\n return sdp.join('\\r\\n') + '\\r\\n';\n};\n","/* Copyright @ 2015 Atlassian Pty Ltd\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nmodule.exports = function arrayEquals(array) {\n // if the other array is a falsy value, return\n if (!array)\n return false;\n\n // compare lengths - can save a lot of time\n if (this.length != array.length)\n return false;\n\n for (var i = 0, l = this.length; i < l; i++) {\n // Check if we have nested arrays\n if (this[i] instanceof Array && array[i] instanceof Array) {\n // recurse into the nested arrays\n if (!arrayEquals.apply(this[i], [array[i]]))\n return false;\n } else if (this[i] != array[i]) {\n // Warning - two different object instances will never be equal:\n // {x:20} != {x:20}\n return false;\n }\n }\n return true;\n};\n\n","/* Copyright @ 2015 Atlassian Pty Ltd\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nexports.Interop = require('./interop');\n","/* Copyright @ 2015 Atlassian Pty Ltd\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/* global RTCSessionDescription */\n/* global RTCIceCandidate */\n/* jshint -W097 */\n\"use strict\";\n\nvar transform = require('./transform');\nvar arrayEquals = require('./array-equals');\n\nfunction Interop() {\n\n /**\n * This map holds the most recent Unified Plan offer/answer SDP that was\n * converted to Plan B, with the SDP type ('offer' or 'answer') as keys and\n * the SDP string as values.\n *\n * @type {{}}\n */\n this.cache = {\n mlB2UMap : {},\n mlU2BMap : {}\n };\n}\n\nmodule.exports = Interop;\n\n/**\n * Changes the candidate args to match with the related Unified Plan\n */\nInterop.prototype.candidateToUnifiedPlan = function(candidate) {\n var cand = new RTCIceCandidate(candidate);\n\n cand.sdpMLineIndex = this.cache.mlB2UMap[cand.sdpMLineIndex];\n /* TODO: change sdpMid to (audio|video)-SSRC */\n\n return cand;\n};\n\n/**\n * Changes the candidate args to match with the related Plan B\n */\nInterop.prototype.candidateToPlanB = function(candidate) {\n var cand = new RTCIceCandidate(candidate);\n\n if (cand.sdpMid.indexOf('audio') === 0) {\n cand.sdpMid = 'audio';\n } else if (cand.sdpMid.indexOf('video') === 0) {\n cand.sdpMid = 'video';\n } else {\n throw new Error('candidate with ' + cand.sdpMid + ' not allowed');\n }\n\n cand.sdpMLineIndex = this.cache.mlU2BMap[cand.sdpMLineIndex];\n\n return cand;\n};\n\n/**\n * Returns the index of the first m-line with the given media type and with a\n * direction which allows sending, in the last Unified Plan description with\n * type \"answer\" converted to Plan B. Returns {null} if there is no saved\n * answer, or if none of its m-lines with the given type allow sending.\n * @param type the media type (\"audio\" or \"video\").\n * @returns {*}\n */\nInterop.prototype.getFirstSendingIndexFromAnswer = function(type) {\n if (!this.cache.answer) {\n return null;\n }\n\n var session = transform.parse(this.cache.answer);\n if (session && session.media && Array.isArray(session.media)){\n for (var i = 0; i < session.media.length; i++) {\n if (session.media[i].type == type &&\n (!session.media[i].direction /* default to sendrecv */ ||\n session.media[i].direction === 'sendrecv' ||\n session.media[i].direction === 'sendonly')){\n return i;\n }\n }\n }\n\n return null;\n};\n\n/**\n * This method transforms a Unified Plan SDP to an equivalent Plan B SDP. A\n * PeerConnection wrapper transforms the SDP to Plan B before passing it to the\n * application.\n *\n * @param desc\n * @returns {*}\n */\nInterop.prototype.toPlanB = function(desc) {\n var self = this;\n //#region Preliminary input validation.\n\n if (typeof desc !== 'object' || desc === null ||\n typeof desc.sdp !== 'string') {\n console.warn('An empty description was passed as an argument.');\n return desc;\n }\n\n // Objectify the SDP for easier manipulation.\n var session = transform.parse(desc.sdp);\n\n // If the SDP contains no media, there's nothing to transform.\n if (typeof session.media === 'undefined' ||\n !Array.isArray(session.media) || session.media.length === 0) {\n console.warn('The description has no media.');\n return desc;\n }\n\n // Try some heuristics to \"make sure\" this is a Unified Plan SDP. Plan B\n // SDP has a video, an audio and a data \"channel\" at most.\n if (session.media.length <= 3 && session.media.every(function(m) {\n return ['video', 'audio', 'data'].indexOf(m.mid) !== -1;\n })) {\n console.warn('This description does not look like Unified Plan.');\n return desc;\n }\n\n //#endregion\n\n // HACK https://bugzilla.mozilla.org/show_bug.cgi?id=1113443\n var sdp = desc.sdp;\n var rewrite = false;\n for (var i = 0; i < session.media.length; i++) {\n var uLine = session.media[i];\n uLine.rtp.forEach(function(rtp) {\n if (rtp.codec === 'NULL')\n {\n rewrite = true;\n var offer = transform.parse(self.cache.offer);\n rtp.codec = offer.media[i].rtp[0].codec;\n }\n });\n }\n if (rewrite) {\n sdp = transform.write(session);\n }\n\n // Unified Plan SDP is our \"precious\". Cache it for later use in the Plan B\n // -> Unified Plan transformation.\n this.cache[desc.type] = sdp;\n\n //#region Convert from Unified Plan to Plan B.\n\n // We rebuild the session.media array.\n var media = session.media;\n session.media = [];\n\n // Associative array that maps channel types to channel objects for fast\n // access to channel objects by their type, e.g. type2bl['audio']->channel\n // obj.\n var type2bl = {};\n\n // Used to build the group:BUNDLE value after the channels construction\n // loop.\n var types = [];\n\n media.forEach(function(uLine) {\n // rtcp-mux is required in the Plan B SDP.\n if ((typeof uLine.rtcpMux !== 'string' ||\n uLine.rtcpMux !== 'rtcp-mux') &&\n uLine.direction !== 'inactive') {\n throw new Error('Cannot convert to Plan B because m-lines ' +\n 'without the rtcp-mux attribute were found.');\n }\n\n // If we don't have a channel for this uLine.type OR the selected is\n // inactive, then select this uLine as the channel basis.\n if (typeof type2bl[uLine.type] === 'undefined' ||\n type2bl[uLine.type].direction === 'inactive') {\n type2bl[uLine.type] = uLine;\n }\n\n if (uLine.protocol != type2bl[uLine.type].protocol) {\n throw new Error('Cannot convert to Plan B because m-lines ' +\n 'have different protocols and this library does not have ' +\n 'support for that');\n }\n\n if (uLine.payloads != type2bl[uLine.type].payloads) {\n throw new Error('Cannot convert to Plan B because m-lines ' +\n 'have different payloads and this library does not have ' +\n 'support for that');\n }\n\n });\n\n // Implode the Unified Plan m-lines/tracks into Plan B channels.\n media.forEach(function(uLine) {\n if (uLine.type === 'application') {\n session.media.push(uLine);\n types.push(uLine.mid);\n return;\n }\n\n // Add sources to the channel and handle a=msid.\n if (typeof uLine.sources === 'object') {\n Object.keys(uLine.sources).forEach(function(ssrc) {\n if (typeof type2bl[uLine.type].sources !== 'object')\n type2bl[uLine.type].sources = {};\n\n // Assign the sources to the channel.\n type2bl[uLine.type].sources[ssrc] =\n uLine.sources[ssrc];\n\n if (typeof uLine.msid !== 'undefined') {\n // In Plan B the msid is an SSRC attribute. Also, we don't\n // care about the obsolete label and mslabel attributes.\n //\n // Note that it is not guaranteed that the uLine will\n // have an msid. recvonly channels in particular don't have\n // one.\n type2bl[uLine.type].sources[ssrc].msid =\n uLine.msid;\n }\n // NOTE ssrcs in ssrc groups will share msids, as\n // draft-uberti-rtcweb-plan-00 mandates.\n });\n }\n\n // Add ssrc groups to the channel.\n if (typeof uLine.ssrcGroups !== 'undefined' &&\n Array.isArray(uLine.ssrcGroups)) {\n\n // Create the ssrcGroups array, if it's not defined.\n if (typeof type2bl[uLine.type].ssrcGroups === 'undefined' ||\n !Array.isArray(type2bl[uLine.type].ssrcGroups)) {\n type2bl[uLine.type].ssrcGroups = [];\n }\n\n type2bl[uLine.type].ssrcGroups =\n type2bl[uLine.type].ssrcGroups.concat(\n uLine.ssrcGroups);\n }\n\n if (type2bl[uLine.type] === uLine) {\n // Plan B mids are in ['audio', 'video', 'data']\n uLine.mid = uLine.type;\n\n // Plan B doesn't support/need the bundle-only attribute.\n delete uLine.bundleOnly;\n\n // In Plan B the msid is an SSRC attribute.\n delete uLine.msid;\n\n\t if (uLine.type == media[0].type) {\n\t types.unshift(uLine.type);\n\t // Add the channel to the new media array.\n\t session.media.unshift(uLine);\n\t } else {\n\t types.push(uLine.type);\n\t // Add the channel to the new media array.\n\t session.media.push(uLine);\n\t }\n }\n });\n\n if (typeof session.groups !== 'undefined') {\n // We regenerate the BUNDLE group with the new mids.\n session.groups.some(function(group) {\n\t if (group.type === 'BUNDLE') {\n\t group.mids = types.join(' ');\n\t return true;\n\t }\n });\n }\n\n // msid semantic\n session.msidSemantic = {\n semantic: 'WMS',\n token: '*'\n };\n\n var resStr = transform.write(session);\n\n return new RTCSessionDescription({\n type: desc.type,\n sdp: resStr\n });\n\n //#endregion\n};\n\n/* follow rules defined in RFC4145 */\nfunction addSetupAttr(uLine) {\n if (typeof uLine.setup === 'undefined') {\n return;\n }\n\n if (uLine.setup === \"active\") {\n uLine.setup = \"passive\";\n } else if (uLine.setup === \"passive\") {\n uLine.setup = \"active\";\n }\n}\n\n/**\n * This method transforms a Plan B SDP to an equivalent Unified Plan SDP. A\n * PeerConnection wrapper transforms the SDP to Unified Plan before passing it\n * to FF.\n *\n * @param desc\n * @returns {*}\n */\nInterop.prototype.toUnifiedPlan = function(desc) {\n var self = this;\n //#region Preliminary input validation.\n\n if (typeof desc !== 'object' || desc === null ||\n typeof desc.sdp !== 'string') {\n console.warn('An empty description was passed as an argument.');\n return desc;\n }\n\n var session = transform.parse(desc.sdp);\n\n // If the SDP contains no media, there's nothing to transform.\n if (typeof session.media === 'undefined' ||\n !Array.isArray(session.media) || session.media.length === 0) {\n console.warn('The description has no media.');\n return desc;\n }\n\n // Try some heuristics to \"make sure\" this is a Plan B SDP. Plan B SDP has\n // a video, an audio and a data \"channel\" at most.\n if (session.media.length > 3 || !session.media.every(function(m) {\n return ['video', 'audio', 'data'].indexOf(m.mid) !== -1;\n })) {\n console.warn('This description does not look like Plan B.');\n return desc;\n }\n\n // Make sure this Plan B SDP can be converted to a Unified Plan SDP.\n var mids = [];\n session.media.forEach(function(m) {\n mids.push(m.mid);\n });\n\n var hasBundle = false;\n if (typeof session.groups !== 'undefined' &&\n Array.isArray(session.groups)) {\n hasBundle = session.groups.every(function(g) {\n return g.type !== 'BUNDLE' ||\n arrayEquals.apply(g.mids.sort(), [mids.sort()]);\n });\n }\n\n if (!hasBundle) {\n var mustBeBundle = false;\n\n session.media.forEach(function(m) {\n if (m.direction !== 'inactive') {\n mustBeBundle = true;\n }\n });\n\n if (mustBeBundle) {\n throw new Error(\"Cannot convert to Unified Plan because m-lines that\" +\n \" are not bundled were found.\");\n }\n }\n\n //#endregion\n\n\n //#region Convert from Plan B to Unified Plan.\n\n // Unfortunately, a Plan B offer/answer doesn't have enough information to\n // rebuild an equivalent Unified Plan offer/answer.\n //\n // For example, if this is a local answer (in Unified Plan style) that we\n // convert to Plan B prior to handing it over to the application (the\n // PeerConnection wrapper called us, for instance, after a successful\n // createAnswer), we want to remember the m-line at which we've seen the\n // (local) SSRC. That's because when the application wants to do call the\n // SLD method, forcing us to do the inverse transformation (from Plan B to\n // Unified Plan), we need to know to which m-line to assign the (local)\n // SSRC. We also need to know all the other m-lines that the original\n // answer had and include them in the transformed answer as well.\n //\n // Another example is if this is a remote offer that we convert to Plan B\n // prior to giving it to the application, we want to remember the mid at\n // which we've seen the (remote) SSRC.\n //\n // In the iteration that follows, we use the cached Unified Plan (if it\n // exists) to assign mids to ssrcs.\n\n var type;\n if (desc.type === 'answer') {\n type = 'offer';\n } else if (desc.type === 'offer') {\n type = 'answer';\n } else {\n throw new Error(\"Type '\" + desc.type + \"' not supported.\");\n }\n\n var cached;\n if (typeof this.cache[type] !== 'undefined') {\n cached = transform.parse(this.cache[type]);\n }\n\n var recvonlySsrcs = {\n audio: {},\n video: {}\n };\n\n // A helper map that sends mids to m-line objects. We use it later to\n // rebuild the Unified Plan style session.media array.\n var mid2ul = {};\n var bIdx = 0;\n var uIdx = 0;\n\n var sources2ul = {};\n\n var candidates;\n var iceUfrag;\n var icePwd;\n var fingerprint;\n var payloads = {};\n var rtcpFb = {};\n var rtp = {};\n\n session.media.forEach(function(bLine) {\n if ((typeof bLine.rtcpMux !== 'string' ||\n bLine.rtcpMux !== 'rtcp-mux') &&\n bLine.direction !== 'inactive') {\n throw new Error(\"Cannot convert to Unified Plan because m-lines \" +\n \"without the rtcp-mux attribute were found.\");\n }\n\n if (bLine.type === 'application') {\n mid2ul[bLine.mid] = bLine;\n return;\n }\n\n // With rtcp-mux and bundle all the channels should have the same ICE\n // stuff.\n var sources = bLine.sources;\n var ssrcGroups = bLine.ssrcGroups;\n var port = bLine.port;\n\n /* Chrome adds different candidates even using bundle, so we concat the candidates list */\n if (typeof bLine.candidates != 'undefined') {\n if (typeof candidates != 'undefined') {\n candidates = candidates.concat(bLine.candidates);\n } else {\n candidates = bLine.candidates;\n }\n }\n\n if ((typeof iceUfrag != 'undefined') && (typeof bLine.iceUfrag != 'undefined') && (iceUfrag != bLine.iceUfrag)) {\n throw new Error(\"Only BUNDLE supported, iceUfrag must be the same for all m-lines.\\n\" +\n \"\\tLast iceUfrag: \" + iceUfrag + \"\\n\" +\n \"\\tNew iceUfrag: \" + bLine.iceUfrag\n );\n }\n\n if (typeof bLine.iceUfrag != 'undefined') {\n iceUfrag = bLine.iceUfrag;\n }\n\n if ((typeof icePwd != 'undefined') && (typeof bLine.icePwd != 'undefined') && (icePwd != bLine.icePwd)) {\n throw new Error(\"Only BUNDLE supported, icePwd must be the same for all m-lines.\\n\" +\n \"\\tLast icePwd: \" + icePwd + \"\\n\" +\n \"\\tNew icePwd: \" + bLine.icePwd\n );\n }\n\n if (typeof bLine.icePwd != 'undefined') {\n icePwd = bLine.icePwd;\n }\n\n if ((typeof fingerprint != 'undefined') && (typeof bLine.fingerprint != 'undefined') &&\n (fingerprint.type != bLine.fingerprint.type || fingerprint.hash != bLine.fingerprint.hash)) {\n throw new Error(\"Only BUNDLE supported, fingerprint must be the same for all m-lines.\\n\" +\n \"\\tLast fingerprint: \" + JSON.stringify(fingerprint) + \"\\n\" +\n \"\\tNew fingerprint: \" + JSON.stringify(bLine.fingerprint)\n );\n }\n\n if (typeof bLine.fingerprint != 'undefined') {\n fingerprint = bLine.fingerprint;\n }\n\n payloads[bLine.type] = bLine.payloads;\n rtcpFb[bLine.type] = bLine.rtcpFb;\n rtp[bLine.type] = bLine.rtp;\n\n // inverted ssrc group map\n var ssrc2group = {};\n if (typeof ssrcGroups !== 'undefined' && Array.isArray(ssrcGroups)) {\n ssrcGroups.forEach(function (ssrcGroup) {\n // XXX This might brake if an SSRC is in more than one group\n // for some reason.\n if (typeof ssrcGroup.ssrcs !== 'undefined' &&\n Array.isArray(ssrcGroup.ssrcs)) {\n ssrcGroup.ssrcs.forEach(function (ssrc) {\n if (typeof ssrc2group[ssrc] === 'undefined') {\n ssrc2group[ssrc] = [];\n }\n\n ssrc2group[ssrc].push(ssrcGroup);\n });\n }\n });\n }\n\n // ssrc to m-line index.\n var ssrc2ml = {};\n\n if (typeof sources === 'object') {\n\n // We'll use the \"bLine\" object as a prototype for each new \"mLine\"\n // that we create, but first we need to clean it up a bit.\n delete bLine.sources;\n delete bLine.ssrcGroups;\n delete bLine.candidates;\n delete bLine.iceUfrag;\n delete bLine.icePwd;\n delete bLine.fingerprint;\n delete bLine.port;\n delete bLine.mid;\n\n // Explode the Plan B channel sources with one m-line per source.\n Object.keys(sources).forEach(function(ssrc) {\n\n // The (unified) m-line for this SSRC. We either create it from\n // scratch or, if it's a grouped SSRC, we re-use a related\n // mline. In other words, if the source is grouped with another\n // source, put the two together in the same m-line.\n var uLine;\n\n // We assume here that we are the answerer in the O/A, so any\n // offers which we translate come from the remote side, while\n // answers are local. So the check below is to make that we\n // handle receive-only SSRCs in a special way only if they come\n // from the remote side.\n if (desc.type==='offer') {\n // We want to detect SSRCs which are used by a remote peer\n // in an m-line with direction=recvonly (i.e. they are\n // being used for RTCP only).\n // This information would have gotten lost if the remote\n // peer used Unified Plan and their local description was\n // translated to Plan B. So we use the lack of an MSID\n // attribute to deduce a \"receive only\" SSRC.\n if (!sources[ssrc].msid) {\n recvonlySsrcs[bLine.type][ssrc] = sources[ssrc];\n // Receive-only SSRCs must not create new m-lines. We\n // will assign them to an existing m-line later.\n return;\n }\n }\n\n if (typeof ssrc2group[ssrc] !== 'undefined' &&\n Array.isArray(ssrc2group[ssrc])) {\n ssrc2group[ssrc].some(function (ssrcGroup) {\n // ssrcGroup.ssrcs *is* an Array, no need to check\n // again here.\n return ssrcGroup.ssrcs.some(function (related) {\n if (typeof ssrc2ml[related] === 'object') {\n uLine = ssrc2ml[related];\n return true;\n }\n });\n });\n }\n\n if (typeof uLine === 'object') {\n // the m-line already exists. Just add the source.\n uLine.sources[ssrc] = sources[ssrc];\n delete sources[ssrc].msid;\n } else {\n // Use the \"bLine\" as a prototype for the \"uLine\".\n uLine = Object.create(bLine);\n ssrc2ml[ssrc] = uLine;\n\n if (typeof sources[ssrc].msid !== 'undefined') {\n // Assign the msid of the source to the m-line. Note\n // that it is not guaranteed that the source will have\n // msid. In particular \"recvonly\" sources don't have an\n // msid. Note that \"recvonly\" is a term only defined\n // for m-lines.\n uLine.msid = sources[ssrc].msid;\n delete sources[ssrc].msid;\n }\n\n // We assign one SSRC per media line.\n uLine.sources = {};\n uLine.sources[ssrc] = sources[ssrc];\n uLine.ssrcGroups = ssrc2group[ssrc];\n\n // Use the cached Unified Plan SDP (if it exists) to assign\n // SSRCs to mids.\n if (typeof cached !== 'undefined' &&\n typeof cached.media !== 'undefined' &&\n Array.isArray(cached.media)) {\n\n cached.media.forEach(function (m) {\n if (typeof m.sources === 'object') {\n Object.keys(m.sources).forEach(function (s) {\n if (s === ssrc) {\n uLine.mid = m.mid;\n }\n });\n }\n });\n }\n\n if (typeof uLine.mid === 'undefined') {\n\n // If this is an SSRC that we see for the first time\n // assign it a new mid. This is typically the case when\n // this method is called to transform a remote\n // description for the first time or when there is a\n // new SSRC in the remote description because a new\n // peer has joined the conference. Local SSRCs should\n // have already been added to the map in the toPlanB\n // method.\n //\n // Because FF generates answers in Unified Plan style,\n // we MUST already have a cached answer with all the\n // local SSRCs mapped to some m-line/mid.\n\n uLine.mid = [bLine.type, '-', ssrc].join('');\n }\n\n // Include the candidates in the 1st media line.\n uLine.candidates = candidates;\n uLine.iceUfrag = iceUfrag;\n uLine.icePwd = icePwd;\n uLine.fingerprint = fingerprint;\n uLine.port = port;\n\n mid2ul[uLine.mid] = uLine;\n sources2ul[uIdx] = uLine.sources;\n\n self.cache.mlU2BMap[uIdx] = bIdx;\n if (typeof self.cache.mlB2UMap[bIdx] === 'undefined') {\n self.cache.mlB2UMap[bIdx] = uIdx;\n }\n uIdx++;\n }\n });\n } else {\n var uLine = bLine;\n\n uLine.candidates = candidates;\n uLine.iceUfrag = iceUfrag;\n uLine.icePwd = icePwd;\n uLine.fingerprint = fingerprint;\n uLine.port = port;\n\n mid2ul[uLine.mid] = uLine;\n\n self.cache.mlU2BMap[uIdx] = bIdx;\n if (typeof self.cache.mlB2UMap[bIdx] === 'undefined') {\n self.cache.mlB2UMap[bIdx] = uIdx;\n }\n }\n\n bIdx++;\n });\n\n // Rebuild the media array in the right order and add the missing mLines\n // (missing from the Plan B SDP).\n session.media = [];\n mids = []; // reuse\n\n if (desc.type === 'answer') {\n\n // The media lines in the answer must match the media lines in the\n // offer. The order is important too. Here we assume that Firefox is\n // the answerer, so we merely have to use the reconstructed (unified)\n // answer to update the cached (unified) answer accordingly.\n //\n // In the general case, one would have to use the cached (unified)\n // offer to find the m-lines that are missing from the reconstructed\n // answer, potentially grabbing them from the cached (unified) answer.\n // One has to be careful with this approach because inactive m-lines do\n // not always have an mid, making it tricky (impossible?) to find where\n // exactly and which m-lines are missing from the reconstructed answer.\n\n for (var i = 0; i < cached.media.length; i++) {\n var uLine = cached.media[i];\n\n delete uLine.msid;\n delete uLine.sources;\n delete uLine.ssrcGroups;\n\n if (typeof sources2ul[i] === 'undefined') {\n if (!uLine.direction\n || uLine.direction === 'sendrecv')\n uLine.direction = 'recvonly';\n else if (uLine.direction === 'sendonly')\n uLine.direction = 'inactive';\n } else {\n if (!uLine.direction\n || uLine.direction === 'sendrecv')\n uLine.direction = 'sendrecv';\n else if (uLine.direction === 'recvonly')\n uLine.direction = 'sendonly';\n }\n\n uLine.sources = sources2ul[i];\n uLine.candidates = candidates;\n uLine.iceUfrag = iceUfrag;\n uLine.icePwd = icePwd;\n uLine.fingerprint = fingerprint;\n\n uLine.rtp = rtp[uLine.type];\n uLine.payloads = payloads[uLine.type];\n uLine.rtcpFb = rtcpFb[uLine.type];\n\n session.media.push(uLine);\n\n if (typeof uLine.mid === 'string') {\n // inactive lines don't/may not have an mid.\n mids.push(uLine.mid);\n }\n }\n } else {\n\n // SDP offer/answer (and the JSEP spec) forbids removing an m-section\n // under any circumstances. If we are no longer interested in sending a\n // track, we just remove the msid and ssrc attributes and set it to\n // either a=recvonly (as the reofferer, we must use recvonly if the\n // other side was previously sending on the m-section, but we can also\n // leave the possibility open if it wasn't previously in use), or\n // a=inactive.\n\n if (typeof cached !== 'undefined' &&\n typeof cached.media !== 'undefined' &&\n Array.isArray(cached.media)) {\n cached.media.forEach(function(uLine) {\n mids.push(uLine.mid);\n if (typeof mid2ul[uLine.mid] !== 'undefined') {\n session.media.push(mid2ul[uLine.mid]);\n } else {\n delete uLine.msid;\n delete uLine.sources;\n delete uLine.ssrcGroups;\n\n if (!uLine.direction\n || uLine.direction === 'sendrecv') {\n uLine.direction = 'sendonly';\n }\n if (!uLine.direction\n || uLine.direction === 'recvonly') {\n uLine.direction = 'inactive';\n }\n\n addSetupAttr (uLine);\n session.media.push(uLine);\n }\n });\n }\n\n // Add all the remaining (new) m-lines of the transformed SDP.\n Object.keys(mid2ul).forEach(function(mid) {\n if (mids.indexOf(mid) === -1) {\n mids.push(mid);\n if (mid2ul[mid].direction === 'recvonly') {\n // This is a remote recvonly channel. Add its SSRC to the\n // appropriate sendrecv or sendonly channel.\n // TODO(gp) what if we don't have sendrecv/sendonly\n // channel?\n\n var done = false;\n\n session.media.some(function (uLine) {\n if ((uLine.direction === 'sendrecv' ||\n uLine.direction === 'sendonly') &&\n uLine.type === mid2ul[mid].type) {\n // mid2ul[mid] shouldn't have any ssrc-groups\n Object.keys(mid2ul[mid].sources).forEach(\n function (ssrc) {\n uLine.sources[ssrc] =\n mid2ul[mid].sources[ssrc];\n });\n\n done = true;\n return true;\n }\n });\n\n if (!done) {\n session.media.push(mid2ul[mid]);\n }\n } else {\n session.media.push(mid2ul[mid]);\n }\n }\n });\n }\n\n // After we have constructed the Plan Unified m-lines we can figure out\n // where (in which m-line) to place the 'recvonly SSRCs'.\n // Note: we assume here that we are the answerer in the O/A, so any offers\n // which we translate come from the remote side, while answers are local\n // (and so our last local description is cached as an 'answer').\n [\"audio\", \"video\"].forEach(function (type) {\n if (!session || !session.media || !Array.isArray(session.media))\n return;\n\n var idx = null;\n if (Object.keys(recvonlySsrcs[type]).length > 0) {\n idx = self.getFirstSendingIndexFromAnswer(type);\n if (idx === null){\n // If this is the first offer we receive, we don't have a\n // cached answer. Assume that we will be sending media using\n // the first m-line for each media type.\n\n for (var i = 0; i < session.media.length; i++) {\n if (session.media[i].type === type) {\n idx = i;\n break;\n }\n }\n }\n }\n\n if (idx && session.media.length > idx) {\n var mLine = session.media[idx];\n Object.keys(recvonlySsrcs[type]).forEach(function(ssrc) {\n if (mLine.sources && mLine.sources[ssrc]) {\n console.warn(\"Replacing an existing SSRC.\");\n }\n if (!mLine.sources) {\n mLine.sources = {};\n }\n\n mLine.sources[ssrc] = recvonlySsrcs[type][ssrc];\n });\n }\n });\n\n if (typeof session.groups !== 'undefined') {\n // We regenerate the BUNDLE group (since we regenerated the mids)\n session.groups.some(function(group) {\n\t if (group.type === 'BUNDLE') {\n\t group.mids = mids.join(' ');\n\t return true;\n\t }\n });\n }\n\n // msid semantic\n session.msidSemantic = {\n semantic: 'WMS',\n token: '*'\n };\n\n var resStr = transform.write(session);\n\n // Cache the transformed SDP (Unified Plan) for later re-use in this\n // function.\n this.cache[desc.type] = resStr;\n\n return new RTCSessionDescription({\n type: desc.type,\n sdp: resStr\n });\n\n //#endregion\n};\n","/* Copyright @ 2015 Atlassian Pty Ltd\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nvar transform = require('sdp-transform');\n\nexports.write = function(session, opts) {\n\n if (typeof session !== 'undefined' &&\n typeof session.media !== 'undefined' &&\n Array.isArray(session.media)) {\n\n session.media.forEach(function (mLine) {\n // expand sources to ssrcs\n if (typeof mLine.sources !== 'undefined' &&\n Object.keys(mLine.sources).length !== 0) {\n mLine.ssrcs = [];\n Object.keys(mLine.sources).forEach(function (ssrc) {\n var source = mLine.sources[ssrc];\n Object.keys(source).forEach(function (attribute) {\n mLine.ssrcs.push({\n id: ssrc,\n attribute: attribute,\n value: source[attribute]\n });\n });\n });\n delete mLine.sources;\n }\n\n // join ssrcs in ssrc groups\n if (typeof mLine.ssrcGroups !== 'undefined' &&\n Array.isArray(mLine.ssrcGroups)) {\n mLine.ssrcGroups.forEach(function (ssrcGroup) {\n if (typeof ssrcGroup.ssrcs !== 'undefined' &&\n Array.isArray(ssrcGroup.ssrcs)) {\n ssrcGroup.ssrcs = ssrcGroup.ssrcs.join(' ');\n }\n });\n }\n });\n }\n\n // join group mids\n if (typeof session !== 'undefined' &&\n typeof session.groups !== 'undefined' && Array.isArray(session.groups)) {\n\n session.groups.forEach(function (g) {\n if (typeof g.mids !== 'undefined' && Array.isArray(g.mids)) {\n g.mids = g.mids.join(' ');\n }\n });\n }\n\n return transform.write(session, opts);\n};\n\nexports.parse = function(sdp) {\n var session = transform.parse(sdp);\n\n if (typeof session !== 'undefined' && typeof session.media !== 'undefined' &&\n Array.isArray(session.media)) {\n\n session.media.forEach(function (mLine) {\n // group sources attributes by ssrc\n if (typeof mLine.ssrcs !== 'undefined' && Array.isArray(mLine.ssrcs)) {\n mLine.sources = {};\n mLine.ssrcs.forEach(function (ssrc) {\n if (!mLine.sources[ssrc.id])\n mLine.sources[ssrc.id] = {};\n mLine.sources[ssrc.id][ssrc.attribute] = ssrc.value;\n });\n\n delete mLine.ssrcs;\n }\n\n // split ssrcs in ssrc groups\n if (typeof mLine.ssrcGroups !== 'undefined' &&\n Array.isArray(mLine.ssrcGroups)) {\n mLine.ssrcGroups.forEach(function (ssrcGroup) {\n if (typeof ssrcGroup.ssrcs === 'string') {\n ssrcGroup.ssrcs = ssrcGroup.ssrcs.split(' ');\n }\n });\n }\n });\n }\n // split group mids\n if (typeof session !== 'undefined' &&\n typeof session.groups !== 'undefined' && Array.isArray(session.groups)) {\n\n session.groups.forEach(function (g) {\n if (typeof g.mids === 'string') {\n g.mids = g.mids.split(' ');\n }\n });\n }\n\n return session;\n};\n\n"," /* eslint-env node */\n'use strict';\n\n// SDP helpers.\nvar SDPUtils = {};\n\n// Generate an alphanumeric identifier for cname or mids.\n// TODO: use UUIDs instead? https://gist.github.com/jed/982883\nSDPUtils.generateIdentifier = function() {\n return Math.random().toString(36).substr(2, 10);\n};\n\n// The RTCP CNAME used by all peerconnections from the same JS.\nSDPUtils.localCName = SDPUtils.generateIdentifier();\n\n// Splits SDP into lines, dealing with both CRLF and LF.\nSDPUtils.splitLines = function(blob) {\n return blob.trim().split('\\n').map(function(line) {\n return line.trim();\n });\n};\n// Splits SDP into sessionpart and mediasections. Ensures CRLF.\nSDPUtils.splitSections = function(blob) {\n var parts = blob.split('\\nm=');\n return parts.map(function(part, index) {\n return (index > 0 ? 'm=' + part : part).trim() + '\\r\\n';\n });\n};\n\n// Returns lines that start with a certain prefix.\nSDPUtils.matchPrefix = function(blob, prefix) {\n return SDPUtils.splitLines(blob).filter(function(line) {\n return line.indexOf(prefix) === 0;\n });\n};\n\n// Parses an ICE candidate line. Sample input:\n// candidate:702786350 2 udp 41819902 8.8.8.8 60769 typ relay raddr 8.8.8.8\n// rport 55996\"\nSDPUtils.parseCandidate = function(line) {\n var parts;\n // Parse both variants.\n if (line.indexOf('a=candidate:') === 0) {\n parts = line.substring(12).split(' ');\n } else {\n parts = line.substring(10).split(' ');\n }\n\n var candidate = {\n foundation: parts[0],\n component: parseInt(parts[1], 10),\n protocol: parts[2].toLowerCase(),\n priority: parseInt(parts[3], 10),\n ip: parts[4],\n port: parseInt(parts[5], 10),\n // skip parts[6] == 'typ'\n type: parts[7]\n };\n\n for (var i = 8; i < parts.length; i += 2) {\n switch (parts[i]) {\n case 'raddr':\n candidate.relatedAddress = parts[i + 1];\n break;\n case 'rport':\n candidate.relatedPort = parseInt(parts[i + 1], 10);\n break;\n case 'tcptype':\n candidate.tcpType = parts[i + 1];\n break;\n case 'ufrag':\n candidate.ufrag = parts[i + 1]; // for backward compability.\n candidate.usernameFragment = parts[i + 1];\n break;\n default: // extension handling, in particular ufrag\n candidate[parts[i]] = parts[i + 1];\n break;\n }\n }\n return candidate;\n};\n\n// Translates a candidate object into SDP candidate attribute.\nSDPUtils.writeCandidate = function(candidate) {\n var sdp = [];\n sdp.push(candidate.foundation);\n sdp.push(candidate.component);\n sdp.push(candidate.protocol.toUpperCase());\n sdp.push(candidate.priority);\n sdp.push(candidate.ip);\n sdp.push(candidate.port);\n\n var type = candidate.type;\n sdp.push('typ');\n sdp.push(type);\n if (type !== 'host' && candidate.relatedAddress &&\n candidate.relatedPort) {\n sdp.push('raddr');\n sdp.push(candidate.relatedAddress); // was: relAddr\n sdp.push('rport');\n sdp.push(candidate.relatedPort); // was: relPort\n }\n if (candidate.tcpType && candidate.protocol.toLowerCase() === 'tcp') {\n sdp.push('tcptype');\n sdp.push(candidate.tcpType);\n }\n if (candidate.ufrag) {\n sdp.push('ufrag');\n sdp.push(candidate.ufrag);\n }\n return 'candidate:' + sdp.join(' ');\n};\n\n// Parses an ice-options line, returns an array of option tags.\n// a=ice-options:foo bar\nSDPUtils.parseIceOptions = function(line) {\n return line.substr(14).split(' ');\n}\n\n// Parses an rtpmap line, returns RTCRtpCoddecParameters. Sample input:\n// a=rtpmap:111 opus/48000/2\nSDPUtils.parseRtpMap = function(line) {\n var parts = line.substr(9).split(' ');\n var parsed = {\n payloadType: parseInt(parts.shift(), 10) // was: id\n };\n\n parts = parts[0].split('/');\n\n parsed.name = parts[0];\n parsed.clockRate = parseInt(parts[1], 10); // was: clockrate\n // was: channels\n parsed.numChannels = parts.length === 3 ? parseInt(parts[2], 10) : 1;\n return parsed;\n};\n\n// Generate an a=rtpmap line from RTCRtpCodecCapability or\n// RTCRtpCodecParameters.\nSDPUtils.writeRtpMap = function(codec) {\n var pt = codec.payloadType;\n if (codec.preferredPayloadType !== undefined) {\n pt = codec.preferredPayloadType;\n }\n return 'a=rtpmap:' + pt + ' ' + codec.name + '/' + codec.clockRate +\n (codec.numChannels !== 1 ? '/' + codec.numChannels : '') + '\\r\\n';\n};\n\n// Parses an a=extmap line (headerextension from RFC 5285). Sample input:\n// a=extmap:2 urn:ietf:params:rtp-hdrext:toffset\n// a=extmap:2/sendonly urn:ietf:params:rtp-hdrext:toffset\nSDPUtils.parseExtmap = function(line) {\n var parts = line.substr(9).split(' ');\n return {\n id: parseInt(parts[0], 10),\n direction: parts[0].indexOf('/') > 0 ? parts[0].split('/')[1] : 'sendrecv',\n uri: parts[1]\n };\n};\n\n// Generates a=extmap line from RTCRtpHeaderExtensionParameters or\n// RTCRtpHeaderExtension.\nSDPUtils.writeExtmap = function(headerExtension) {\n return 'a=extmap:' + (headerExtension.id || headerExtension.preferredId) +\n (headerExtension.direction && headerExtension.direction !== 'sendrecv'\n ? '/' + headerExtension.direction\n : '') +\n ' ' + headerExtension.uri + '\\r\\n';\n};\n\n// Parses an ftmp line, returns dictionary. Sample input:\n// a=fmtp:96 vbr=on;cng=on\n// Also deals with vbr=on; cng=on\nSDPUtils.parseFmtp = function(line) {\n var parsed = {};\n var kv;\n var parts = line.substr(line.indexOf(' ') + 1).split(';');\n for (var j = 0; j < parts.length; j++) {\n kv = parts[j].trim().split('=');\n parsed[kv[0].trim()] = kv[1];\n }\n return parsed;\n};\n\n// Generates an a=ftmp line from RTCRtpCodecCapability or RTCRtpCodecParameters.\nSDPUtils.writeFmtp = function(codec) {\n var line = '';\n var pt = codec.payloadType;\n if (codec.preferredPayloadType !== undefined) {\n pt = codec.preferredPayloadType;\n }\n if (codec.parameters && Object.keys(codec.parameters).length) {\n var params = [];\n Object.keys(codec.parameters).forEach(function(param) {\n params.push(param + '=' + codec.parameters[param]);\n });\n line += 'a=fmtp:' + pt + ' ' + params.join(';') + '\\r\\n';\n }\n return line;\n};\n\n// Parses an rtcp-fb line, returns RTCPRtcpFeedback object. Sample input:\n// a=rtcp-fb:98 nack rpsi\nSDPUtils.parseRtcpFb = function(line) {\n var parts = line.substr(line.indexOf(' ') + 1).split(' ');\n return {\n type: parts.shift(),\n parameter: parts.join(' ')\n };\n};\n// Generate a=rtcp-fb lines from RTCRtpCodecCapability or RTCRtpCodecParameters.\nSDPUtils.writeRtcpFb = function(codec) {\n var lines = '';\n var pt = codec.payloadType;\n if (codec.preferredPayloadType !== undefined) {\n pt = codec.preferredPayloadType;\n }\n if (codec.rtcpFeedback && codec.rtcpFeedback.length) {\n // FIXME: special handling for trr-int?\n codec.rtcpFeedback.forEach(function(fb) {\n lines += 'a=rtcp-fb:' + pt + ' ' + fb.type +\n (fb.parameter && fb.parameter.length ? ' ' + fb.parameter : '') +\n '\\r\\n';\n });\n }\n return lines;\n};\n\n// Parses an RFC 5576 ssrc media attribute. Sample input:\n// a=ssrc:3735928559 cname:something\nSDPUtils.parseSsrcMedia = function(line) {\n var sp = line.indexOf(' ');\n var parts = {\n ssrc: parseInt(line.substr(7, sp - 7), 10)\n };\n var colon = line.indexOf(':', sp);\n if (colon > -1) {\n parts.attribute = line.substr(sp + 1, colon - sp - 1);\n parts.value = line.substr(colon + 1);\n } else {\n parts.attribute = line.substr(sp + 1);\n }\n return parts;\n};\n\n// Extracts the MID (RFC 5888) from a media section.\n// returns the MID or undefined if no mid line was found.\nSDPUtils.getMid = function(mediaSection) {\n var mid = SDPUtils.matchPrefix(mediaSection, 'a=mid:')[0];\n if (mid) {\n return mid.substr(6);\n }\n}\n\nSDPUtils.parseFingerprint = function(line) {\n var parts = line.substr(14).split(' ');\n return {\n algorithm: parts[0].toLowerCase(), // algorithm is case-sensitive in Edge.\n value: parts[1]\n };\n};\n\n// Extracts DTLS parameters from SDP media section or sessionpart.\n// FIXME: for consistency with other functions this should only\n// get the fingerprint line as input. See also getIceParameters.\nSDPUtils.getDtlsParameters = function(mediaSection, sessionpart) {\n var lines = SDPUtils.matchPrefix(mediaSection + sessionpart,\n 'a=fingerprint:');\n // Note: a=setup line is ignored since we use the 'auto' role.\n // Note2: 'algorithm' is not case sensitive except in Edge.\n return {\n role: 'auto',\n fingerprints: lines.map(SDPUtils.parseFingerprint)\n };\n};\n\n// Serializes DTLS parameters to SDP.\nSDPUtils.writeDtlsParameters = function(params, setupType) {\n var sdp = 'a=setup:' + setupType + '\\r\\n';\n params.fingerprints.forEach(function(fp) {\n sdp += 'a=fingerprint:' + fp.algorithm + ' ' + fp.value + '\\r\\n';\n });\n return sdp;\n};\n// Parses ICE information from SDP media section or sessionpart.\n// FIXME: for consistency with other functions this should only\n// get the ice-ufrag and ice-pwd lines as input.\nSDPUtils.getIceParameters = function(mediaSection, sessionpart) {\n var lines = SDPUtils.splitLines(mediaSection);\n // Search in session part, too.\n lines = lines.concat(SDPUtils.splitLines(sessionpart));\n var iceParameters = {\n usernameFragment: lines.filter(function(line) {\n return line.indexOf('a=ice-ufrag:') === 0;\n })[0].substr(12),\n password: lines.filter(function(line) {\n return line.indexOf('a=ice-pwd:') === 0;\n })[0].substr(10)\n };\n return iceParameters;\n};\n\n// Serializes ICE parameters to SDP.\nSDPUtils.writeIceParameters = function(params) {\n return 'a=ice-ufrag:' + params.usernameFragment + '\\r\\n' +\n 'a=ice-pwd:' + params.password + '\\r\\n';\n};\n\n// Parses the SDP media section and returns RTCRtpParameters.\nSDPUtils.parseRtpParameters = function(mediaSection) {\n var description = {\n codecs: [],\n headerExtensions: [],\n fecMechanisms: [],\n rtcp: []\n };\n var lines = SDPUtils.splitLines(mediaSection);\n var mline = lines[0].split(' ');\n for (var i = 3; i < mline.length; i++) { // find all codecs from mline[3..]\n var pt = mline[i];\n var rtpmapline = SDPUtils.matchPrefix(\n mediaSection, 'a=rtpmap:' + pt + ' ')[0];\n if (rtpmapline) {\n var codec = SDPUtils.parseRtpMap(rtpmapline);\n var fmtps = SDPUtils.matchPrefix(\n mediaSection, 'a=fmtp:' + pt + ' ');\n // Only the first a=fmtp: is considered.\n codec.parameters = fmtps.length ? SDPUtils.parseFmtp(fmtps[0]) : {};\n codec.rtcpFeedback = SDPUtils.matchPrefix(\n mediaSection, 'a=rtcp-fb:' + pt + ' ')\n .map(SDPUtils.parseRtcpFb);\n description.codecs.push(codec);\n // parse FEC mechanisms from rtpmap lines.\n switch (codec.name.toUpperCase()) {\n case 'RED':\n case 'ULPFEC':\n description.fecMechanisms.push(codec.name.toUpperCase());\n break;\n default: // only RED and ULPFEC are recognized as FEC mechanisms.\n break;\n }\n }\n }\n SDPUtils.matchPrefix(mediaSection, 'a=extmap:').forEach(function(line) {\n description.headerExtensions.push(SDPUtils.parseExtmap(line));\n });\n // FIXME: parse rtcp.\n return description;\n};\n\n// Generates parts of the SDP media section describing the capabilities /\n// parameters.\nSDPUtils.writeRtpDescription = function(kind, caps) {\n var sdp = '';\n\n // Build the mline.\n sdp += 'm=' + kind + ' ';\n sdp += caps.codecs.length > 0 ? '9' : '0'; // reject if no codecs.\n sdp += ' UDP/TLS/RTP/SAVPF ';\n sdp += caps.codecs.map(function(codec) {\n if (codec.preferredPayloadType !== undefined) {\n return codec.preferredPayloadType;\n }\n return codec.payloadType;\n }).join(' ') + '\\r\\n';\n\n sdp += 'c=IN IP4 0.0.0.0\\r\\n';\n sdp += 'a=rtcp:9 IN IP4 0.0.0.0\\r\\n';\n\n // Add a=rtpmap lines for each codec. Also fmtp and rtcp-fb.\n caps.codecs.forEach(function(codec) {\n sdp += SDPUtils.writeRtpMap(codec);\n sdp += SDPUtils.writeFmtp(codec);\n sdp += SDPUtils.writeRtcpFb(codec);\n });\n var maxptime = 0;\n caps.codecs.forEach(function(codec) {\n if (codec.maxptime > maxptime) {\n maxptime = codec.maxptime;\n }\n });\n if (maxptime > 0) {\n sdp += 'a=maxptime:' + maxptime + '\\r\\n';\n }\n sdp += 'a=rtcp-mux\\r\\n';\n\n caps.headerExtensions.forEach(function(extension) {\n sdp += SDPUtils.writeExtmap(extension);\n });\n // FIXME: write fecMechanisms.\n return sdp;\n};\n\n// Parses the SDP media section and returns an array of\n// RTCRtpEncodingParameters.\nSDPUtils.parseRtpEncodingParameters = function(mediaSection) {\n var encodingParameters = [];\n var description = SDPUtils.parseRtpParameters(mediaSection);\n var hasRed = description.fecMechanisms.indexOf('RED') !== -1;\n var hasUlpfec = description.fecMechanisms.indexOf('ULPFEC') !== -1;\n\n // filter a=ssrc:... cname:, ignore PlanB-msid\n var ssrcs = SDPUtils.matchPrefix(mediaSection, 'a=ssrc:')\n .map(function(line) {\n return SDPUtils.parseSsrcMedia(line);\n })\n .filter(function(parts) {\n return parts.attribute === 'cname';\n });\n var primarySsrc = ssrcs.length > 0 && ssrcs[0].ssrc;\n var secondarySsrc;\n\n var flows = SDPUtils.matchPrefix(mediaSection, 'a=ssrc-group:FID')\n .map(function(line) {\n var parts = line.split(' ');\n parts.shift();\n return parts.map(function(part) {\n return parseInt(part, 10);\n });\n });\n if (flows.length > 0 && flows[0].length > 1 && flows[0][0] === primarySsrc) {\n secondarySsrc = flows[0][1];\n }\n\n description.codecs.forEach(function(codec) {\n if (codec.name.toUpperCase() === 'RTX' && codec.parameters.apt) {\n var encParam = {\n ssrc: primarySsrc,\n codecPayloadType: parseInt(codec.parameters.apt, 10),\n rtx: {\n ssrc: secondarySsrc\n }\n };\n encodingParameters.push(encParam);\n if (hasRed) {\n encParam = JSON.parse(JSON.stringify(encParam));\n encParam.fec = {\n ssrc: secondarySsrc,\n mechanism: hasUlpfec ? 'red+ulpfec' : 'red'\n };\n encodingParameters.push(encParam);\n }\n }\n });\n if (encodingParameters.length === 0 && primarySsrc) {\n encodingParameters.push({\n ssrc: primarySsrc\n });\n }\n\n // we support both b=AS and b=TIAS but interpret AS as TIAS.\n var bandwidth = SDPUtils.matchPrefix(mediaSection, 'b=');\n if (bandwidth.length) {\n if (bandwidth[0].indexOf('b=TIAS:') === 0) {\n bandwidth = parseInt(bandwidth[0].substr(7), 10);\n } else if (bandwidth[0].indexOf('b=AS:') === 0) {\n // use formula from JSEP to convert b=AS to TIAS value.\n bandwidth = parseInt(bandwidth[0].substr(5), 10) * 1000 * 0.95\n - (50 * 40 * 8);\n } else {\n bandwidth = undefined;\n }\n encodingParameters.forEach(function(params) {\n params.maxBitrate = bandwidth;\n });\n }\n return encodingParameters;\n};\n\n// parses http://draft.ortc.org/#rtcrtcpparameters*\nSDPUtils.parseRtcpParameters = function(mediaSection) {\n var rtcpParameters = {};\n\n var cname;\n // Gets the first SSRC. Note that with RTX there might be multiple\n // SSRCs.\n var remoteSsrc = SDPUtils.matchPrefix(mediaSection, 'a=ssrc:')\n .map(function(line) {\n return SDPUtils.parseSsrcMedia(line);\n })\n .filter(function(obj) {\n return obj.attribute === 'cname';\n })[0];\n if (remoteSsrc) {\n rtcpParameters.cname = remoteSsrc.value;\n rtcpParameters.ssrc = remoteSsrc.ssrc;\n }\n\n // Edge uses the compound attribute instead of reducedSize\n // compound is !reducedSize\n var rsize = SDPUtils.matchPrefix(mediaSection, 'a=rtcp-rsize');\n rtcpParameters.reducedSize = rsize.length > 0;\n rtcpParameters.compound = rsize.length === 0;\n\n // parses the rtcp-mux attrіbute.\n // Note that Edge does not support unmuxed RTCP.\n var mux = SDPUtils.matchPrefix(mediaSection, 'a=rtcp-mux');\n rtcpParameters.mux = mux.length > 0;\n\n return rtcpParameters;\n};\n\n// parses either a=msid: or a=ssrc:... msid lines and returns\n// the id of the MediaStream and MediaStreamTrack.\nSDPUtils.parseMsid = function(mediaSection) {\n var parts;\n var spec = SDPUtils.matchPrefix(mediaSection, 'a=msid:');\n if (spec.length === 1) {\n parts = spec[0].substr(7).split(' ');\n return {stream: parts[0], track: parts[1]};\n }\n var planB = SDPUtils.matchPrefix(mediaSection, 'a=ssrc:')\n .map(function(line) {\n return SDPUtils.parseSsrcMedia(line);\n })\n .filter(function(parts) {\n return parts.attribute === 'msid';\n });\n if (planB.length > 0) {\n parts = planB[0].value.split(' ');\n return {stream: parts[0], track: parts[1]};\n }\n};\n\n// Generate a session ID for SDP.\n// https://tools.ietf.org/html/draft-ietf-rtcweb-jsep-20#section-5.2.1\n// recommends using a cryptographically random +ve 64-bit value\n// but right now this should be acceptable and within the right range\nSDPUtils.generateSessionId = function() {\n return Math.random().toString().substr(2, 21);\n};\n\n// Write boilder plate for start of SDP\n// sessId argument is optional - if not supplied it will\n// be generated randomly\n// sessVersion is optional and defaults to 2\nSDPUtils.writeSessionBoilerplate = function(sessId, sessVer) {\n var sessionId;\n var version = sessVer !== undefined ? sessVer : 2;\n if (sessId) {\n sessionId = sessId;\n } else {\n sessionId = SDPUtils.generateSessionId();\n }\n // FIXME: sess-id should be an NTP timestamp.\n return 'v=0\\r\\n' +\n 'o=thisisadapterortc ' + sessionId + ' ' + version + ' IN IP4 127.0.0.1\\r\\n' +\n 's=-\\r\\n' +\n 't=0 0\\r\\n';\n};\n\nSDPUtils.writeMediaSection = function(transceiver, caps, type, stream) {\n var sdp = SDPUtils.writeRtpDescription(transceiver.kind, caps);\n\n // Map ICE parameters (ufrag, pwd) to SDP.\n sdp += SDPUtils.writeIceParameters(\n transceiver.iceGatherer.getLocalParameters());\n\n // Map DTLS parameters to SDP.\n sdp += SDPUtils.writeDtlsParameters(\n transceiver.dtlsTransport.getLocalParameters(),\n type === 'offer' ? 'actpass' : 'active');\n\n sdp += 'a=mid:' + transceiver.mid + '\\r\\n';\n\n if (transceiver.direction) {\n sdp += 'a=' + transceiver.direction + '\\r\\n';\n } else if (transceiver.rtpSender && transceiver.rtpReceiver) {\n sdp += 'a=sendrecv\\r\\n';\n } else if (transceiver.rtpSender) {\n sdp += 'a=sendonly\\r\\n';\n } else if (transceiver.rtpReceiver) {\n sdp += 'a=recvonly\\r\\n';\n } else {\n sdp += 'a=inactive\\r\\n';\n }\n\n if (transceiver.rtpSender) {\n // spec.\n var msid = 'msid:' + stream.id + ' ' +\n transceiver.rtpSender.track.id + '\\r\\n';\n sdp += 'a=' + msid;\n\n // for Chrome.\n sdp += 'a=ssrc:' + transceiver.sendEncodingParameters[0].ssrc +\n ' ' + msid;\n if (transceiver.sendEncodingParameters[0].rtx) {\n sdp += 'a=ssrc:' + transceiver.sendEncodingParameters[0].rtx.ssrc +\n ' ' + msid;\n sdp += 'a=ssrc-group:FID ' +\n transceiver.sendEncodingParameters[0].ssrc + ' ' +\n transceiver.sendEncodingParameters[0].rtx.ssrc +\n '\\r\\n';\n }\n }\n // FIXME: this should be written by writeRtpDescription.\n sdp += 'a=ssrc:' + transceiver.sendEncodingParameters[0].ssrc +\n ' cname:' + SDPUtils.localCName + '\\r\\n';\n if (transceiver.rtpSender && transceiver.sendEncodingParameters[0].rtx) {\n sdp += 'a=ssrc:' + transceiver.sendEncodingParameters[0].rtx.ssrc +\n ' cname:' + SDPUtils.localCName + '\\r\\n';\n }\n return sdp;\n};\n\n// Gets the direction from the mediaSection or the sessionpart.\nSDPUtils.getDirection = function(mediaSection, sessionpart) {\n // Look for sendrecv, sendonly, recvonly, inactive, default to sendrecv.\n var lines = SDPUtils.splitLines(mediaSection);\n for (var i = 0; i < lines.length; i++) {\n switch (lines[i]) {\n case 'a=sendrecv':\n case 'a=sendonly':\n case 'a=recvonly':\n case 'a=inactive':\n return lines[i].substr(2);\n default:\n // FIXME: What should happen here?\n }\n }\n if (sessionpart) {\n return SDPUtils.getDirection(sessionpart);\n }\n return 'sendrecv';\n};\n\nSDPUtils.getKind = function(mediaSection) {\n var lines = SDPUtils.splitLines(mediaSection);\n var mline = lines[0].split(' ');\n return mline[0].substr(2);\n};\n\nSDPUtils.isRejected = function(mediaSection) {\n return mediaSection.split(' ', 2)[1] === '0';\n};\n\nSDPUtils.parseMLine = function(mediaSection) {\n var lines = SDPUtils.splitLines(mediaSection);\n var mline = lines[0].split(' ');\n return {\n kind: mline[0].substr(2),\n port: parseInt(mline[1], 10),\n protocol: mline[2],\n fmt: mline.slice(3).join(' ')\n };\n};\n\n// Expose public methods.\nif (typeof module === 'object') {\n module.exports = SDPUtils;\n}\n","/**\n * UAParser.js v0.7.14\n * Lightweight JavaScript-based User-Agent string parser\n * https://github.com/faisalman/ua-parser-js\n *\n * Copyright © 2012-2016 Faisal Salman \n * Dual licensed under GPLv2 & MIT\n */\n\n(function (window, undefined) {\n\n 'use strict';\n\n //////////////\n // Constants\n /////////////\n\n\n var LIBVERSION = '0.7.14',\n EMPTY = '',\n UNKNOWN = '?',\n FUNC_TYPE = 'function',\n UNDEF_TYPE = 'undefined',\n OBJ_TYPE = 'object',\n STR_TYPE = 'string',\n MAJOR = 'major', // deprecated\n MODEL = 'model',\n NAME = 'name',\n TYPE = 'type',\n VENDOR = 'vendor',\n VERSION = 'version',\n ARCHITECTURE= 'architecture',\n CONSOLE = 'console',\n MOBILE = 'mobile',\n TABLET = 'tablet',\n SMARTTV = 'smarttv',\n WEARABLE = 'wearable',\n EMBEDDED = 'embedded';\n\n\n ///////////\n // Helper\n //////////\n\n\n var util = {\n extend : function (regexes, extensions) {\n var margedRegexes = {};\n for (var i in regexes) {\n if (extensions[i] && extensions[i].length % 2 === 0) {\n margedRegexes[i] = extensions[i].concat(regexes[i]);\n } else {\n margedRegexes[i] = regexes[i];\n }\n }\n return margedRegexes;\n },\n has : function (str1, str2) {\n if (typeof str1 === \"string\") {\n return str2.toLowerCase().indexOf(str1.toLowerCase()) !== -1;\n } else {\n return false;\n }\n },\n lowerize : function (str) {\n return str.toLowerCase();\n },\n major : function (version) {\n return typeof(version) === STR_TYPE ? version.replace(/[^\\d\\.]/g,'').split(\".\")[0] : undefined;\n },\n trim : function (str) {\n return str.replace(/^[\\s\\uFEFF\\xA0]+|[\\s\\uFEFF\\xA0]+$/g, '');\n }\n };\n\n\n ///////////////\n // Map helper\n //////////////\n\n\n var mapper = {\n\n rgx : function (ua, arrays) {\n\n //var result = {},\n var i = 0, j, k, p, q, matches, match;//, args = arguments;\n\n /*// construct object barebones\n for (p = 0; p < args[1].length; p++) {\n q = args[1][p];\n result[typeof q === OBJ_TYPE ? q[0] : q] = undefined;\n }*/\n\n // loop through all regexes maps\n while (i < arrays.length && !matches) {\n\n var regex = arrays[i], // even sequence (0,2,4,..)\n props = arrays[i + 1]; // odd sequence (1,3,5,..)\n j = k = 0;\n\n // try matching uastring with regexes\n while (j < regex.length && !matches) {\n\n matches = regex[j++].exec(ua);\n\n if (!!matches) {\n for (p = 0; p < props.length; p++) {\n match = matches[++k];\n q = props[p];\n // check if given property is actually array\n if (typeof q === OBJ_TYPE && q.length > 0) {\n if (q.length == 2) {\n if (typeof q[1] == FUNC_TYPE) {\n // assign modified match\n this[q[0]] = q[1].call(this, match);\n } else {\n // assign given value, ignore regex match\n this[q[0]] = q[1];\n }\n } else if (q.length == 3) {\n // check whether function or regex\n if (typeof q[1] === FUNC_TYPE && !(q[1].exec && q[1].test)) {\n // call function (usually string mapper)\n this[q[0]] = match ? q[1].call(this, match, q[2]) : undefined;\n } else {\n // sanitize match using given regex\n this[q[0]] = match ? match.replace(q[1], q[2]) : undefined;\n }\n } else if (q.length == 4) {\n this[q[0]] = match ? q[3].call(this, match.replace(q[1], q[2])) : undefined;\n }\n } else {\n this[q] = match ? match : undefined;\n }\n }\n }\n }\n i += 2;\n }\n //console.log(this);\n //return this;\n },\n\n str : function (str, map) {\n\n for (var i in map) {\n // check if array\n if (typeof map[i] === OBJ_TYPE && map[i].length > 0) {\n for (var j = 0; j < map[i].length; j++) {\n if (util.has(map[i][j], str)) {\n return (i === UNKNOWN) ? undefined : i;\n }\n }\n } else if (util.has(map[i], str)) {\n return (i === UNKNOWN) ? undefined : i;\n }\n }\n return str;\n }\n };\n\n\n ///////////////\n // String map\n //////////////\n\n\n var maps = {\n\n browser : {\n oldsafari : {\n version : {\n '1.0' : '/8',\n '1.2' : '/1',\n '1.3' : '/3',\n '2.0' : '/412',\n '2.0.2' : '/416',\n '2.0.3' : '/417',\n '2.0.4' : '/419',\n '?' : '/'\n }\n }\n },\n\n device : {\n amazon : {\n model : {\n 'Fire Phone' : ['SD', 'KF']\n }\n },\n sprint : {\n model : {\n 'Evo Shift 4G' : '7373KT'\n },\n vendor : {\n 'HTC' : 'APA',\n 'Sprint' : 'Sprint'\n }\n }\n },\n\n os : {\n windows : {\n version : {\n 'ME' : '4.90',\n 'NT 3.11' : 'NT3.51',\n 'NT 4.0' : 'NT4.0',\n '2000' : 'NT 5.0',\n 'XP' : ['NT 5.1', 'NT 5.2'],\n 'Vista' : 'NT 6.0',\n '7' : 'NT 6.1',\n '8' : 'NT 6.2',\n '8.1' : 'NT 6.3',\n '10' : ['NT 6.4', 'NT 10.0'],\n 'RT' : 'ARM'\n }\n }\n }\n };\n\n\n //////////////\n // Regex map\n /////////////\n\n\n var regexes = {\n\n browser : [[\n\n // Presto based\n /(opera\\smini)\\/([\\w\\.-]+)/i, // Opera Mini\n /(opera\\s[mobiletab]+).+version\\/([\\w\\.-]+)/i, // Opera Mobi/Tablet\n /(opera).+version\\/([\\w\\.]+)/i, // Opera > 9.80\n /(opera)[\\/\\s]+([\\w\\.]+)/i // Opera < 9.80\n ], [NAME, VERSION], [\n\n /(opios)[\\/\\s]+([\\w\\.]+)/i // Opera mini on iphone >= 8.0\n ], [[NAME, 'Opera Mini'], VERSION], [\n\n /\\s(opr)\\/([\\w\\.]+)/i // Opera Webkit\n ], [[NAME, 'Opera'], VERSION], [\n\n // Mixed\n /(kindle)\\/([\\w\\.]+)/i, // Kindle\n /(lunascape|maxthon|netfront|jasmine|blazer)[\\/\\s]?([\\w\\.]+)*/i,\n // Lunascape/Maxthon/Netfront/Jasmine/Blazer\n\n // Trident based\n /(avant\\s|iemobile|slim|baidu)(?:browser)?[\\/\\s]?([\\w\\.]*)/i,\n // Avant/IEMobile/SlimBrowser/Baidu\n /(?:ms|\\()(ie)\\s([\\w\\.]+)/i, // Internet Explorer\n\n // Webkit/KHTML based\n /(rekonq)\\/([\\w\\.]+)*/i, // Rekonq\n /(chromium|flock|rockmelt|midori|epiphany|silk|skyfire|ovibrowser|bolt|iron|vivaldi|iridium|phantomjs|bowser)\\/([\\w\\.-]+)/i\n // Chromium/Flock/RockMelt/Midori/Epiphany/Silk/Skyfire/Bolt/Iron/Iridium/PhantomJS/Bowser\n ], [NAME, VERSION], [\n\n /(trident).+rv[:\\s]([\\w\\.]+).+like\\sgecko/i // IE11\n ], [[NAME, 'IE'], VERSION], [\n\n /(edge)\\/((\\d+)?[\\w\\.]+)/i // Microsoft Edge\n ], [NAME, VERSION], [\n\n /(yabrowser)\\/([\\w\\.]+)/i // Yandex\n ], [[NAME, 'Yandex'], VERSION], [\n\n /(puffin)\\/([\\w\\.]+)/i // Puffin\n ], [[NAME, 'Puffin'], VERSION], [\n\n /((?:[\\s\\/])uc?\\s?browser|(?:juc.+)ucweb)[\\/\\s]?([\\w\\.]+)/i\n // UCBrowser\n ], [[NAME, 'UCBrowser'], VERSION], [\n\n /(comodo_dragon)\\/([\\w\\.]+)/i // Comodo Dragon\n ], [[NAME, /_/g, ' '], VERSION], [\n\n /(micromessenger)\\/([\\w\\.]+)/i // WeChat\n ], [[NAME, 'WeChat'], VERSION], [\n\n /(QQ)\\/([\\d\\.]+)/i // QQ, aka ShouQ\n ], [NAME, VERSION], [\n\n /m?(qqbrowser)[\\/\\s]?([\\w\\.]+)/i // QQBrowser\n ], [NAME, VERSION], [\n\n /xiaomi\\/miuibrowser\\/([\\w\\.]+)/i // MIUI Browser\n ], [VERSION, [NAME, 'MIUI Browser']], [\n\n /;fbav\\/([\\w\\.]+);/i // Facebook App for iOS & Android\n ], [VERSION, [NAME, 'Facebook']], [\n\n /(headlesschrome) ([\\w\\.]+)/i // Chrome Headless\n ], [VERSION, [NAME, 'Chrome Headless']], [\n\n /\\swv\\).+(chrome)\\/([\\w\\.]+)/i // Chrome WebView\n ], [[NAME, /(.+)/, '$1 WebView'], VERSION], [\n\n /((?:oculus|samsung)browser)\\/([\\w\\.]+)/i\n ], [[NAME, /(.+(?:g|us))(.+)/, '$1 $2'], VERSION], [ // Oculus / Samsung Browser\n\n /android.+version\\/([\\w\\.]+)\\s+(?:mobile\\s?safari|safari)*/i // Android Browser\n ], [VERSION, [NAME, 'Android Browser']], [\n\n /(chrome|omniweb|arora|[tizenoka]{5}\\s?browser)\\/v?([\\w\\.]+)/i\n // Chrome/OmniWeb/Arora/Tizen/Nokia\n ], [NAME, VERSION], [\n\n /(dolfin)\\/([\\w\\.]+)/i // Dolphin\n ], [[NAME, 'Dolphin'], VERSION], [\n\n /((?:android.+)crmo|crios)\\/([\\w\\.]+)/i // Chrome for Android/iOS\n ], [[NAME, 'Chrome'], VERSION], [\n\n /(coast)\\/([\\w\\.]+)/i // Opera Coast\n ], [[NAME, 'Opera Coast'], VERSION], [\n\n /fxios\\/([\\w\\.-]+)/i // Firefox for iOS\n ], [VERSION, [NAME, 'Firefox']], [\n\n /version\\/([\\w\\.]+).+?mobile\\/\\w+\\s(safari)/i // Mobile Safari\n ], [VERSION, [NAME, 'Mobile Safari']], [\n\n /version\\/([\\w\\.]+).+?(mobile\\s?safari|safari)/i // Safari & Safari Mobile\n ], [VERSION, NAME], [\n\n /webkit.+?(mobile\\s?safari|safari)(\\/[\\w\\.]+)/i // Safari < 3.0\n ], [NAME, [VERSION, mapper.str, maps.browser.oldsafari.version]], [\n\n /(konqueror)\\/([\\w\\.]+)/i, // Konqueror\n /(webkit|khtml)\\/([\\w\\.]+)/i\n ], [NAME, VERSION], [\n\n // Gecko based\n /(navigator|netscape)\\/([\\w\\.-]+)/i // Netscape\n ], [[NAME, 'Netscape'], VERSION], [\n /(swiftfox)/i, // Swiftfox\n /(icedragon|iceweasel|camino|chimera|fennec|maemo\\sbrowser|minimo|conkeror)[\\/\\s]?([\\w\\.\\+]+)/i,\n // IceDragon/Iceweasel/Camino/Chimera/Fennec/Maemo/Minimo/Conkeror\n /(firefox|seamonkey|k-meleon|icecat|iceape|firebird|phoenix)\\/([\\w\\.-]+)/i,\n // Firefox/SeaMonkey/K-Meleon/IceCat/IceApe/Firebird/Phoenix\n /(mozilla)\\/([\\w\\.]+).+rv\\:.+gecko\\/\\d+/i, // Mozilla\n\n // Other\n /(polaris|lynx|dillo|icab|doris|amaya|w3m|netsurf|sleipnir)[\\/\\s]?([\\w\\.]+)/i,\n // Polaris/Lynx/Dillo/iCab/Doris/Amaya/w3m/NetSurf/Sleipnir\n /(links)\\s\\(([\\w\\.]+)/i, // Links\n /(gobrowser)\\/?([\\w\\.]+)*/i, // GoBrowser\n /(ice\\s?browser)\\/v?([\\w\\._]+)/i, // ICE Browser\n /(mosaic)[\\/\\s]([\\w\\.]+)/i // Mosaic\n ], [NAME, VERSION]\n\n /* /////////////////////\n // Media players BEGIN\n ////////////////////////\n\n , [\n\n /(apple(?:coremedia|))\\/((\\d+)[\\w\\._]+)/i, // Generic Apple CoreMedia\n /(coremedia) v((\\d+)[\\w\\._]+)/i\n ], [NAME, VERSION], [\n\n /(aqualung|lyssna|bsplayer)\\/((\\d+)?[\\w\\.-]+)/i // Aqualung/Lyssna/BSPlayer\n ], [NAME, VERSION], [\n\n /(ares|ossproxy)\\s((\\d+)[\\w\\.-]+)/i // Ares/OSSProxy\n ], [NAME, VERSION], [\n\n /(audacious|audimusicstream|amarok|bass|core|dalvik|gnomemplayer|music on console|nsplayer|psp-internetradioplayer|videos)\\/((\\d+)[\\w\\.-]+)/i,\n // Audacious/AudiMusicStream/Amarok/BASS/OpenCORE/Dalvik/GnomeMplayer/MoC\n // NSPlayer/PSP-InternetRadioPlayer/Videos\n /(clementine|music player daemon)\\s((\\d+)[\\w\\.-]+)/i, // Clementine/MPD\n /(lg player|nexplayer)\\s((\\d+)[\\d\\.]+)/i,\n /player\\/(nexplayer|lg player)\\s((\\d+)[\\w\\.-]+)/i // NexPlayer/LG Player\n ], [NAME, VERSION], [\n /(nexplayer)\\s((\\d+)[\\w\\.-]+)/i // Nexplayer\n ], [NAME, VERSION], [\n\n /(flrp)\\/((\\d+)[\\w\\.-]+)/i // Flip Player\n ], [[NAME, 'Flip Player'], VERSION], [\n\n /(fstream|nativehost|queryseekspider|ia-archiver|facebookexternalhit)/i\n // FStream/NativeHost/QuerySeekSpider/IA Archiver/facebookexternalhit\n ], [NAME], [\n\n /(gstreamer) souphttpsrc (?:\\([^\\)]+\\)){0,1} libsoup\\/((\\d+)[\\w\\.-]+)/i\n // Gstreamer\n ], [NAME, VERSION], [\n\n /(htc streaming player)\\s[\\w_]+\\s\\/\\s((\\d+)[\\d\\.]+)/i, // HTC Streaming Player\n /(java|python-urllib|python-requests|wget|libcurl)\\/((\\d+)[\\w\\.-_]+)/i,\n // Java/urllib/requests/wget/cURL\n /(lavf)((\\d+)[\\d\\.]+)/i // Lavf (FFMPEG)\n ], [NAME, VERSION], [\n\n /(htc_one_s)\\/((\\d+)[\\d\\.]+)/i // HTC One S\n ], [[NAME, /_/g, ' '], VERSION], [\n\n /(mplayer)(?:\\s|\\/)(?:(?:sherpya-){0,1}svn)(?:-|\\s)(r\\d+(?:-\\d+[\\w\\.-]+){0,1})/i\n // MPlayer SVN\n ], [NAME, VERSION], [\n\n /(mplayer)(?:\\s|\\/|[unkow-]+)((\\d+)[\\w\\.-]+)/i // MPlayer\n ], [NAME, VERSION], [\n\n /(mplayer)/i, // MPlayer (no other info)\n /(yourmuze)/i, // YourMuze\n /(media player classic|nero showtime)/i // Media Player Classic/Nero ShowTime\n ], [NAME], [\n\n /(nero (?:home|scout))\\/((\\d+)[\\w\\.-]+)/i // Nero Home/Nero Scout\n ], [NAME, VERSION], [\n\n /(nokia\\d+)\\/((\\d+)[\\w\\.-]+)/i // Nokia\n ], [NAME, VERSION], [\n\n /\\s(songbird)\\/((\\d+)[\\w\\.-]+)/i // Songbird/Philips-Songbird\n ], [NAME, VERSION], [\n\n /(winamp)3 version ((\\d+)[\\w\\.-]+)/i, // Winamp\n /(winamp)\\s((\\d+)[\\w\\.-]+)/i,\n /(winamp)mpeg\\/((\\d+)[\\w\\.-]+)/i\n ], [NAME, VERSION], [\n\n /(ocms-bot|tapinradio|tunein radio|unknown|winamp|inlight radio)/i // OCMS-bot/tap in radio/tunein/unknown/winamp (no other info)\n // inlight radio\n ], [NAME], [\n\n /(quicktime|rma|radioapp|radioclientapplication|soundtap|totem|stagefright|streamium)\\/((\\d+)[\\w\\.-]+)/i\n // QuickTime/RealMedia/RadioApp/RadioClientApplication/\n // SoundTap/Totem/Stagefright/Streamium\n ], [NAME, VERSION], [\n\n /(smp)((\\d+)[\\d\\.]+)/i // SMP\n ], [NAME, VERSION], [\n\n /(vlc) media player - version ((\\d+)[\\w\\.]+)/i, // VLC Videolan\n /(vlc)\\/((\\d+)[\\w\\.-]+)/i,\n /(xbmc|gvfs|xine|xmms|irapp)\\/((\\d+)[\\w\\.-]+)/i, // XBMC/gvfs/Xine/XMMS/irapp\n /(foobar2000)\\/((\\d+)[\\d\\.]+)/i, // Foobar2000\n /(itunes)\\/((\\d+)[\\d\\.]+)/i // iTunes\n ], [NAME, VERSION], [\n\n /(wmplayer)\\/((\\d+)[\\w\\.-]+)/i, // Windows Media Player\n /(windows-media-player)\\/((\\d+)[\\w\\.-]+)/i\n ], [[NAME, /-/g, ' '], VERSION], [\n\n /windows\\/((\\d+)[\\w\\.-]+) upnp\\/[\\d\\.]+ dlnadoc\\/[\\d\\.]+ (home media server)/i\n // Windows Media Server\n ], [VERSION, [NAME, 'Windows']], [\n\n /(com\\.riseupradioalarm)\\/((\\d+)[\\d\\.]*)/i // RiseUP Radio Alarm\n ], [NAME, VERSION], [\n\n /(rad.io)\\s((\\d+)[\\d\\.]+)/i, // Rad.io\n /(radio.(?:de|at|fr))\\s((\\d+)[\\d\\.]+)/i\n ], [[NAME, 'rad.io'], VERSION]\n\n //////////////////////\n // Media players END\n ////////////////////*/\n\n ],\n\n cpu : [[\n\n /(?:(amd|x(?:(?:86|64)[_-])?|wow|win)64)[;\\)]/i // AMD64\n ], [[ARCHITECTURE, 'amd64']], [\n\n /(ia32(?=;))/i // IA32 (quicktime)\n ], [[ARCHITECTURE, util.lowerize]], [\n\n /((?:i[346]|x)86)[;\\)]/i // IA32\n ], [[ARCHITECTURE, 'ia32']], [\n\n // PocketPC mistakenly identified as PowerPC\n /windows\\s(ce|mobile);\\sppc;/i\n ], [[ARCHITECTURE, 'arm']], [\n\n /((?:ppc|powerpc)(?:64)?)(?:\\smac|;|\\))/i // PowerPC\n ], [[ARCHITECTURE, /ower/, '', util.lowerize]], [\n\n /(sun4\\w)[;\\)]/i // SPARC\n ], [[ARCHITECTURE, 'sparc']], [\n\n /((?:avr32|ia64(?=;))|68k(?=\\))|arm(?:64|(?=v\\d+;))|(?=atmel\\s)avr|(?:irix|mips|sparc)(?:64)?(?=;)|pa-risc)/i\n // IA64, 68K, ARM/64, AVR/32, IRIX/64, MIPS/64, SPARC/64, PA-RISC\n ], [[ARCHITECTURE, util.lowerize]]\n ],\n\n device : [[\n\n /\\((ipad|playbook);[\\w\\s\\);-]+(rim|apple)/i // iPad/PlayBook\n ], [MODEL, VENDOR, [TYPE, TABLET]], [\n\n /applecoremedia\\/[\\w\\.]+ \\((ipad)/ // iPad\n ], [MODEL, [VENDOR, 'Apple'], [TYPE, TABLET]], [\n\n /(apple\\s{0,1}tv)/i // Apple TV\n ], [[MODEL, 'Apple TV'], [VENDOR, 'Apple']], [\n\n /(archos)\\s(gamepad2?)/i, // Archos\n /(hp).+(touchpad)/i, // HP TouchPad\n /(hp).+(tablet)/i, // HP Tablet\n /(kindle)\\/([\\w\\.]+)/i, // Kindle\n /\\s(nook)[\\w\\s]+build\\/(\\w+)/i, // Nook\n /(dell)\\s(strea[kpr\\s\\d]*[\\dko])/i // Dell Streak\n ], [VENDOR, MODEL, [TYPE, TABLET]], [\n\n /(kf[A-z]+)\\sbuild\\/[\\w\\.]+.*silk\\//i // Kindle Fire HD\n ], [MODEL, [VENDOR, 'Amazon'], [TYPE, TABLET]], [\n /(sd|kf)[0349hijorstuw]+\\sbuild\\/[\\w\\.]+.*silk\\//i // Fire Phone\n ], [[MODEL, mapper.str, maps.device.amazon.model], [VENDOR, 'Amazon'], [TYPE, MOBILE]], [\n\n /\\((ip[honed|\\s\\w*]+);.+(apple)/i // iPod/iPhone\n ], [MODEL, VENDOR, [TYPE, MOBILE]], [\n /\\((ip[honed|\\s\\w*]+);/i // iPod/iPhone\n ], [MODEL, [VENDOR, 'Apple'], [TYPE, MOBILE]], [\n\n /(blackberry)[\\s-]?(\\w+)/i, // BlackBerry\n /(blackberry|benq|palm(?=\\-)|sonyericsson|acer|asus|dell|meizu|motorola|polytron)[\\s_-]?([\\w-]+)*/i,\n // BenQ/Palm/Sony-Ericsson/Acer/Asus/Dell/Meizu/Motorola/Polytron\n /(hp)\\s([\\w\\s]+\\w)/i, // HP iPAQ\n /(asus)-?(\\w+)/i // Asus\n ], [VENDOR, MODEL, [TYPE, MOBILE]], [\n /\\(bb10;\\s(\\w+)/i // BlackBerry 10\n ], [MODEL, [VENDOR, 'BlackBerry'], [TYPE, MOBILE]], [\n // Asus Tablets\n /android.+(transfo[prime\\s]{4,10}\\s\\w+|eeepc|slider\\s\\w+|nexus 7|padfone)/i\n ], [MODEL, [VENDOR, 'Asus'], [TYPE, TABLET]], [\n\n /(sony)\\s(tablet\\s[ps])\\sbuild\\//i, // Sony\n /(sony)?(?:sgp.+)\\sbuild\\//i\n ], [[VENDOR, 'Sony'], [MODEL, 'Xperia Tablet'], [TYPE, TABLET]], [\n /android.+\\s([c-g]\\d{4}|so[-l]\\w+)\\sbuild\\//i\n ], [MODEL, [VENDOR, 'Sony'], [TYPE, MOBILE]], [\n\n /\\s(ouya)\\s/i, // Ouya\n /(nintendo)\\s([wids3u]+)/i // Nintendo\n ], [VENDOR, MODEL, [TYPE, CONSOLE]], [\n\n /android.+;\\s(shield)\\sbuild/i // Nvidia\n ], [MODEL, [VENDOR, 'Nvidia'], [TYPE, CONSOLE]], [\n\n /(playstation\\s[34portablevi]+)/i // Playstation\n ], [MODEL, [VENDOR, 'Sony'], [TYPE, CONSOLE]], [\n\n /(sprint\\s(\\w+))/i // Sprint Phones\n ], [[VENDOR, mapper.str, maps.device.sprint.vendor], [MODEL, mapper.str, maps.device.sprint.model], [TYPE, MOBILE]], [\n\n /(lenovo)\\s?(S(?:5000|6000)+(?:[-][\\w+]))/i // Lenovo tablets\n ], [VENDOR, MODEL, [TYPE, TABLET]], [\n\n /(htc)[;_\\s-]+([\\w\\s]+(?=\\))|\\w+)*/i, // HTC\n /(zte)-(\\w+)*/i, // ZTE\n /(alcatel|geeksphone|lenovo|nexian|panasonic|(?=;\\s)sony)[_\\s-]?([\\w-]+)*/i\n // Alcatel/GeeksPhone/Lenovo/Nexian/Panasonic/Sony\n ], [VENDOR, [MODEL, /_/g, ' '], [TYPE, MOBILE]], [\n\n /(nexus\\s9)/i // HTC Nexus 9\n ], [MODEL, [VENDOR, 'HTC'], [TYPE, TABLET]], [\n\n /d\\/huawei([\\w\\s-]+)[;\\)]/i,\n /(nexus\\s6p)/i // Huawei\n ], [MODEL, [VENDOR, 'Huawei'], [TYPE, MOBILE]], [\n\n /(microsoft);\\s(lumia[\\s\\w]+)/i // Microsoft Lumia\n ], [VENDOR, MODEL, [TYPE, MOBILE]], [\n\n /[\\s\\(;](xbox(?:\\sone)?)[\\s\\);]/i // Microsoft Xbox\n ], [MODEL, [VENDOR, 'Microsoft'], [TYPE, CONSOLE]], [\n /(kin\\.[onetw]{3})/i // Microsoft Kin\n ], [[MODEL, /\\./g, ' '], [VENDOR, 'Microsoft'], [TYPE, MOBILE]], [\n\n // Motorola\n /\\s(milestone|droid(?:[2-4x]|\\s(?:bionic|x2|pro|razr))?(:?\\s4g)?)[\\w\\s]+build\\//i,\n /mot[\\s-]?(\\w+)*/i,\n /(XT\\d{3,4}) build\\//i,\n /(nexus\\s6)/i\n ], [MODEL, [VENDOR, 'Motorola'], [TYPE, MOBILE]], [\n /android.+\\s(mz60\\d|xoom[\\s2]{0,2})\\sbuild\\//i\n ], [MODEL, [VENDOR, 'Motorola'], [TYPE, TABLET]], [\n\n /hbbtv\\/\\d+\\.\\d+\\.\\d+\\s+\\([\\w\\s]*;\\s*(\\w[^;]*);([^;]*)/i // HbbTV devices\n ], [[VENDOR, util.trim], [MODEL, util.trim], [TYPE, SMARTTV]], [\n\n /hbbtv.+maple;(\\d+)/i\n ], [[MODEL, /^/, 'SmartTV'], [VENDOR, 'Samsung'], [TYPE, SMARTTV]], [\n\n /\\(dtv[\\);].+(aquos)/i // Sharp\n ], [MODEL, [VENDOR, 'Sharp'], [TYPE, SMARTTV]], [\n\n /android.+((sch-i[89]0\\d|shw-m380s|gt-p\\d{4}|gt-n\\d+|sgh-t8[56]9|nexus 10))/i,\n /((SM-T\\w+))/i\n ], [[VENDOR, 'Samsung'], MODEL, [TYPE, TABLET]], [ // Samsung\n /smart-tv.+(samsung)/i\n ], [VENDOR, [TYPE, SMARTTV], MODEL], [\n /((s[cgp]h-\\w+|gt-\\w+|galaxy\\snexus|sm-\\w[\\w\\d]+))/i,\n /(sam[sung]*)[\\s-]*(\\w+-?[\\w-]*)*/i,\n /sec-((sgh\\w+))/i\n ], [[VENDOR, 'Samsung'], MODEL, [TYPE, MOBILE]], [\n\n /sie-(\\w+)*/i // Siemens\n ], [MODEL, [VENDOR, 'Siemens'], [TYPE, MOBILE]], [\n\n /(maemo|nokia).*(n900|lumia\\s\\d+)/i, // Nokia\n /(nokia)[\\s_-]?([\\w-]+)*/i\n ], [[VENDOR, 'Nokia'], MODEL, [TYPE, MOBILE]], [\n\n /android\\s3\\.[\\s\\w;-]{10}(a\\d{3})/i // Acer\n ], [MODEL, [VENDOR, 'Acer'], [TYPE, TABLET]], [\n\n /android.+([vl]k\\-?\\d{3})\\s+build/i // LG Tablet\n ], [MODEL, [VENDOR, 'LG'], [TYPE, TABLET]], [\n /android\\s3\\.[\\s\\w;-]{10}(lg?)-([06cv9]{3,4})/i // LG Tablet\n ], [[VENDOR, 'LG'], MODEL, [TYPE, TABLET]], [\n /(lg) netcast\\.tv/i // LG SmartTV\n ], [VENDOR, MODEL, [TYPE, SMARTTV]], [\n /(nexus\\s[45])/i, // LG\n /lg[e;\\s\\/-]+(\\w+)*/i,\n /android.+lg(\\-?[\\d\\w]+)\\s+build/i\n ], [MODEL, [VENDOR, 'LG'], [TYPE, MOBILE]], [\n\n /android.+(ideatab[a-z0-9\\-\\s]+)/i // Lenovo\n ], [MODEL, [VENDOR, 'Lenovo'], [TYPE, TABLET]], [\n\n /linux;.+((jolla));/i // Jolla\n ], [VENDOR, MODEL, [TYPE, MOBILE]], [\n\n /((pebble))app\\/[\\d\\.]+\\s/i // Pebble\n ], [VENDOR, MODEL, [TYPE, WEARABLE]], [\n\n /android.+;\\s(oppo)\\s?([\\w\\s]+)\\sbuild/i // OPPO\n ], [VENDOR, MODEL, [TYPE, MOBILE]], [\n\n /crkey/i // Google Chromecast\n ], [[MODEL, 'Chromecast'], [VENDOR, 'Google']], [\n\n /android.+;\\s(glass)\\s\\d/i // Google Glass\n ], [MODEL, [VENDOR, 'Google'], [TYPE, WEARABLE]], [\n\n /android.+;\\s(pixel c)\\s/i // Google Pixel C\n ], [MODEL, [VENDOR, 'Google'], [TYPE, TABLET]], [\n\n /android.+;\\s(pixel xl|pixel)\\s/i // Google Pixel\n ], [MODEL, [VENDOR, 'Google'], [TYPE, MOBILE]], [\n\n /android.+(\\w+)\\s+build\\/hm\\1/i, // Xiaomi Hongmi 'numeric' models\n /android.+(hm[\\s\\-_]*note?[\\s_]*(?:\\d\\w)?)\\s+build/i, // Xiaomi Hongmi\n /android.+(mi[\\s\\-_]*(?:one|one[\\s_]plus|note lte)?[\\s_]*(?:\\d\\w)?)\\s+build/i // Xiaomi Mi\n ], [[MODEL, /_/g, ' '], [VENDOR, 'Xiaomi'], [TYPE, MOBILE]], [\n\n /android.+;\\s(m[1-5]\\snote)\\sbuild/i // Meizu Tablet\n ], [MODEL, [VENDOR, 'Meizu'], [TYPE, TABLET]], [\n\n /android.+a000(1)\\s+build/i // OnePlus\n ], [MODEL, [VENDOR, 'OnePlus'], [TYPE, MOBILE]], [\n\n /android.+[;\\/]\\s*(RCT[\\d\\w]+)\\s+build/i // RCA Tablets\n ], [MODEL, [VENDOR, 'RCA'], [TYPE, TABLET]], [\n\n /android.+[;\\/]\\s*(Venue[\\d\\s]*)\\s+build/i // Dell Venue Tablets\n ], [MODEL, [VENDOR, 'Dell'], [TYPE, TABLET]], [\n\n /android.+[;\\/]\\s*(Q[T|M][\\d\\w]+)\\s+build/i // Verizon Tablet\n ], [MODEL, [VENDOR, 'Verizon'], [TYPE, TABLET]], [\n\n /android.+[;\\/]\\s+(Barnes[&\\s]+Noble\\s+|BN[RT])(V?.*)\\s+build/i // Barnes & Noble Tablet\n ], [[VENDOR, 'Barnes & Noble'], MODEL, [TYPE, TABLET]], [\n\n /android.+[;\\/]\\s+(TM\\d{3}.*\\b)\\s+build/i // Barnes & Noble Tablet\n ], [MODEL, [VENDOR, 'NuVision'], [TYPE, TABLET]], [\n\n /android.+[;\\/]\\s*(zte)?.+(k\\d{2})\\s+build/i // ZTE K Series Tablet\n ], [[VENDOR, 'ZTE'], MODEL, [TYPE, TABLET]], [\n\n /android.+[;\\/]\\s*(gen\\d{3})\\s+build.*49h/i // Swiss GEN Mobile\n ], [MODEL, [VENDOR, 'Swiss'], [TYPE, MOBILE]], [\n\n /android.+[;\\/]\\s*(zur\\d{3})\\s+build/i // Swiss ZUR Tablet\n ], [MODEL, [VENDOR, 'Swiss'], [TYPE, TABLET]], [\n\n /android.+[;\\/]\\s*((Zeki)?TB.*\\b)\\s+build/i // Zeki Tablets\n ], [MODEL, [VENDOR, 'Zeki'], [TYPE, TABLET]], [\n\n /(android).+[;\\/]\\s+([YR]\\d{2}x?.*)\\s+build/i,\n /android.+[;\\/]\\s+(Dragon[\\-\\s]+Touch\\s+|DT)(.+)\\s+build/i // Dragon Touch Tablet\n ], [[VENDOR, 'Dragon Touch'], MODEL, [TYPE, TABLET]], [\n\n /android.+[;\\/]\\s*(NS-?.+)\\s+build/i // Insignia Tablets\n ], [MODEL, [VENDOR, 'Insignia'], [TYPE, TABLET]], [\n\n /android.+[;\\/]\\s*((NX|Next)-?.+)\\s+build/i // NextBook Tablets\n ], [MODEL, [VENDOR, 'NextBook'], [TYPE, TABLET]], [\n\n /android.+[;\\/]\\s*(Xtreme\\_?)?(V(1[045]|2[015]|30|40|60|7[05]|90))\\s+build/i\n ], [[VENDOR, 'Voice'], MODEL, [TYPE, MOBILE]], [ // Voice Xtreme Phones\n\n /android.+[;\\/]\\s*(LVTEL\\-?)?(V1[12])\\s+build/i // LvTel Phones\n ], [[VENDOR, 'LvTel'], MODEL, [TYPE, MOBILE]], [\n\n /android.+[;\\/]\\s*(V(100MD|700NA|7011|917G).*\\b)\\s+build/i // Envizen Tablets\n ], [MODEL, [VENDOR, 'Envizen'], [TYPE, TABLET]], [\n\n /android.+[;\\/]\\s*(Le[\\s\\-]+Pan)[\\s\\-]+(.*\\b)\\s+build/i // Le Pan Tablets\n ], [VENDOR, MODEL, [TYPE, TABLET]], [\n\n /android.+[;\\/]\\s*(Trio[\\s\\-]*.*)\\s+build/i // MachSpeed Tablets\n ], [MODEL, [VENDOR, 'MachSpeed'], [TYPE, TABLET]], [\n\n /android.+[;\\/]\\s*(Trinity)[\\-\\s]*(T\\d{3})\\s+build/i // Trinity Tablets\n ], [VENDOR, MODEL, [TYPE, TABLET]], [\n\n /android.+[;\\/]\\s*TU_(1491)\\s+build/i // Rotor Tablets\n ], [MODEL, [VENDOR, 'Rotor'], [TYPE, TABLET]], [\n\n /android.+(KS(.+))\\s+build/i // Amazon Kindle Tablets\n ], [MODEL, [VENDOR, 'Amazon'], [TYPE, TABLET]], [\n\n /android.+(Gigaset)[\\s\\-]+(Q.+)\\s+build/i // Gigaset Tablets\n ], [VENDOR, MODEL, [TYPE, TABLET]], [\n\n /\\s(tablet|tab)[;\\/]/i, // Unidentifiable Tablet\n /\\s(mobile)(?:[;\\/]|\\ssafari)/i // Unidentifiable Mobile\n ], [[TYPE, util.lowerize], VENDOR, MODEL], [\n\n /(android.+)[;\\/].+build/i // Generic Android Device\n ], [MODEL, [VENDOR, 'Generic']]\n\n\n /*//////////////////////////\n // TODO: move to string map\n ////////////////////////////\n\n /(C6603)/i // Sony Xperia Z C6603\n ], [[MODEL, 'Xperia Z C6603'], [VENDOR, 'Sony'], [TYPE, MOBILE]], [\n /(C6903)/i // Sony Xperia Z 1\n ], [[MODEL, 'Xperia Z 1'], [VENDOR, 'Sony'], [TYPE, MOBILE]], [\n\n /(SM-G900[F|H])/i // Samsung Galaxy S5\n ], [[MODEL, 'Galaxy S5'], [VENDOR, 'Samsung'], [TYPE, MOBILE]], [\n /(SM-G7102)/i // Samsung Galaxy Grand 2\n ], [[MODEL, 'Galaxy Grand 2'], [VENDOR, 'Samsung'], [TYPE, MOBILE]], [\n /(SM-G530H)/i // Samsung Galaxy Grand Prime\n ], [[MODEL, 'Galaxy Grand Prime'], [VENDOR, 'Samsung'], [TYPE, MOBILE]], [\n /(SM-G313HZ)/i // Samsung Galaxy V\n ], [[MODEL, 'Galaxy V'], [VENDOR, 'Samsung'], [TYPE, MOBILE]], [\n /(SM-T805)/i // Samsung Galaxy Tab S 10.5\n ], [[MODEL, 'Galaxy Tab S 10.5'], [VENDOR, 'Samsung'], [TYPE, TABLET]], [\n /(SM-G800F)/i // Samsung Galaxy S5 Mini\n ], [[MODEL, 'Galaxy S5 Mini'], [VENDOR, 'Samsung'], [TYPE, MOBILE]], [\n /(SM-T311)/i // Samsung Galaxy Tab 3 8.0\n ], [[MODEL, 'Galaxy Tab 3 8.0'], [VENDOR, 'Samsung'], [TYPE, TABLET]], [\n\n /(T3C)/i // Advan Vandroid T3C\n ], [MODEL, [VENDOR, 'Advan'], [TYPE, TABLET]], [\n /(ADVAN T1J\\+)/i // Advan Vandroid T1J+\n ], [[MODEL, 'Vandroid T1J+'], [VENDOR, 'Advan'], [TYPE, TABLET]], [\n /(ADVAN S4A)/i // Advan Vandroid S4A\n ], [[MODEL, 'Vandroid S4A'], [VENDOR, 'Advan'], [TYPE, MOBILE]], [\n\n /(V972M)/i // ZTE V972M\n ], [MODEL, [VENDOR, 'ZTE'], [TYPE, MOBILE]], [\n\n /(i-mobile)\\s(IQ\\s[\\d\\.]+)/i // i-mobile IQ\n ], [VENDOR, MODEL, [TYPE, MOBILE]], [\n /(IQ6.3)/i // i-mobile IQ IQ 6.3\n ], [[MODEL, 'IQ 6.3'], [VENDOR, 'i-mobile'], [TYPE, MOBILE]], [\n /(i-mobile)\\s(i-style\\s[\\d\\.]+)/i // i-mobile i-STYLE\n ], [VENDOR, MODEL, [TYPE, MOBILE]], [\n /(i-STYLE2.1)/i // i-mobile i-STYLE 2.1\n ], [[MODEL, 'i-STYLE 2.1'], [VENDOR, 'i-mobile'], [TYPE, MOBILE]], [\n\n /(mobiistar touch LAI 512)/i // mobiistar touch LAI 512\n ], [[MODEL, 'Touch LAI 512'], [VENDOR, 'mobiistar'], [TYPE, MOBILE]], [\n\n /////////////\n // END TODO\n ///////////*/\n\n ],\n\n engine : [[\n\n /windows.+\\sedge\\/([\\w\\.]+)/i // EdgeHTML\n ], [VERSION, [NAME, 'EdgeHTML']], [\n\n /(presto)\\/([\\w\\.]+)/i, // Presto\n /(webkit|trident|netfront|netsurf|amaya|lynx|w3m)\\/([\\w\\.]+)/i, // WebKit/Trident/NetFront/NetSurf/Amaya/Lynx/w3m\n /(khtml|tasman|links)[\\/\\s]\\(?([\\w\\.]+)/i, // KHTML/Tasman/Links\n /(icab)[\\/\\s]([23]\\.[\\d\\.]+)/i // iCab\n ], [NAME, VERSION], [\n\n /rv\\:([\\w\\.]+).*(gecko)/i // Gecko\n ], [VERSION, NAME]\n ],\n\n os : [[\n\n // Windows based\n /microsoft\\s(windows)\\s(vista|xp)/i // Windows (iTunes)\n ], [NAME, VERSION], [\n /(windows)\\snt\\s6\\.2;\\s(arm)/i, // Windows RT\n /(windows\\sphone(?:\\sos)*)[\\s\\/]?([\\d\\.\\s]+\\w)*/i, // Windows Phone\n /(windows\\smobile|windows)[\\s\\/]?([ntce\\d\\.\\s]+\\w)/i\n ], [NAME, [VERSION, mapper.str, maps.os.windows.version]], [\n /(win(?=3|9|n)|win\\s9x\\s)([nt\\d\\.]+)/i\n ], [[NAME, 'Windows'], [VERSION, mapper.str, maps.os.windows.version]], [\n\n // Mobile/Embedded OS\n /\\((bb)(10);/i // BlackBerry 10\n ], [[NAME, 'BlackBerry'], VERSION], [\n /(blackberry)\\w*\\/?([\\w\\.]+)*/i, // Blackberry\n /(tizen)[\\/\\s]([\\w\\.]+)/i, // Tizen\n /(android|webos|palm\\sos|qnx|bada|rim\\stablet\\sos|meego|contiki)[\\/\\s-]?([\\w\\.]+)*/i,\n // Android/WebOS/Palm/QNX/Bada/RIM/MeeGo/Contiki\n /linux;.+(sailfish);/i // Sailfish OS\n ], [NAME, VERSION], [\n /(symbian\\s?os|symbos|s60(?=;))[\\/\\s-]?([\\w\\.]+)*/i // Symbian\n ], [[NAME, 'Symbian'], VERSION], [\n /\\((series40);/i // Series 40\n ], [NAME], [\n /mozilla.+\\(mobile;.+gecko.+firefox/i // Firefox OS\n ], [[NAME, 'Firefox OS'], VERSION], [\n\n // Console\n /(nintendo|playstation)\\s([wids34portablevu]+)/i, // Nintendo/Playstation\n\n // GNU/Linux based\n /(mint)[\\/\\s\\(]?(\\w+)*/i, // Mint\n /(mageia|vectorlinux)[;\\s]/i, // Mageia/VectorLinux\n /(joli|[kxln]?ubuntu|debian|[open]*suse|gentoo|(?=\\s)arch|slackware|fedora|mandriva|centos|pclinuxos|redhat|zenwalk|linpus)[\\/\\s-]?(?!chrom)([\\w\\.-]+)*/i,\n // Joli/Ubuntu/Debian/SUSE/Gentoo/Arch/Slackware\n // Fedora/Mandriva/CentOS/PCLinuxOS/RedHat/Zenwalk/Linpus\n /(hurd|linux)\\s?([\\w\\.]+)*/i, // Hurd/Linux\n /(gnu)\\s?([\\w\\.]+)*/i // GNU\n ], [NAME, VERSION], [\n\n /(cros)\\s[\\w]+\\s([\\w\\.]+\\w)/i // Chromium OS\n ], [[NAME, 'Chromium OS'], VERSION],[\n\n // Solaris\n /(sunos)\\s?([\\w\\.]+\\d)*/i // Solaris\n ], [[NAME, 'Solaris'], VERSION], [\n\n // BSD based\n /\\s([frentopc-]{0,4}bsd|dragonfly)\\s?([\\w\\.]+)*/i // FreeBSD/NetBSD/OpenBSD/PC-BSD/DragonFly\n ], [NAME, VERSION],[\n\n /(haiku)\\s(\\w+)/i // Haiku\n ], [NAME, VERSION],[\n\n /cfnetwork\\/.+darwin/i,\n /ip[honead]+(?:.*os\\s([\\w]+)*\\slike\\smac|;\\sopera)/i // iOS\n ], [[VERSION, /_/g, '.'], [NAME, 'iOS']], [\n\n /(mac\\sos\\sx)\\s?([\\w\\s\\.]+\\w)*/i,\n /(macintosh|mac(?=_powerpc)\\s)/i // Mac OS\n ], [[NAME, 'Mac OS'], [VERSION, /_/g, '.']], [\n\n // Other\n /((?:open)?solaris)[\\/\\s-]?([\\w\\.]+)*/i, // Solaris\n /(aix)\\s((\\d)(?=\\.|\\)|\\s)[\\w\\.]*)*/i, // AIX\n /(plan\\s9|minix|beos|os\\/2|amigaos|morphos|risc\\sos|openvms)/i,\n // Plan9/Minix/BeOS/OS2/AmigaOS/MorphOS/RISCOS/OpenVMS\n /(unix)\\s?([\\w\\.]+)*/i // UNIX\n ], [NAME, VERSION]\n ]\n };\n\n\n /////////////////\n // Constructor\n ////////////////\n\n var Browser = function (name, version) {\n this[NAME] = name;\n this[VERSION] = version;\n };\n var CPU = function (arch) {\n this[ARCHITECTURE] = arch;\n };\n var Device = function (vendor, model, type) {\n this[VENDOR] = vendor;\n this[MODEL] = model;\n this[TYPE] = type;\n };\n var Engine = Browser;\n var OS = Browser;\n\n var UAParser = function (uastring, extensions) {\n\n if (typeof uastring === 'object') {\n extensions = uastring;\n uastring = undefined;\n }\n\n if (!(this instanceof UAParser)) {\n return new UAParser(uastring, extensions).getResult();\n }\n\n var ua = uastring || ((window && window.navigator && window.navigator.userAgent) ? window.navigator.userAgent : EMPTY);\n var rgxmap = extensions ? util.extend(regexes, extensions) : regexes;\n var browser = new Browser();\n var cpu = new CPU();\n var device = new Device();\n var engine = new Engine();\n var os = new OS();\n\n this.getBrowser = function () {\n mapper.rgx.call(browser, ua, rgxmap.browser);\n browser.major = util.major(browser.version); // deprecated\n return browser;\n };\n this.getCPU = function () {\n mapper.rgx.call(cpu, ua, rgxmap.cpu);\n return cpu;\n };\n this.getDevice = function () {\n mapper.rgx.call(device, ua, rgxmap.device);\n return device;\n };\n this.getEngine = function () {\n mapper.rgx.call(engine, ua, rgxmap.engine);\n return engine;\n };\n this.getOS = function () {\n mapper.rgx.call(os, ua, rgxmap.os);\n return os;\n };\n this.getResult = function () {\n return {\n ua : this.getUA(),\n browser : this.getBrowser(),\n engine : this.getEngine(),\n os : this.getOS(),\n device : this.getDevice(),\n cpu : this.getCPU()\n };\n };\n this.getUA = function () {\n return ua;\n };\n this.setUA = function (uastring) {\n ua = uastring;\n browser = new Browser();\n cpu = new CPU();\n device = new Device();\n engine = new Engine();\n os = new OS();\n return this;\n };\n return this;\n };\n\n UAParser.VERSION = LIBVERSION;\n UAParser.BROWSER = {\n NAME : NAME,\n MAJOR : MAJOR, // deprecated\n VERSION : VERSION\n };\n UAParser.CPU = {\n ARCHITECTURE : ARCHITECTURE\n };\n UAParser.DEVICE = {\n MODEL : MODEL,\n VENDOR : VENDOR,\n TYPE : TYPE,\n CONSOLE : CONSOLE,\n MOBILE : MOBILE,\n SMARTTV : SMARTTV,\n TABLET : TABLET,\n WEARABLE: WEARABLE,\n EMBEDDED: EMBEDDED\n };\n UAParser.ENGINE = {\n NAME : NAME,\n VERSION : VERSION\n };\n UAParser.OS = {\n NAME : NAME,\n VERSION : VERSION\n };\n //UAParser.Utils = util;\n\n ///////////\n // Export\n //////////\n\n\n // check js environment\n if (typeof(exports) !== UNDEF_TYPE) {\n // nodejs env\n if (typeof module !== UNDEF_TYPE && module.exports) {\n exports = module.exports = UAParser;\n }\n exports.UAParser = UAParser;\n } else {\n // requirejs env (optional)\n if (typeof(define) === FUNC_TYPE && define.amd) {\n define(function () {\n return UAParser;\n });\n } else if (window) {\n // browser env\n window.UAParser = UAParser;\n }\n }\n\n // jQuery/Zepto specific (optional)\n // Note:\n // In AMD env the global scope should be kept clean, but jQuery is an exception.\n // jQuery always exports to global scope, unless jQuery.noConflict(true) is used,\n // and we should catch that.\n var $ = window && (window.jQuery || window.Zepto);\n if (typeof $ !== UNDEF_TYPE) {\n var parser = new UAParser();\n $.ua = parser.getResult();\n $.ua.get = function () {\n return parser.getUA();\n };\n $.ua.set = function (uastring) {\n parser.setUA(uastring);\n var result = parser.getResult();\n for (var prop in result) {\n $.ua[prop] = result[prop];\n }\n };\n }\n\n})(typeof window === 'object' ? window : this);\n","\nvar rng;\n\nvar crypto = global.crypto || global.msCrypto; // for IE 11\nif (crypto && crypto.getRandomValues) {\n // WHATWG crypto-based RNG - http://wiki.whatwg.org/wiki/Crypto\n // Moderately fast, high quality\n var _rnds8 = new Uint8Array(16);\n rng = function whatwgRNG() {\n crypto.getRandomValues(_rnds8);\n return _rnds8;\n };\n}\n\nif (!rng) {\n // Math.random()-based (RNG)\n //\n // If all else fails, use Math.random(). It's fast, but is of unspecified\n // quality.\n var _rnds = new Array(16);\n rng = function() {\n for (var i = 0, r; i < 16; i++) {\n if ((i & 0x03) === 0) r = Math.random() * 0x100000000;\n _rnds[i] = r >>> ((i & 0x03) << 3) & 0xff;\n }\n\n return _rnds;\n };\n}\n\nmodule.exports = rng;\n\n","// uuid.js\n//\n// Copyright (c) 2010-2012 Robert Kieffer\n// MIT License - http://opensource.org/licenses/mit-license.php\n\n// Unique ID creation requires a high quality random # generator. We feature\n// detect to determine the best RNG source, normalizing to a function that\n// returns 128-bits of randomness, since that's what's usually required\nvar _rng = require('./rng');\n\n// Maps for number <-> hex string conversion\nvar _byteToHex = [];\nvar _hexToByte = {};\nfor (var i = 0; i < 256; i++) {\n _byteToHex[i] = (i + 0x100).toString(16).substr(1);\n _hexToByte[_byteToHex[i]] = i;\n}\n\n// **`parse()` - Parse a UUID into it's component bytes**\nfunction parse(s, buf, offset) {\n var i = (buf && offset) || 0, ii = 0;\n\n buf = buf || [];\n s.toLowerCase().replace(/[0-9a-f]{2}/g, function(oct) {\n if (ii < 16) { // Don't overflow!\n buf[i + ii++] = _hexToByte[oct];\n }\n });\n\n // Zero out remaining bytes if string was short\n while (ii < 16) {\n buf[i + ii++] = 0;\n }\n\n return buf;\n}\n\n// **`unparse()` - Convert UUID byte array (ala parse()) into a string**\nfunction unparse(buf, offset) {\n var i = offset || 0, bth = _byteToHex;\n return bth[buf[i++]] + bth[buf[i++]] +\n bth[buf[i++]] + bth[buf[i++]] + '-' +\n bth[buf[i++]] + bth[buf[i++]] + '-' +\n bth[buf[i++]] + bth[buf[i++]] + '-' +\n bth[buf[i++]] + bth[buf[i++]] + '-' +\n bth[buf[i++]] + bth[buf[i++]] +\n bth[buf[i++]] + bth[buf[i++]] +\n bth[buf[i++]] + bth[buf[i++]];\n}\n\n// **`v1()` - Generate time-based UUID**\n//\n// Inspired by https://github.com/LiosK/UUID.js\n// and http://docs.python.org/library/uuid.html\n\n// random #'s we need to init node and clockseq\nvar _seedBytes = _rng();\n\n// Per 4.5, create and 48-bit node id, (47 random bits + multicast bit = 1)\nvar _nodeId = [\n _seedBytes[0] | 0x01,\n _seedBytes[1], _seedBytes[2], _seedBytes[3], _seedBytes[4], _seedBytes[5]\n];\n\n// Per 4.2.2, randomize (14 bit) clockseq\nvar _clockseq = (_seedBytes[6] << 8 | _seedBytes[7]) & 0x3fff;\n\n// Previous uuid creation time\nvar _lastMSecs = 0, _lastNSecs = 0;\n\n// See https://github.com/broofa/node-uuid for API details\nfunction v1(options, buf, offset) {\n var i = buf && offset || 0;\n var b = buf || [];\n\n options = options || {};\n\n var clockseq = options.clockseq !== undefined ? options.clockseq : _clockseq;\n\n // UUID timestamps are 100 nano-second units since the Gregorian epoch,\n // (1582-10-15 00:00). JSNumbers aren't precise enough for this, so\n // time is handled internally as 'msecs' (integer milliseconds) and 'nsecs'\n // (100-nanoseconds offset from msecs) since unix epoch, 1970-01-01 00:00.\n var msecs = options.msecs !== undefined ? options.msecs : new Date().getTime();\n\n // Per 4.2.1.2, use count of uuid's generated during the current clock\n // cycle to simulate higher resolution clock\n var nsecs = options.nsecs !== undefined ? options.nsecs : _lastNSecs + 1;\n\n // Time since last uuid creation (in msecs)\n var dt = (msecs - _lastMSecs) + (nsecs - _lastNSecs)/10000;\n\n // Per 4.2.1.2, Bump clockseq on clock regression\n if (dt < 0 && options.clockseq === undefined) {\n clockseq = clockseq + 1 & 0x3fff;\n }\n\n // Reset nsecs if clock regresses (new clockseq) or we've moved onto a new\n // time interval\n if ((dt < 0 || msecs > _lastMSecs) && options.nsecs === undefined) {\n nsecs = 0;\n }\n\n // Per 4.2.1.2 Throw error if too many uuids are requested\n if (nsecs >= 10000) {\n throw new Error('uuid.v1(): Can\\'t create more than 10M uuids/sec');\n }\n\n _lastMSecs = msecs;\n _lastNSecs = nsecs;\n _clockseq = clockseq;\n\n // Per 4.1.4 - Convert from unix epoch to Gregorian epoch\n msecs += 12219292800000;\n\n // `time_low`\n var tl = ((msecs & 0xfffffff) * 10000 + nsecs) % 0x100000000;\n b[i++] = tl >>> 24 & 0xff;\n b[i++] = tl >>> 16 & 0xff;\n b[i++] = tl >>> 8 & 0xff;\n b[i++] = tl & 0xff;\n\n // `time_mid`\n var tmh = (msecs / 0x100000000 * 10000) & 0xfffffff;\n b[i++] = tmh >>> 8 & 0xff;\n b[i++] = tmh & 0xff;\n\n // `time_high_and_version`\n b[i++] = tmh >>> 24 & 0xf | 0x10; // include version\n b[i++] = tmh >>> 16 & 0xff;\n\n // `clock_seq_hi_and_reserved` (Per 4.2.2 - include variant)\n b[i++] = clockseq >>> 8 | 0x80;\n\n // `clock_seq_low`\n b[i++] = clockseq & 0xff;\n\n // `node`\n var node = options.node || _nodeId;\n for (var n = 0; n < 6; n++) {\n b[i + n] = node[n];\n }\n\n return buf ? buf : unparse(b);\n}\n\n// **`v4()` - Generate random UUID**\n\n// See https://github.com/broofa/node-uuid for API details\nfunction v4(options, buf, offset) {\n // Deprecated - 'format' argument, as supported in v1.2\n var i = buf && offset || 0;\n\n if (typeof(options) == 'string') {\n buf = options == 'binary' ? new Array(16) : null;\n options = null;\n }\n options = options || {};\n\n var rnds = options.random || (options.rng || _rng)();\n\n // Per 4.4, set bits for version and `clock_seq_hi_and_reserved`\n rnds[6] = (rnds[6] & 0x0f) | 0x40;\n rnds[8] = (rnds[8] & 0x3f) | 0x80;\n\n // Copy bytes to buffer, if provided\n if (buf) {\n for (var ii = 0; ii < 16; ii++) {\n buf[i + ii] = rnds[ii];\n }\n }\n\n return buf || unparse(rnds);\n}\n\n// Export public API\nvar uuid = v4;\nuuid.v1 = v1;\nuuid.v4 = v4;\nuuid.parse = parse;\nuuid.unparse = unparse;\n\nmodule.exports = uuid;\n","/*\n * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.\n *\n * Use of this source code is governed by a BSD-style license\n * that can be found in the LICENSE file in the root of the source\n * tree.\n */\n /* eslint-env node */\n\n'use strict';\n\nvar adapterFactory = require('./adapter_factory.js');\nmodule.exports = adapterFactory({window: global.window});\n","/*\n * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.\n *\n * Use of this source code is governed by a BSD-style license\n * that can be found in the LICENSE file in the root of the source\n * tree.\n */\n /* eslint-env node */\n\n'use strict';\n\nvar utils = require('./utils');\n// Shimming starts here.\nmodule.exports = function(dependencies, opts) {\n var window = dependencies && dependencies.window;\n\n var options = {\n shimChrome: true,\n shimFirefox: true,\n shimEdge: true,\n shimSafari: true,\n };\n\n for (var key in opts) {\n if (hasOwnProperty.call(opts, key)) {\n options[key] = opts[key];\n }\n }\n\n // Utils.\n var logging = utils.log;\n var browserDetails = utils.detectBrowser(window);\n\n // Export to the adapter global object visible in the browser.\n var adapter = {\n browserDetails: browserDetails,\n extractVersion: utils.extractVersion,\n disableLog: utils.disableLog,\n disableWarnings: utils.disableWarnings\n };\n\n // Uncomment the line below if you want logging to occur, including logging\n // for the switch statement below. Can also be turned on in the browser via\n // adapter.disableLog(false), but then logging from the switch statement below\n // will not appear.\n // require('./utils').disableLog(false);\n\n // Browser shims.\n var chromeShim = require('./chrome/chrome_shim') || null;\n var edgeShim = require('./edge/edge_shim') || null;\n var firefoxShim = require('./firefox/firefox_shim') || null;\n var safariShim = require('./safari/safari_shim') || null;\n var commonShim = require('./common_shim') || null;\n\n // Shim browser if found.\n switch (browserDetails.browser) {\n case 'chrome':\n if (!chromeShim || !chromeShim.shimPeerConnection ||\n !options.shimChrome) {\n logging('Chrome shim is not included in this adapter release.');\n return adapter;\n }\n logging('adapter.js shimming chrome.');\n // Export to the adapter global object visible in the browser.\n adapter.browserShim = chromeShim;\n commonShim.shimCreateObjectURL(window);\n\n chromeShim.shimGetUserMedia(window);\n chromeShim.shimMediaStream(window);\n chromeShim.shimSourceObject(window);\n chromeShim.shimPeerConnection(window);\n chromeShim.shimOnTrack(window);\n chromeShim.shimAddTrackRemoveTrack(window);\n chromeShim.shimGetSendersWithDtmf(window);\n\n commonShim.shimRTCIceCandidate(window);\n break;\n case 'firefox':\n if (!firefoxShim || !firefoxShim.shimPeerConnection ||\n !options.shimFirefox) {\n logging('Firefox shim is not included in this adapter release.');\n return adapter;\n }\n logging('adapter.js shimming firefox.');\n // Export to the adapter global object visible in the browser.\n adapter.browserShim = firefoxShim;\n commonShim.shimCreateObjectURL(window);\n\n firefoxShim.shimGetUserMedia(window);\n firefoxShim.shimSourceObject(window);\n firefoxShim.shimPeerConnection(window);\n firefoxShim.shimOnTrack(window);\n\n commonShim.shimRTCIceCandidate(window);\n break;\n case 'edge':\n if (!edgeShim || !edgeShim.shimPeerConnection || !options.shimEdge) {\n logging('MS edge shim is not included in this adapter release.');\n return adapter;\n }\n logging('adapter.js shimming edge.');\n // Export to the adapter global object visible in the browser.\n adapter.browserShim = edgeShim;\n commonShim.shimCreateObjectURL(window);\n\n edgeShim.shimGetUserMedia(window);\n edgeShim.shimPeerConnection(window);\n edgeShim.shimReplaceTrack(window);\n\n // the edge shim implements the full RTCIceCandidate object.\n break;\n case 'safari':\n if (!safariShim || !options.shimSafari) {\n logging('Safari shim is not included in this adapter release.');\n return adapter;\n }\n logging('adapter.js shimming safari.');\n // Export to the adapter global object visible in the browser.\n adapter.browserShim = safariShim;\n commonShim.shimCreateObjectURL(window);\n\n safariShim.shimRTCIceServerUrls(window);\n safariShim.shimCallbacksAPI(window);\n safariShim.shimLocalStreamsAPI(window);\n safariShim.shimRemoteStreamsAPI(window);\n safariShim.shimTrackEventTransceiver(window);\n safariShim.shimGetUserMedia(window);\n\n commonShim.shimRTCIceCandidate(window);\n break;\n default:\n logging('Unsupported browser!');\n break;\n }\n\n return adapter;\n};\n","\n/*\n * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.\n *\n * Use of this source code is governed by a BSD-style license\n * that can be found in the LICENSE file in the root of the source\n * tree.\n */\n /* eslint-env node */\n'use strict';\nvar utils = require('../utils.js');\nvar logging = utils.log;\n\nvar chromeShim = {\n shimMediaStream: function(window) {\n window.MediaStream = window.MediaStream || window.webkitMediaStream;\n },\n\n shimOnTrack: function(window) {\n if (typeof window === 'object' && window.RTCPeerConnection && !('ontrack' in\n window.RTCPeerConnection.prototype)) {\n Object.defineProperty(window.RTCPeerConnection.prototype, 'ontrack', {\n get: function() {\n return this._ontrack;\n },\n set: function(f) {\n if (this._ontrack) {\n this.removeEventListener('track', this._ontrack);\n }\n this.addEventListener('track', this._ontrack = f);\n }\n });\n var origSetRemoteDescription =\n window.RTCPeerConnection.prototype.setRemoteDescription;\n window.RTCPeerConnection.prototype.setRemoteDescription = function() {\n var pc = this;\n if (!pc._ontrackpoly) {\n pc._ontrackpoly = function(e) {\n // onaddstream does not fire when a track is added to an existing\n // stream. But stream.onaddtrack is implemented so we use that.\n e.stream.addEventListener('addtrack', function(te) {\n var receiver;\n if (window.RTCPeerConnection.prototype.getReceivers) {\n receiver = pc.getReceivers().find(function(r) {\n return r.track && r.track.id === te.track.id;\n });\n } else {\n receiver = {track: te.track};\n }\n\n var event = new Event('track');\n event.track = te.track;\n event.receiver = receiver;\n event.transceiver = {receiver: receiver};\n event.streams = [e.stream];\n pc.dispatchEvent(event);\n });\n e.stream.getTracks().forEach(function(track) {\n var receiver;\n if (window.RTCPeerConnection.prototype.getReceivers) {\n receiver = pc.getReceivers().find(function(r) {\n return r.track && r.track.id === track.id;\n });\n } else {\n receiver = {track: track};\n }\n var event = new Event('track');\n event.track = track;\n event.receiver = receiver;\n event.transceiver = {receiver: receiver};\n event.streams = [e.stream];\n pc.dispatchEvent(event);\n });\n };\n pc.addEventListener('addstream', pc._ontrackpoly);\n }\n return origSetRemoteDescription.apply(pc, arguments);\n };\n }\n },\n\n shimGetSendersWithDtmf: function(window) {\n // Overrides addTrack/removeTrack, depends on shimAddTrackRemoveTrack.\n if (typeof window === 'object' && window.RTCPeerConnection &&\n !('getSenders' in window.RTCPeerConnection.prototype) &&\n 'createDTMFSender' in window.RTCPeerConnection.prototype) {\n var shimSenderWithDtmf = function(pc, track) {\n return {\n track: track,\n get dtmf() {\n if (this._dtmf === undefined) {\n if (track.kind === 'audio') {\n this._dtmf = pc.createDTMFSender(track);\n } else {\n this._dtmf = null;\n }\n }\n return this._dtmf;\n },\n _pc: pc\n };\n };\n\n // augment addTrack when getSenders is not available.\n if (!window.RTCPeerConnection.prototype.getSenders) {\n window.RTCPeerConnection.prototype.getSenders = function() {\n this._senders = this._senders || [];\n return this._senders.slice(); // return a copy of the internal state.\n };\n var origAddTrack = window.RTCPeerConnection.prototype.addTrack;\n window.RTCPeerConnection.prototype.addTrack = function(track, stream) {\n var pc = this;\n var sender = origAddTrack.apply(pc, arguments);\n if (!sender) {\n sender = shimSenderWithDtmf(pc, track);\n pc._senders.push(sender);\n }\n return sender;\n };\n\n var origRemoveTrack = window.RTCPeerConnection.prototype.removeTrack;\n window.RTCPeerConnection.prototype.removeTrack = function(sender) {\n var pc = this;\n origRemoveTrack.apply(pc, arguments);\n var idx = pc._senders.indexOf(sender);\n if (idx !== -1) {\n pc._senders.splice(idx, 1);\n }\n };\n }\n var origAddStream = window.RTCPeerConnection.prototype.addStream;\n window.RTCPeerConnection.prototype.addStream = function(stream) {\n var pc = this;\n pc._senders = pc._senders || [];\n origAddStream.apply(pc, [stream]);\n stream.getTracks().forEach(function(track) {\n pc._senders.push(shimSenderWithDtmf(pc, track));\n });\n };\n\n var origRemoveStream = window.RTCPeerConnection.prototype.removeStream;\n window.RTCPeerConnection.prototype.removeStream = function(stream) {\n var pc = this;\n pc._senders = pc._senders || [];\n origRemoveStream.apply(pc, [(pc._streams[stream.id] || stream)]);\n\n stream.getTracks().forEach(function(track) {\n var sender = pc._senders.find(function(s) {\n return s.track === track;\n });\n if (sender) {\n pc._senders.splice(pc._senders.indexOf(sender), 1); // remove sender\n }\n });\n };\n } else if (typeof window === 'object' && window.RTCPeerConnection &&\n 'getSenders' in window.RTCPeerConnection.prototype &&\n 'createDTMFSender' in window.RTCPeerConnection.prototype &&\n window.RTCRtpSender &&\n !('dtmf' in window.RTCRtpSender.prototype)) {\n var origGetSenders = window.RTCPeerConnection.prototype.getSenders;\n window.RTCPeerConnection.prototype.getSenders = function() {\n var pc = this;\n var senders = origGetSenders.apply(pc, []);\n senders.forEach(function(sender) {\n sender._pc = pc;\n });\n return senders;\n };\n\n Object.defineProperty(window.RTCRtpSender.prototype, 'dtmf', {\n get: function() {\n if (this._dtmf === undefined) {\n if (this.track.kind === 'audio') {\n this._dtmf = this._pc.createDTMFSender(this.track);\n } else {\n this._dtmf = null;\n }\n }\n return this._dtmf;\n }\n });\n }\n },\n\n shimSourceObject: function(window) {\n var URL = window && window.URL;\n\n if (typeof window === 'object') {\n if (window.HTMLMediaElement &&\n !('srcObject' in window.HTMLMediaElement.prototype)) {\n // Shim the srcObject property, once, when HTMLMediaElement is found.\n Object.defineProperty(window.HTMLMediaElement.prototype, 'srcObject', {\n get: function() {\n return this._srcObject;\n },\n set: function(stream) {\n var self = this;\n // Use _srcObject as a private property for this shim\n this._srcObject = stream;\n if (this.src) {\n URL.revokeObjectURL(this.src);\n }\n\n if (!stream) {\n this.src = '';\n return undefined;\n }\n this.src = URL.createObjectURL(stream);\n // We need to recreate the blob url when a track is added or\n // removed. Doing it manually since we want to avoid a recursion.\n stream.addEventListener('addtrack', function() {\n if (self.src) {\n URL.revokeObjectURL(self.src);\n }\n self.src = URL.createObjectURL(stream);\n });\n stream.addEventListener('removetrack', function() {\n if (self.src) {\n URL.revokeObjectURL(self.src);\n }\n self.src = URL.createObjectURL(stream);\n });\n }\n });\n }\n }\n },\n\n shimAddTrackRemoveTrack: function(window) {\n var browserDetails = utils.detectBrowser(window);\n // shim addTrack and removeTrack.\n if (window.RTCPeerConnection.prototype.addTrack &&\n browserDetails.version >= 62) {\n return;\n }\n\n // also shim pc.getLocalStreams when addTrack is shimmed\n // to return the original streams.\n var origGetLocalStreams = window.RTCPeerConnection.prototype\n .getLocalStreams;\n window.RTCPeerConnection.prototype.getLocalStreams = function() {\n var self = this;\n var nativeStreams = origGetLocalStreams.apply(this);\n self._reverseStreams = self._reverseStreams || {};\n return nativeStreams.map(function(stream) {\n return self._reverseStreams[stream.id];\n });\n };\n\n var origAddStream = window.RTCPeerConnection.prototype.addStream;\n window.RTCPeerConnection.prototype.addStream = function(stream) {\n var pc = this;\n pc._streams = pc._streams || {};\n pc._reverseStreams = pc._reverseStreams || {};\n\n stream.getTracks().forEach(function(track) {\n var alreadyExists = pc.getSenders().find(function(s) {\n return s.track === track;\n });\n if (alreadyExists) {\n throw new DOMException('Track already exists.',\n 'InvalidAccessError');\n }\n });\n // Add identity mapping for consistency with addTrack.\n // Unless this is being used with a stream from addTrack.\n if (!pc._reverseStreams[stream.id]) {\n var newStream = new window.MediaStream(stream.getTracks());\n pc._streams[stream.id] = newStream;\n pc._reverseStreams[newStream.id] = stream;\n stream = newStream;\n }\n origAddStream.apply(pc, [stream]);\n };\n\n var origRemoveStream = window.RTCPeerConnection.prototype.removeStream;\n window.RTCPeerConnection.prototype.removeStream = function(stream) {\n var pc = this;\n pc._streams = pc._streams || {};\n pc._reverseStreams = pc._reverseStreams || {};\n\n origRemoveStream.apply(pc, [(pc._streams[stream.id] || stream)]);\n delete pc._reverseStreams[(pc._streams[stream.id] ?\n pc._streams[stream.id].id : stream.id)];\n delete pc._streams[stream.id];\n };\n\n window.RTCPeerConnection.prototype.addTrack = function(track, stream) {\n var pc = this;\n if (pc.signalingState === 'closed') {\n throw new DOMException(\n 'The RTCPeerConnection\\'s signalingState is \\'closed\\'.',\n 'InvalidStateError');\n }\n var streams = [].slice.call(arguments, 1);\n if (streams.length !== 1 ||\n !streams[0].getTracks().find(function(t) {\n return t === track;\n })) {\n // this is not fully correct but all we can manage without\n // [[associated MediaStreams]] internal slot.\n throw new DOMException(\n 'The adapter.js addTrack polyfill only supports a single ' +\n ' stream which is associated with the specified track.',\n 'NotSupportedError');\n }\n\n var alreadyExists = pc.getSenders().find(function(s) {\n return s.track === track;\n });\n if (alreadyExists) {\n throw new DOMException('Track already exists.',\n 'InvalidAccessError');\n }\n\n pc._streams = pc._streams || {};\n pc._reverseStreams = pc._reverseStreams || {};\n var oldStream = pc._streams[stream.id];\n if (oldStream) {\n // this is using odd Chrome behaviour, use with caution:\n // https://bugs.chromium.org/p/webrtc/issues/detail?id=7815\n // Note: we rely on the high-level addTrack/dtmf shim to\n // create the sender with a dtmf sender.\n oldStream.addTrack(track);\n\n // Trigger ONN async.\n Promise.resolve().then(function() {\n pc.dispatchEvent(new Event('negotiationneeded'));\n });\n } else {\n var newStream = new window.MediaStream([track]);\n pc._streams[stream.id] = newStream;\n pc._reverseStreams[newStream.id] = stream;\n pc.addStream(newStream);\n }\n return pc.getSenders().find(function(s) {\n return s.track === track;\n });\n };\n\n // replace the internal stream id with the external one and\n // vice versa.\n function replaceInternalStreamId(pc, description) {\n var sdp = description.sdp;\n Object.keys(pc._reverseStreams || []).forEach(function(internalId) {\n var externalStream = pc._reverseStreams[internalId];\n var internalStream = pc._streams[externalStream.id];\n sdp = sdp.replace(new RegExp(internalStream.id, 'g'),\n externalStream.id);\n });\n return new RTCSessionDescription({\n type: description.type,\n sdp: sdp\n });\n }\n function replaceExternalStreamId(pc, description) {\n var sdp = description.sdp;\n Object.keys(pc._reverseStreams || []).forEach(function(internalId) {\n var externalStream = pc._reverseStreams[internalId];\n var internalStream = pc._streams[externalStream.id];\n sdp = sdp.replace(new RegExp(externalStream.id, 'g'),\n internalStream.id);\n });\n return new RTCSessionDescription({\n type: description.type,\n sdp: sdp\n });\n }\n ['createOffer', 'createAnswer'].forEach(function(method) {\n var nativeMethod = window.RTCPeerConnection.prototype[method];\n window.RTCPeerConnection.prototype[method] = function() {\n var pc = this;\n var args = arguments;\n var isLegacyCall = arguments.length &&\n typeof arguments[0] === 'function';\n if (isLegacyCall) {\n return nativeMethod.apply(pc, [\n function(description) {\n var desc = replaceInternalStreamId(pc, description);\n args[0].apply(null, [desc]);\n },\n function(err) {\n if (args[1]) {\n args[1].apply(null, err);\n }\n }, arguments[2]\n ]);\n }\n return nativeMethod.apply(pc, arguments)\n .then(function(description) {\n return replaceInternalStreamId(pc, description);\n });\n };\n });\n\n var origSetLocalDescription =\n window.RTCPeerConnection.prototype.setLocalDescription;\n window.RTCPeerConnection.prototype.setLocalDescription = function() {\n var pc = this;\n if (!arguments.length || !arguments[0].type) {\n return origSetLocalDescription.apply(pc, arguments);\n }\n arguments[0] = replaceExternalStreamId(pc, arguments[0]);\n return origSetLocalDescription.apply(pc, arguments);\n };\n\n // TODO: mangle getStats: https://w3c.github.io/webrtc-stats/#dom-rtcmediastreamstats-streamidentifier\n\n var origLocalDescription = Object.getOwnPropertyDescriptor(\n window.RTCPeerConnection.prototype, 'localDescription');\n Object.defineProperty(window.RTCPeerConnection.prototype,\n 'localDescription', {\n get: function() {\n var pc = this;\n var description = origLocalDescription.get.apply(this);\n if (description.type === '') {\n return description;\n }\n return replaceInternalStreamId(pc, description);\n }\n });\n\n window.RTCPeerConnection.prototype.removeTrack = function(sender) {\n var pc = this;\n if (pc.signalingState === 'closed') {\n throw new DOMException(\n 'The RTCPeerConnection\\'s signalingState is \\'closed\\'.',\n 'InvalidStateError');\n }\n // We can not yet check for sender instanceof RTCRtpSender\n // since we shim RTPSender. So we check if sender._pc is set.\n if (!sender._pc) {\n throw new DOMException('Argument 1 of RTCPeerConnection.removeTrack ' +\n 'does not implement interface RTCRtpSender.', 'TypeError');\n }\n var isLocal = sender._pc === pc;\n if (!isLocal) {\n throw new DOMException('Sender was not created by this connection.',\n 'InvalidAccessError');\n }\n\n // Search for the native stream the senders track belongs to.\n pc._streams = pc._streams || {};\n var stream;\n Object.keys(pc._streams).forEach(function(streamid) {\n var hasTrack = pc._streams[streamid].getTracks().find(function(track) {\n return sender.track === track;\n });\n if (hasTrack) {\n stream = pc._streams[streamid];\n }\n });\n\n if (stream) {\n if (stream.getTracks().length === 1) {\n // if this is the last track of the stream, remove the stream. This\n // takes care of any shimmed _senders.\n pc.removeStream(stream);\n } else {\n // relying on the same odd chrome behaviour as above.\n stream.removeTrack(sender.track);\n }\n pc.dispatchEvent(new Event('negotiationneeded'));\n }\n };\n },\n\n shimPeerConnection: function(window) {\n var browserDetails = utils.detectBrowser(window);\n\n // The RTCPeerConnection object.\n if (!window.RTCPeerConnection) {\n window.RTCPeerConnection = function(pcConfig, pcConstraints) {\n // Translate iceTransportPolicy to iceTransports,\n // see https://code.google.com/p/webrtc/issues/detail?id=4869\n // this was fixed in M56 along with unprefixing RTCPeerConnection.\n logging('PeerConnection');\n if (pcConfig && pcConfig.iceTransportPolicy) {\n pcConfig.iceTransports = pcConfig.iceTransportPolicy;\n }\n\n return new window.webkitRTCPeerConnection(pcConfig, pcConstraints);\n };\n window.RTCPeerConnection.prototype =\n window.webkitRTCPeerConnection.prototype;\n // wrap static methods. Currently just generateCertificate.\n if (window.webkitRTCPeerConnection.generateCertificate) {\n Object.defineProperty(window.RTCPeerConnection, 'generateCertificate', {\n get: function() {\n return window.webkitRTCPeerConnection.generateCertificate;\n }\n });\n }\n } else {\n // migrate from non-spec RTCIceServer.url to RTCIceServer.urls\n var OrigPeerConnection = window.RTCPeerConnection;\n window.RTCPeerConnection = function(pcConfig, pcConstraints) {\n if (pcConfig && pcConfig.iceServers) {\n var newIceServers = [];\n for (var i = 0; i < pcConfig.iceServers.length; i++) {\n var server = pcConfig.iceServers[i];\n if (!server.hasOwnProperty('urls') &&\n server.hasOwnProperty('url')) {\n utils.deprecated('RTCIceServer.url', 'RTCIceServer.urls');\n server = JSON.parse(JSON.stringify(server));\n server.urls = server.url;\n newIceServers.push(server);\n } else {\n newIceServers.push(pcConfig.iceServers[i]);\n }\n }\n pcConfig.iceServers = newIceServers;\n }\n return new OrigPeerConnection(pcConfig, pcConstraints);\n };\n window.RTCPeerConnection.prototype = OrigPeerConnection.prototype;\n // wrap static methods. Currently just generateCertificate.\n Object.defineProperty(window.RTCPeerConnection, 'generateCertificate', {\n get: function() {\n return OrigPeerConnection.generateCertificate;\n }\n });\n }\n\n var origGetStats = window.RTCPeerConnection.prototype.getStats;\n window.RTCPeerConnection.prototype.getStats = function(selector,\n successCallback, errorCallback) {\n var self = this;\n var args = arguments;\n\n // If selector is a function then we are in the old style stats so just\n // pass back the original getStats format to avoid breaking old users.\n if (arguments.length > 0 && typeof selector === 'function') {\n return origGetStats.apply(this, arguments);\n }\n\n // When spec-style getStats is supported, return those when called with\n // either no arguments or the selector argument is null.\n if (origGetStats.length === 0 && (arguments.length === 0 ||\n typeof arguments[0] !== 'function')) {\n return origGetStats.apply(this, []);\n }\n\n var fixChromeStats_ = function(response) {\n var standardReport = {};\n var reports = response.result();\n reports.forEach(function(report) {\n var standardStats = {\n id: report.id,\n timestamp: report.timestamp,\n type: {\n localcandidate: 'local-candidate',\n remotecandidate: 'remote-candidate'\n }[report.type] || report.type\n };\n report.names().forEach(function(name) {\n standardStats[name] = report.stat(name);\n });\n standardReport[standardStats.id] = standardStats;\n });\n\n return standardReport;\n };\n\n // shim getStats with maplike support\n var makeMapStats = function(stats) {\n return new Map(Object.keys(stats).map(function(key) {\n return [key, stats[key]];\n }));\n };\n\n if (arguments.length >= 2) {\n var successCallbackWrapper_ = function(response) {\n args[1](makeMapStats(fixChromeStats_(response)));\n };\n\n return origGetStats.apply(this, [successCallbackWrapper_,\n arguments[0]]);\n }\n\n // promise-support\n return new Promise(function(resolve, reject) {\n origGetStats.apply(self, [\n function(response) {\n resolve(makeMapStats(fixChromeStats_(response)));\n }, reject]);\n }).then(successCallback, errorCallback);\n };\n\n // add promise support -- natively available in Chrome 51\n if (browserDetails.version < 51) {\n ['setLocalDescription', 'setRemoteDescription', 'addIceCandidate']\n .forEach(function(method) {\n var nativeMethod = window.RTCPeerConnection.prototype[method];\n window.RTCPeerConnection.prototype[method] = function() {\n var args = arguments;\n var self = this;\n var promise = new Promise(function(resolve, reject) {\n nativeMethod.apply(self, [args[0], resolve, reject]);\n });\n if (args.length < 2) {\n return promise;\n }\n return promise.then(function() {\n args[1].apply(null, []);\n },\n function(err) {\n if (args.length >= 3) {\n args[2].apply(null, [err]);\n }\n });\n };\n });\n }\n\n // promise support for createOffer and createAnswer. Available (without\n // bugs) since M52: crbug/619289\n if (browserDetails.version < 52) {\n ['createOffer', 'createAnswer'].forEach(function(method) {\n var nativeMethod = window.RTCPeerConnection.prototype[method];\n window.RTCPeerConnection.prototype[method] = function() {\n var self = this;\n if (arguments.length < 1 || (arguments.length === 1 &&\n typeof arguments[0] === 'object')) {\n var opts = arguments.length === 1 ? arguments[0] : undefined;\n return new Promise(function(resolve, reject) {\n nativeMethod.apply(self, [resolve, reject, opts]);\n });\n }\n return nativeMethod.apply(this, arguments);\n };\n });\n }\n\n // shim implicit creation of RTCSessionDescription/RTCIceCandidate\n ['setLocalDescription', 'setRemoteDescription', 'addIceCandidate']\n .forEach(function(method) {\n var nativeMethod = window.RTCPeerConnection.prototype[method];\n window.RTCPeerConnection.prototype[method] = function() {\n arguments[0] = new ((method === 'addIceCandidate') ?\n window.RTCIceCandidate :\n window.RTCSessionDescription)(arguments[0]);\n return nativeMethod.apply(this, arguments);\n };\n });\n\n // support for addIceCandidate(null or undefined)\n var nativeAddIceCandidate =\n window.RTCPeerConnection.prototype.addIceCandidate;\n window.RTCPeerConnection.prototype.addIceCandidate = function() {\n if (!arguments[0]) {\n if (arguments[1]) {\n arguments[1].apply(null);\n }\n return Promise.resolve();\n }\n return nativeAddIceCandidate.apply(this, arguments);\n };\n }\n};\n\n\n// Expose public methods.\nmodule.exports = {\n shimMediaStream: chromeShim.shimMediaStream,\n shimOnTrack: chromeShim.shimOnTrack,\n shimAddTrackRemoveTrack: chromeShim.shimAddTrackRemoveTrack,\n shimGetSendersWithDtmf: chromeShim.shimGetSendersWithDtmf,\n shimSourceObject: chromeShim.shimSourceObject,\n shimPeerConnection: chromeShim.shimPeerConnection,\n shimGetUserMedia: require('./getusermedia')\n};\n","/*\n * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.\n *\n * Use of this source code is governed by a BSD-style license\n * that can be found in the LICENSE file in the root of the source\n * tree.\n */\n /* eslint-env node */\n'use strict';\nvar utils = require('../utils.js');\nvar logging = utils.log;\n\n// Expose public methods.\nmodule.exports = function(window) {\n var browserDetails = utils.detectBrowser(window);\n var navigator = window && window.navigator;\n\n var constraintsToChrome_ = function(c) {\n if (typeof c !== 'object' || c.mandatory || c.optional) {\n return c;\n }\n var cc = {};\n Object.keys(c).forEach(function(key) {\n if (key === 'require' || key === 'advanced' || key === 'mediaSource') {\n return;\n }\n var r = (typeof c[key] === 'object') ? c[key] : {ideal: c[key]};\n if (r.exact !== undefined && typeof r.exact === 'number') {\n r.min = r.max = r.exact;\n }\n var oldname_ = function(prefix, name) {\n if (prefix) {\n return prefix + name.charAt(0).toUpperCase() + name.slice(1);\n }\n return (name === 'deviceId') ? 'sourceId' : name;\n };\n if (r.ideal !== undefined) {\n cc.optional = cc.optional || [];\n var oc = {};\n if (typeof r.ideal === 'number') {\n oc[oldname_('min', key)] = r.ideal;\n cc.optional.push(oc);\n oc = {};\n oc[oldname_('max', key)] = r.ideal;\n cc.optional.push(oc);\n } else {\n oc[oldname_('', key)] = r.ideal;\n cc.optional.push(oc);\n }\n }\n if (r.exact !== undefined && typeof r.exact !== 'number') {\n cc.mandatory = cc.mandatory || {};\n cc.mandatory[oldname_('', key)] = r.exact;\n } else {\n ['min', 'max'].forEach(function(mix) {\n if (r[mix] !== undefined) {\n cc.mandatory = cc.mandatory || {};\n cc.mandatory[oldname_(mix, key)] = r[mix];\n }\n });\n }\n });\n if (c.advanced) {\n cc.optional = (cc.optional || []).concat(c.advanced);\n }\n return cc;\n };\n\n var shimConstraints_ = function(constraints, func) {\n constraints = JSON.parse(JSON.stringify(constraints));\n if (constraints && typeof constraints.audio === 'object') {\n var remap = function(obj, a, b) {\n if (a in obj && !(b in obj)) {\n obj[b] = obj[a];\n delete obj[a];\n }\n };\n constraints = JSON.parse(JSON.stringify(constraints));\n remap(constraints.audio, 'autoGainControl', 'googAutoGainControl');\n remap(constraints.audio, 'noiseSuppression', 'googNoiseSuppression');\n constraints.audio = constraintsToChrome_(constraints.audio);\n }\n if (constraints && typeof constraints.video === 'object') {\n // Shim facingMode for mobile & surface pro.\n var face = constraints.video.facingMode;\n face = face && ((typeof face === 'object') ? face : {ideal: face});\n var getSupportedFacingModeLies = browserDetails.version < 61;\n\n if ((face && (face.exact === 'user' || face.exact === 'environment' ||\n face.ideal === 'user' || face.ideal === 'environment')) &&\n !(navigator.mediaDevices.getSupportedConstraints &&\n navigator.mediaDevices.getSupportedConstraints().facingMode &&\n !getSupportedFacingModeLies)) {\n delete constraints.video.facingMode;\n var matches;\n if (face.exact === 'environment' || face.ideal === 'environment') {\n matches = ['back', 'rear'];\n } else if (face.exact === 'user' || face.ideal === 'user') {\n matches = ['front'];\n }\n if (matches) {\n // Look for matches in label, or use last cam for back (typical).\n return navigator.mediaDevices.enumerateDevices()\n .then(function(devices) {\n devices = devices.filter(function(d) {\n return d.kind === 'videoinput';\n });\n var dev = devices.find(function(d) {\n return matches.some(function(match) {\n return d.label.toLowerCase().indexOf(match) !== -1;\n });\n });\n if (!dev && devices.length && matches.indexOf('back') !== -1) {\n dev = devices[devices.length - 1]; // more likely the back cam\n }\n if (dev) {\n constraints.video.deviceId = face.exact ? {exact: dev.deviceId} :\n {ideal: dev.deviceId};\n }\n constraints.video = constraintsToChrome_(constraints.video);\n logging('chrome: ' + JSON.stringify(constraints));\n return func(constraints);\n });\n }\n }\n constraints.video = constraintsToChrome_(constraints.video);\n }\n logging('chrome: ' + JSON.stringify(constraints));\n return func(constraints);\n };\n\n var shimError_ = function(e) {\n return {\n name: {\n PermissionDeniedError: 'NotAllowedError',\n InvalidStateError: 'NotReadableError',\n DevicesNotFoundError: 'NotFoundError',\n ConstraintNotSatisfiedError: 'OverconstrainedError',\n TrackStartError: 'NotReadableError',\n MediaDeviceFailedDueToShutdown: 'NotReadableError',\n MediaDeviceKillSwitchOn: 'NotReadableError'\n }[e.name] || e.name,\n message: e.message,\n constraint: e.constraintName,\n toString: function() {\n return this.name + (this.message && ': ') + this.message;\n }\n };\n };\n\n var getUserMedia_ = function(constraints, onSuccess, onError) {\n shimConstraints_(constraints, function(c) {\n navigator.webkitGetUserMedia(c, onSuccess, function(e) {\n if (onError) {\n onError(shimError_(e));\n }\n });\n });\n };\n\n navigator.getUserMedia = getUserMedia_;\n\n // Returns the result of getUserMedia as a Promise.\n var getUserMediaPromise_ = function(constraints) {\n return new Promise(function(resolve, reject) {\n navigator.getUserMedia(constraints, resolve, reject);\n });\n };\n\n if (!navigator.mediaDevices) {\n navigator.mediaDevices = {\n getUserMedia: getUserMediaPromise_,\n enumerateDevices: function() {\n return new Promise(function(resolve) {\n var kinds = {audio: 'audioinput', video: 'videoinput'};\n return window.MediaStreamTrack.getSources(function(devices) {\n resolve(devices.map(function(device) {\n return {label: device.label,\n kind: kinds[device.kind],\n deviceId: device.id,\n groupId: ''};\n }));\n });\n });\n },\n getSupportedConstraints: function() {\n return {\n deviceId: true, echoCancellation: true, facingMode: true,\n frameRate: true, height: true, width: true\n };\n }\n };\n }\n\n // A shim for getUserMedia method on the mediaDevices object.\n // TODO(KaptenJansson) remove once implemented in Chrome stable.\n if (!navigator.mediaDevices.getUserMedia) {\n navigator.mediaDevices.getUserMedia = function(constraints) {\n return getUserMediaPromise_(constraints);\n };\n } else {\n // Even though Chrome 45 has navigator.mediaDevices and a getUserMedia\n // function which returns a Promise, it does not accept spec-style\n // constraints.\n var origGetUserMedia = navigator.mediaDevices.getUserMedia.\n bind(navigator.mediaDevices);\n navigator.mediaDevices.getUserMedia = function(cs) {\n return shimConstraints_(cs, function(c) {\n return origGetUserMedia(c).then(function(stream) {\n if (c.audio && !stream.getAudioTracks().length ||\n c.video && !stream.getVideoTracks().length) {\n stream.getTracks().forEach(function(track) {\n track.stop();\n });\n throw new DOMException('', 'NotFoundError');\n }\n return stream;\n }, function(e) {\n return Promise.reject(shimError_(e));\n });\n });\n };\n }\n\n // Dummy devicechange event methods.\n // TODO(KaptenJansson) remove once implemented in Chrome stable.\n if (typeof navigator.mediaDevices.addEventListener === 'undefined') {\n navigator.mediaDevices.addEventListener = function() {\n logging('Dummy mediaDevices.addEventListener called.');\n };\n }\n if (typeof navigator.mediaDevices.removeEventListener === 'undefined') {\n navigator.mediaDevices.removeEventListener = function() {\n logging('Dummy mediaDevices.removeEventListener called.');\n };\n }\n};\n","/*\n * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.\n *\n * Use of this source code is governed by a BSD-style license\n * that can be found in the LICENSE file in the root of the source\n * tree.\n */\n /* eslint-env node */\n'use strict';\n\nvar SDPUtils = require('sdp');\nvar utils = require('./utils');\n\n// Wraps the peerconnection event eventNameToWrap in a function\n// which returns the modified event object.\nfunction wrapPeerConnectionEvent(window, eventNameToWrap, wrapper) {\n if (!window.RTCPeerConnection) {\n return;\n }\n var proto = window.RTCPeerConnection.prototype;\n var nativeAddEventListener = proto.addEventListener;\n proto.addEventListener = function(nativeEventName, cb) {\n if (nativeEventName !== eventNameToWrap) {\n return nativeAddEventListener.apply(this, arguments);\n }\n var wrappedCallback = function(e) {\n cb(wrapper(e));\n };\n this._eventMap = this._eventMap || {};\n this._eventMap[cb] = wrappedCallback;\n return nativeAddEventListener.apply(this, [nativeEventName,\n wrappedCallback]);\n };\n\n var nativeRemoveEventListener = proto.removeEventListener;\n proto.removeEventListener = function(nativeEventName, cb) {\n if (nativeEventName !== eventNameToWrap || !this._eventMap\n || !this._eventMap[cb]) {\n return nativeRemoveEventListener.apply(this, arguments);\n }\n var unwrappedCb = this._eventMap[cb];\n delete this._eventMap[cb];\n return nativeRemoveEventListener.apply(this, [nativeEventName,\n unwrappedCb]);\n };\n\n Object.defineProperty(proto, 'on' + eventNameToWrap, {\n get: function() {\n return this['_on' + eventNameToWrap];\n },\n set: function(cb) {\n if (this['_on' + eventNameToWrap]) {\n this.removeEventListener(eventNameToWrap,\n this['_on' + eventNameToWrap]);\n delete this['_on' + eventNameToWrap];\n }\n if (cb) {\n this.addEventListener(eventNameToWrap,\n this['_on' + eventNameToWrap] = cb);\n }\n }\n });\n}\n\nmodule.exports = {\n shimRTCIceCandidate: function(window) {\n // foundation is arbitrarily chosen as an indicator for full support for\n // https://w3c.github.io/webrtc-pc/#rtcicecandidate-interface\n if (window.RTCIceCandidate && 'foundation' in\n window.RTCIceCandidate.prototype) {\n return;\n }\n\n var NativeRTCIceCandidate = window.RTCIceCandidate;\n window.RTCIceCandidate = function(args) {\n // Remove the a= which shouldn't be part of the candidate string.\n if (typeof args === 'object' && args.candidate &&\n args.candidate.indexOf('a=') === 0) {\n args = JSON.parse(JSON.stringify(args));\n args.candidate = args.candidate.substr(2);\n }\n\n // Augment the native candidate with the parsed fields.\n var nativeCandidate = new NativeRTCIceCandidate(args);\n var parsedCandidate = SDPUtils.parseCandidate(args.candidate);\n var augmentedCandidate = Object.assign(nativeCandidate,\n parsedCandidate);\n\n // Add a serializer that does not serialize the extra attributes.\n augmentedCandidate.toJSON = function() {\n return {\n candidate: augmentedCandidate.candidate,\n sdpMid: augmentedCandidate.sdpMid,\n sdpMLineIndex: augmentedCandidate.sdpMLineIndex,\n usernameFragment: augmentedCandidate.usernameFragment,\n };\n };\n return augmentedCandidate;\n };\n\n // Hook up the augmented candidate in onicecandidate and\n // addEventListener('icecandidate', ...)\n wrapPeerConnectionEvent(window, 'icecandidate', function(e) {\n if (e.candidate) {\n Object.defineProperty(e, 'candidate', {\n value: new window.RTCIceCandidate(e.candidate),\n writable: 'false'\n });\n }\n return e;\n });\n },\n\n // shimCreateObjectURL must be called before shimSourceObject to avoid loop.\n\n shimCreateObjectURL: function(window) {\n var URL = window && window.URL;\n\n if (!(typeof window === 'object' && window.HTMLMediaElement &&\n 'srcObject' in window.HTMLMediaElement.prototype &&\n URL.createObjectURL && URL.revokeObjectURL)) {\n // Only shim CreateObjectURL using srcObject if srcObject exists.\n return undefined;\n }\n\n var nativeCreateObjectURL = URL.createObjectURL.bind(URL);\n var nativeRevokeObjectURL = URL.revokeObjectURL.bind(URL);\n var streams = new Map(), newId = 0;\n\n URL.createObjectURL = function(stream) {\n if ('getTracks' in stream) {\n var url = 'polyblob:' + (++newId);\n streams.set(url, stream);\n utils.deprecated('URL.createObjectURL(stream)',\n 'elem.srcObject = stream');\n return url;\n }\n return nativeCreateObjectURL(stream);\n };\n URL.revokeObjectURL = function(url) {\n nativeRevokeObjectURL(url);\n streams.delete(url);\n };\n\n var dsc = Object.getOwnPropertyDescriptor(window.HTMLMediaElement.prototype,\n 'src');\n Object.defineProperty(window.HTMLMediaElement.prototype, 'src', {\n get: function() {\n return dsc.get.apply(this);\n },\n set: function(url) {\n this.srcObject = streams.get(url) || null;\n return dsc.set.apply(this, [url]);\n }\n });\n\n var nativeSetAttribute = window.HTMLMediaElement.prototype.setAttribute;\n window.HTMLMediaElement.prototype.setAttribute = function() {\n if (arguments.length === 2 &&\n ('' + arguments[0]).toLowerCase() === 'src') {\n this.srcObject = streams.get(arguments[1]) || null;\n }\n return nativeSetAttribute.apply(this, arguments);\n };\n }\n};\n","/*\n * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.\n *\n * Use of this source code is governed by a BSD-style license\n * that can be found in the LICENSE file in the root of the source\n * tree.\n */\n /* eslint-env node */\n'use strict';\n\nvar utils = require('../utils');\nvar shimRTCPeerConnection = require('rtcpeerconnection-shim');\n\nmodule.exports = {\n shimGetUserMedia: require('./getusermedia'),\n shimPeerConnection: function(window) {\n var browserDetails = utils.detectBrowser(window);\n\n if (window.RTCIceGatherer) {\n // ORTC defines an RTCIceCandidate object but no constructor.\n // Not implemented in Edge.\n if (!window.RTCIceCandidate) {\n window.RTCIceCandidate = function(args) {\n return args;\n };\n }\n // ORTC does not have a session description object but\n // other browsers (i.e. Chrome) that will support both PC and ORTC\n // in the future might have this defined already.\n if (!window.RTCSessionDescription) {\n window.RTCSessionDescription = function(args) {\n return args;\n };\n }\n // this adds an additional event listener to MediaStrackTrack that signals\n // when a tracks enabled property was changed. Workaround for a bug in\n // addStream, see below. No longer required in 15025+\n if (browserDetails.version < 15025) {\n var origMSTEnabled = Object.getOwnPropertyDescriptor(\n window.MediaStreamTrack.prototype, 'enabled');\n Object.defineProperty(window.MediaStreamTrack.prototype, 'enabled', {\n set: function(value) {\n origMSTEnabled.set.call(this, value);\n var ev = new Event('enabled');\n ev.enabled = value;\n this.dispatchEvent(ev);\n }\n });\n }\n }\n\n // ORTC defines the DTMF sender a bit different.\n // https://github.com/w3c/ortc/issues/714\n if (window.RTCRtpSender && !('dtmf' in window.RTCRtpSender.prototype)) {\n Object.defineProperty(window.RTCRtpSender.prototype, 'dtmf', {\n get: function() {\n if (this._dtmf === undefined) {\n if (this.track.kind === 'audio') {\n this._dtmf = new window.RTCDtmfSender(this);\n } else if (this.track.kind === 'video') {\n this._dtmf = null;\n }\n }\n return this._dtmf;\n }\n });\n }\n\n window.RTCPeerConnection =\n shimRTCPeerConnection(window, browserDetails.version);\n },\n shimReplaceTrack: function(window) {\n // ORTC has replaceTrack -- https://github.com/w3c/ortc/issues/614\n if (window.RTCRtpSender &&\n !('replaceTrack' in window.RTCRtpSender.prototype)) {\n window.RTCRtpSender.prototype.replaceTrack =\n window.RTCRtpSender.prototype.setTrack;\n }\n }\n};\n","/*\n * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.\n *\n * Use of this source code is governed by a BSD-style license\n * that can be found in the LICENSE file in the root of the source\n * tree.\n */\n /* eslint-env node */\n'use strict';\n\n// Expose public methods.\nmodule.exports = function(window) {\n var navigator = window && window.navigator;\n\n var shimError_ = function(e) {\n return {\n name: {PermissionDeniedError: 'NotAllowedError'}[e.name] || e.name,\n message: e.message,\n constraint: e.constraint,\n toString: function() {\n return this.name;\n }\n };\n };\n\n // getUserMedia error shim.\n var origGetUserMedia = navigator.mediaDevices.getUserMedia.\n bind(navigator.mediaDevices);\n navigator.mediaDevices.getUserMedia = function(c) {\n return origGetUserMedia(c).catch(function(e) {\n return Promise.reject(shimError_(e));\n });\n };\n};\n","/*\n * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.\n *\n * Use of this source code is governed by a BSD-style license\n * that can be found in the LICENSE file in the root of the source\n * tree.\n */\n /* eslint-env node */\n'use strict';\n\nvar utils = require('../utils');\n\nvar firefoxShim = {\n shimOnTrack: function(window) {\n if (typeof window === 'object' && window.RTCPeerConnection && !('ontrack' in\n window.RTCPeerConnection.prototype)) {\n Object.defineProperty(window.RTCPeerConnection.prototype, 'ontrack', {\n get: function() {\n return this._ontrack;\n },\n set: function(f) {\n if (this._ontrack) {\n this.removeEventListener('track', this._ontrack);\n this.removeEventListener('addstream', this._ontrackpoly);\n }\n this.addEventListener('track', this._ontrack = f);\n this.addEventListener('addstream', this._ontrackpoly = function(e) {\n e.stream.getTracks().forEach(function(track) {\n var event = new Event('track');\n event.track = track;\n event.receiver = {track: track};\n event.transceiver = {receiver: event.receiver};\n event.streams = [e.stream];\n this.dispatchEvent(event);\n }.bind(this));\n }.bind(this));\n }\n });\n }\n if (typeof window === 'object' && window.RTCTrackEvent &&\n ('receiver' in window.RTCTrackEvent.prototype) &&\n !('transceiver' in window.RTCTrackEvent.prototype)) {\n Object.defineProperty(window.RTCTrackEvent.prototype, 'transceiver', {\n get: function() {\n return {receiver: this.receiver};\n }\n });\n }\n },\n\n shimSourceObject: function(window) {\n // Firefox has supported mozSrcObject since FF22, unprefixed in 42.\n if (typeof window === 'object') {\n if (window.HTMLMediaElement &&\n !('srcObject' in window.HTMLMediaElement.prototype)) {\n // Shim the srcObject property, once, when HTMLMediaElement is found.\n Object.defineProperty(window.HTMLMediaElement.prototype, 'srcObject', {\n get: function() {\n return this.mozSrcObject;\n },\n set: function(stream) {\n this.mozSrcObject = stream;\n }\n });\n }\n }\n },\n\n shimPeerConnection: function(window) {\n var browserDetails = utils.detectBrowser(window);\n\n if (typeof window !== 'object' || !(window.RTCPeerConnection ||\n window.mozRTCPeerConnection)) {\n return; // probably media.peerconnection.enabled=false in about:config\n }\n // The RTCPeerConnection object.\n if (!window.RTCPeerConnection) {\n window.RTCPeerConnection = function(pcConfig, pcConstraints) {\n if (browserDetails.version < 38) {\n // .urls is not supported in FF < 38.\n // create RTCIceServers with a single url.\n if (pcConfig && pcConfig.iceServers) {\n var newIceServers = [];\n for (var i = 0; i < pcConfig.iceServers.length; i++) {\n var server = pcConfig.iceServers[i];\n if (server.hasOwnProperty('urls')) {\n for (var j = 0; j < server.urls.length; j++) {\n var newServer = {\n url: server.urls[j]\n };\n if (server.urls[j].indexOf('turn') === 0) {\n newServer.username = server.username;\n newServer.credential = server.credential;\n }\n newIceServers.push(newServer);\n }\n } else {\n newIceServers.push(pcConfig.iceServers[i]);\n }\n }\n pcConfig.iceServers = newIceServers;\n }\n }\n return new window.mozRTCPeerConnection(pcConfig, pcConstraints);\n };\n window.RTCPeerConnection.prototype =\n window.mozRTCPeerConnection.prototype;\n\n // wrap static methods. Currently just generateCertificate.\n if (window.mozRTCPeerConnection.generateCertificate) {\n Object.defineProperty(window.RTCPeerConnection, 'generateCertificate', {\n get: function() {\n return window.mozRTCPeerConnection.generateCertificate;\n }\n });\n }\n\n window.RTCSessionDescription = window.mozRTCSessionDescription;\n window.RTCIceCandidate = window.mozRTCIceCandidate;\n }\n\n // shim away need for obsolete RTCIceCandidate/RTCSessionDescription.\n ['setLocalDescription', 'setRemoteDescription', 'addIceCandidate']\n .forEach(function(method) {\n var nativeMethod = window.RTCPeerConnection.prototype[method];\n window.RTCPeerConnection.prototype[method] = function() {\n arguments[0] = new ((method === 'addIceCandidate') ?\n window.RTCIceCandidate :\n window.RTCSessionDescription)(arguments[0]);\n return nativeMethod.apply(this, arguments);\n };\n });\n\n // support for addIceCandidate(null or undefined)\n var nativeAddIceCandidate =\n window.RTCPeerConnection.prototype.addIceCandidate;\n window.RTCPeerConnection.prototype.addIceCandidate = function() {\n if (!arguments[0]) {\n if (arguments[1]) {\n arguments[1].apply(null);\n }\n return Promise.resolve();\n }\n return nativeAddIceCandidate.apply(this, arguments);\n };\n\n // shim getStats with maplike support\n var makeMapStats = function(stats) {\n var map = new Map();\n Object.keys(stats).forEach(function(key) {\n map.set(key, stats[key]);\n map[key] = stats[key];\n });\n return map;\n };\n\n var modernStatsTypes = {\n inboundrtp: 'inbound-rtp',\n outboundrtp: 'outbound-rtp',\n candidatepair: 'candidate-pair',\n localcandidate: 'local-candidate',\n remotecandidate: 'remote-candidate'\n };\n\n var nativeGetStats = window.RTCPeerConnection.prototype.getStats;\n window.RTCPeerConnection.prototype.getStats = function(\n selector,\n onSucc,\n onErr\n ) {\n return nativeGetStats.apply(this, [selector || null])\n .then(function(stats) {\n if (browserDetails.version < 48) {\n stats = makeMapStats(stats);\n }\n if (browserDetails.version < 53 && !onSucc) {\n // Shim only promise getStats with spec-hyphens in type names\n // Leave callback version alone; misc old uses of forEach before Map\n try {\n stats.forEach(function(stat) {\n stat.type = modernStatsTypes[stat.type] || stat.type;\n });\n } catch (e) {\n if (e.name !== 'TypeError') {\n throw e;\n }\n // Avoid TypeError: \"type\" is read-only, in old versions. 34-43ish\n stats.forEach(function(stat, i) {\n stats.set(i, Object.assign({}, stat, {\n type: modernStatsTypes[stat.type] || stat.type\n }));\n });\n }\n }\n return stats;\n })\n .then(onSucc, onErr);\n };\n }\n};\n\n// Expose public methods.\nmodule.exports = {\n shimOnTrack: firefoxShim.shimOnTrack,\n shimSourceObject: firefoxShim.shimSourceObject,\n shimPeerConnection: firefoxShim.shimPeerConnection,\n shimGetUserMedia: require('./getusermedia')\n};\n","/*\n * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.\n *\n * Use of this source code is governed by a BSD-style license\n * that can be found in the LICENSE file in the root of the source\n * tree.\n */\n /* eslint-env node */\n'use strict';\n\nvar utils = require('../utils');\nvar logging = utils.log;\n\n// Expose public methods.\nmodule.exports = function(window) {\n var browserDetails = utils.detectBrowser(window);\n var navigator = window && window.navigator;\n var MediaStreamTrack = window && window.MediaStreamTrack;\n\n var shimError_ = function(e) {\n return {\n name: {\n InternalError: 'NotReadableError',\n NotSupportedError: 'TypeError',\n PermissionDeniedError: 'NotAllowedError',\n SecurityError: 'NotAllowedError'\n }[e.name] || e.name,\n message: {\n 'The operation is insecure.': 'The request is not allowed by the ' +\n 'user agent or the platform in the current context.'\n }[e.message] || e.message,\n constraint: e.constraint,\n toString: function() {\n return this.name + (this.message && ': ') + this.message;\n }\n };\n };\n\n // getUserMedia constraints shim.\n var getUserMedia_ = function(constraints, onSuccess, onError) {\n var constraintsToFF37_ = function(c) {\n if (typeof c !== 'object' || c.require) {\n return c;\n }\n var require = [];\n Object.keys(c).forEach(function(key) {\n if (key === 'require' || key === 'advanced' || key === 'mediaSource') {\n return;\n }\n var r = c[key] = (typeof c[key] === 'object') ?\n c[key] : {ideal: c[key]};\n if (r.min !== undefined ||\n r.max !== undefined || r.exact !== undefined) {\n require.push(key);\n }\n if (r.exact !== undefined) {\n if (typeof r.exact === 'number') {\n r. min = r.max = r.exact;\n } else {\n c[key] = r.exact;\n }\n delete r.exact;\n }\n if (r.ideal !== undefined) {\n c.advanced = c.advanced || [];\n var oc = {};\n if (typeof r.ideal === 'number') {\n oc[key] = {min: r.ideal, max: r.ideal};\n } else {\n oc[key] = r.ideal;\n }\n c.advanced.push(oc);\n delete r.ideal;\n if (!Object.keys(r).length) {\n delete c[key];\n }\n }\n });\n if (require.length) {\n c.require = require;\n }\n return c;\n };\n constraints = JSON.parse(JSON.stringify(constraints));\n if (browserDetails.version < 38) {\n logging('spec: ' + JSON.stringify(constraints));\n if (constraints.audio) {\n constraints.audio = constraintsToFF37_(constraints.audio);\n }\n if (constraints.video) {\n constraints.video = constraintsToFF37_(constraints.video);\n }\n logging('ff37: ' + JSON.stringify(constraints));\n }\n return navigator.mozGetUserMedia(constraints, onSuccess, function(e) {\n onError(shimError_(e));\n });\n };\n\n // Returns the result of getUserMedia as a Promise.\n var getUserMediaPromise_ = function(constraints) {\n return new Promise(function(resolve, reject) {\n getUserMedia_(constraints, resolve, reject);\n });\n };\n\n // Shim for mediaDevices on older versions.\n if (!navigator.mediaDevices) {\n navigator.mediaDevices = {getUserMedia: getUserMediaPromise_,\n addEventListener: function() { },\n removeEventListener: function() { }\n };\n }\n navigator.mediaDevices.enumerateDevices =\n navigator.mediaDevices.enumerateDevices || function() {\n return new Promise(function(resolve) {\n var infos = [\n {kind: 'audioinput', deviceId: 'default', label: '', groupId: ''},\n {kind: 'videoinput', deviceId: 'default', label: '', groupId: ''}\n ];\n resolve(infos);\n });\n };\n\n if (browserDetails.version < 41) {\n // Work around http://bugzil.la/1169665\n var orgEnumerateDevices =\n navigator.mediaDevices.enumerateDevices.bind(navigator.mediaDevices);\n navigator.mediaDevices.enumerateDevices = function() {\n return orgEnumerateDevices().then(undefined, function(e) {\n if (e.name === 'NotFoundError') {\n return [];\n }\n throw e;\n });\n };\n }\n if (browserDetails.version < 49) {\n var origGetUserMedia = navigator.mediaDevices.getUserMedia.\n bind(navigator.mediaDevices);\n navigator.mediaDevices.getUserMedia = function(c) {\n return origGetUserMedia(c).then(function(stream) {\n // Work around https://bugzil.la/802326\n if (c.audio && !stream.getAudioTracks().length ||\n c.video && !stream.getVideoTracks().length) {\n stream.getTracks().forEach(function(track) {\n track.stop();\n });\n throw new DOMException('The object can not be found here.',\n 'NotFoundError');\n }\n return stream;\n }, function(e) {\n return Promise.reject(shimError_(e));\n });\n };\n }\n if (!(browserDetails.version > 55 &&\n 'autoGainControl' in navigator.mediaDevices.getSupportedConstraints())) {\n var remap = function(obj, a, b) {\n if (a in obj && !(b in obj)) {\n obj[b] = obj[a];\n delete obj[a];\n }\n };\n\n var nativeGetUserMedia = navigator.mediaDevices.getUserMedia.\n bind(navigator.mediaDevices);\n navigator.mediaDevices.getUserMedia = function(c) {\n if (typeof c === 'object' && typeof c.audio === 'object') {\n c = JSON.parse(JSON.stringify(c));\n remap(c.audio, 'autoGainControl', 'mozAutoGainControl');\n remap(c.audio, 'noiseSuppression', 'mozNoiseSuppression');\n }\n return nativeGetUserMedia(c);\n };\n\n if (MediaStreamTrack && MediaStreamTrack.prototype.getSettings) {\n var nativeGetSettings = MediaStreamTrack.prototype.getSettings;\n MediaStreamTrack.prototype.getSettings = function() {\n var obj = nativeGetSettings.apply(this, arguments);\n remap(obj, 'mozAutoGainControl', 'autoGainControl');\n remap(obj, 'mozNoiseSuppression', 'noiseSuppression');\n return obj;\n };\n }\n\n if (MediaStreamTrack && MediaStreamTrack.prototype.applyConstraints) {\n var nativeApplyConstraints = MediaStreamTrack.prototype.applyConstraints;\n MediaStreamTrack.prototype.applyConstraints = function(c) {\n if (this.kind === 'audio' && typeof c === 'object') {\n c = JSON.parse(JSON.stringify(c));\n remap(c, 'autoGainControl', 'mozAutoGainControl');\n remap(c, 'noiseSuppression', 'mozNoiseSuppression');\n }\n return nativeApplyConstraints.apply(this, [c]);\n };\n }\n }\n navigator.getUserMedia = function(constraints, onSuccess, onError) {\n if (browserDetails.version < 44) {\n return getUserMedia_(constraints, onSuccess, onError);\n }\n // Replace Firefox 44+'s deprecation warning with unprefixed version.\n utils.deprecated('navigator.getUserMedia',\n 'navigator.mediaDevices.getUserMedia');\n navigator.mediaDevices.getUserMedia(constraints).then(onSuccess, onError);\n };\n};\n","/*\n * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.\n *\n * Use of this source code is governed by a BSD-style license\n * that can be found in the LICENSE file in the root of the source\n * tree.\n */\n'use strict';\nvar utils = require('../utils');\n\nvar safariShim = {\n // TODO: DrAlex, should be here, double check against LayoutTests\n\n // TODO: once the back-end for the mac port is done, add.\n // TODO: check for webkitGTK+\n // shimPeerConnection: function() { },\n\n shimLocalStreamsAPI: function(window) {\n if (typeof window !== 'object' || !window.RTCPeerConnection) {\n return;\n }\n if (!('getLocalStreams' in window.RTCPeerConnection.prototype)) {\n window.RTCPeerConnection.prototype.getLocalStreams = function() {\n if (!this._localStreams) {\n this._localStreams = [];\n }\n return this._localStreams;\n };\n }\n if (!('getStreamById' in window.RTCPeerConnection.prototype)) {\n window.RTCPeerConnection.prototype.getStreamById = function(id) {\n var result = null;\n if (this._localStreams) {\n this._localStreams.forEach(function(stream) {\n if (stream.id === id) {\n result = stream;\n }\n });\n }\n if (this._remoteStreams) {\n this._remoteStreams.forEach(function(stream) {\n if (stream.id === id) {\n result = stream;\n }\n });\n }\n return result;\n };\n }\n if (!('addStream' in window.RTCPeerConnection.prototype)) {\n var _addTrack = window.RTCPeerConnection.prototype.addTrack;\n window.RTCPeerConnection.prototype.addStream = function(stream) {\n if (!this._localStreams) {\n this._localStreams = [];\n }\n if (this._localStreams.indexOf(stream) === -1) {\n this._localStreams.push(stream);\n }\n var self = this;\n stream.getTracks().forEach(function(track) {\n _addTrack.call(self, track, stream);\n });\n };\n\n window.RTCPeerConnection.prototype.addTrack = function(track, stream) {\n if (stream) {\n if (!this._localStreams) {\n this._localStreams = [stream];\n } else if (this._localStreams.indexOf(stream) === -1) {\n this._localStreams.push(stream);\n }\n }\n _addTrack.call(this, track, stream);\n };\n }\n if (!('removeStream' in window.RTCPeerConnection.prototype)) {\n window.RTCPeerConnection.prototype.removeStream = function(stream) {\n if (!this._localStreams) {\n this._localStreams = [];\n }\n var index = this._localStreams.indexOf(stream);\n if (index === -1) {\n return;\n }\n this._localStreams.splice(index, 1);\n var self = this;\n var tracks = stream.getTracks();\n this.getSenders().forEach(function(sender) {\n if (tracks.indexOf(sender.track) !== -1) {\n self.removeTrack(sender);\n }\n });\n };\n }\n },\n shimRemoteStreamsAPI: function(window) {\n if (typeof window !== 'object' || !window.RTCPeerConnection) {\n return;\n }\n if (!('getRemoteStreams' in window.RTCPeerConnection.prototype)) {\n window.RTCPeerConnection.prototype.getRemoteStreams = function() {\n return this._remoteStreams ? this._remoteStreams : [];\n };\n }\n if (!('onaddstream' in window.RTCPeerConnection.prototype)) {\n Object.defineProperty(window.RTCPeerConnection.prototype, 'onaddstream', {\n get: function() {\n return this._onaddstream;\n },\n set: function(f) {\n if (this._onaddstream) {\n this.removeEventListener('addstream', this._onaddstream);\n this.removeEventListener('track', this._onaddstreampoly);\n }\n this.addEventListener('addstream', this._onaddstream = f);\n this.addEventListener('track', this._onaddstreampoly = function(e) {\n var stream = e.streams[0];\n if (!this._remoteStreams) {\n this._remoteStreams = [];\n }\n if (this._remoteStreams.indexOf(stream) >= 0) {\n return;\n }\n this._remoteStreams.push(stream);\n var event = new Event('addstream');\n event.stream = e.streams[0];\n this.dispatchEvent(event);\n }.bind(this));\n }\n });\n }\n },\n shimCallbacksAPI: function(window) {\n if (typeof window !== 'object' || !window.RTCPeerConnection) {\n return;\n }\n var prototype = window.RTCPeerConnection.prototype;\n var createOffer = prototype.createOffer;\n var createAnswer = prototype.createAnswer;\n var setLocalDescription = prototype.setLocalDescription;\n var setRemoteDescription = prototype.setRemoteDescription;\n var addIceCandidate = prototype.addIceCandidate;\n\n prototype.createOffer = function(successCallback, failureCallback) {\n var options = (arguments.length >= 2) ? arguments[2] : arguments[0];\n var promise = createOffer.apply(this, [options]);\n if (!failureCallback) {\n return promise;\n }\n promise.then(successCallback, failureCallback);\n return Promise.resolve();\n };\n\n prototype.createAnswer = function(successCallback, failureCallback) {\n var options = (arguments.length >= 2) ? arguments[2] : arguments[0];\n var promise = createAnswer.apply(this, [options]);\n if (!failureCallback) {\n return promise;\n }\n promise.then(successCallback, failureCallback);\n return Promise.resolve();\n };\n\n var withCallback = function(description, successCallback, failureCallback) {\n var promise = setLocalDescription.apply(this, [description]);\n if (!failureCallback) {\n return promise;\n }\n promise.then(successCallback, failureCallback);\n return Promise.resolve();\n };\n prototype.setLocalDescription = withCallback;\n\n withCallback = function(description, successCallback, failureCallback) {\n var promise = setRemoteDescription.apply(this, [description]);\n if (!failureCallback) {\n return promise;\n }\n promise.then(successCallback, failureCallback);\n return Promise.resolve();\n };\n prototype.setRemoteDescription = withCallback;\n\n withCallback = function(candidate, successCallback, failureCallback) {\n var promise = addIceCandidate.apply(this, [candidate]);\n if (!failureCallback) {\n return promise;\n }\n promise.then(successCallback, failureCallback);\n return Promise.resolve();\n };\n prototype.addIceCandidate = withCallback;\n },\n shimGetUserMedia: function(window) {\n var navigator = window && window.navigator;\n\n if (!navigator.getUserMedia) {\n if (navigator.webkitGetUserMedia) {\n navigator.getUserMedia = navigator.webkitGetUserMedia.bind(navigator);\n } else if (navigator.mediaDevices &&\n navigator.mediaDevices.getUserMedia) {\n navigator.getUserMedia = function(constraints, cb, errcb) {\n navigator.mediaDevices.getUserMedia(constraints)\n .then(cb, errcb);\n }.bind(navigator);\n }\n }\n },\n shimRTCIceServerUrls: function(window) {\n // migrate from non-spec RTCIceServer.url to RTCIceServer.urls\n var OrigPeerConnection = window.RTCPeerConnection;\n window.RTCPeerConnection = function(pcConfig, pcConstraints) {\n if (pcConfig && pcConfig.iceServers) {\n var newIceServers = [];\n for (var i = 0; i < pcConfig.iceServers.length; i++) {\n var server = pcConfig.iceServers[i];\n if (!server.hasOwnProperty('urls') &&\n server.hasOwnProperty('url')) {\n utils.deprecated('RTCIceServer.url', 'RTCIceServer.urls');\n server = JSON.parse(JSON.stringify(server));\n server.urls = server.url;\n delete server.url;\n newIceServers.push(server);\n } else {\n newIceServers.push(pcConfig.iceServers[i]);\n }\n }\n pcConfig.iceServers = newIceServers;\n }\n return new OrigPeerConnection(pcConfig, pcConstraints);\n };\n window.RTCPeerConnection.prototype = OrigPeerConnection.prototype;\n // wrap static methods. Currently just generateCertificate.\n if ('generateCertificate' in window.RTCPeerConnection) {\n Object.defineProperty(window.RTCPeerConnection, 'generateCertificate', {\n get: function() {\n return OrigPeerConnection.generateCertificate;\n }\n });\n }\n },\n shimTrackEventTransceiver: function(window) {\n // Add event.transceiver member over deprecated event.receiver\n if (typeof window === 'object' && window.RTCPeerConnection &&\n ('receiver' in window.RTCTrackEvent.prototype) &&\n // can't check 'transceiver' in window.RTCTrackEvent.prototype, as it is\n // defined for some reason even when window.RTCTransceiver is not.\n !window.RTCTransceiver) {\n Object.defineProperty(window.RTCTrackEvent.prototype, 'transceiver', {\n get: function() {\n return {receiver: this.receiver};\n }\n });\n }\n }\n};\n\n// Expose public methods.\nmodule.exports = {\n shimCallbacksAPI: safariShim.shimCallbacksAPI,\n shimLocalStreamsAPI: safariShim.shimLocalStreamsAPI,\n shimRemoteStreamsAPI: safariShim.shimRemoteStreamsAPI,\n shimGetUserMedia: safariShim.shimGetUserMedia,\n shimRTCIceServerUrls: safariShim.shimRTCIceServerUrls,\n shimTrackEventTransceiver: safariShim.shimTrackEventTransceiver\n // TODO\n // shimPeerConnection: safariShim.shimPeerConnection\n};\n","/*\n * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.\n *\n * Use of this source code is governed by a BSD-style license\n * that can be found in the LICENSE file in the root of the source\n * tree.\n */\n /* eslint-env node */\n'use strict';\n\nvar logDisabled_ = true;\nvar deprecationWarnings_ = true;\n\n// Utility methods.\nvar utils = {\n disableLog: function(bool) {\n if (typeof bool !== 'boolean') {\n return new Error('Argument type: ' + typeof bool +\n '. Please use a boolean.');\n }\n logDisabled_ = bool;\n return (bool) ? 'adapter.js logging disabled' :\n 'adapter.js logging enabled';\n },\n\n /**\n * Disable or enable deprecation warnings\n * @param {!boolean} bool set to true to disable warnings.\n */\n disableWarnings: function(bool) {\n if (typeof bool !== 'boolean') {\n return new Error('Argument type: ' + typeof bool +\n '. Please use a boolean.');\n }\n deprecationWarnings_ = !bool;\n return 'adapter.js deprecation warnings ' + (bool ? 'disabled' : 'enabled');\n },\n\n log: function() {\n if (typeof window === 'object') {\n if (logDisabled_) {\n return;\n }\n if (typeof console !== 'undefined' && typeof console.log === 'function') {\n console.log.apply(console, arguments);\n }\n }\n },\n\n /**\n * Shows a deprecation warning suggesting the modern and spec-compatible API.\n */\n deprecated: function(oldMethod, newMethod) {\n if (!deprecationWarnings_) {\n return;\n }\n console.warn(oldMethod + ' is deprecated, please use ' + newMethod +\n ' instead.');\n },\n\n /**\n * Extract browser version out of the provided user agent string.\n *\n * @param {!string} uastring userAgent string.\n * @param {!string} expr Regular expression used as match criteria.\n * @param {!number} pos position in the version string to be returned.\n * @return {!number} browser version.\n */\n extractVersion: function(uastring, expr, pos) {\n var match = uastring.match(expr);\n return match && match.length >= pos && parseInt(match[pos], 10);\n },\n\n /**\n * Browser detector.\n *\n * @return {object} result containing browser and version\n * properties.\n */\n detectBrowser: function(window) {\n var navigator = window && window.navigator;\n\n // Returned result object.\n var result = {};\n result.browser = null;\n result.version = null;\n\n // Fail early if it's not a browser\n if (typeof window === 'undefined' || !window.navigator) {\n result.browser = 'Not a browser.';\n return result;\n }\n\n // Firefox.\n if (navigator.mozGetUserMedia) {\n result.browser = 'firefox';\n result.version = this.extractVersion(navigator.userAgent,\n /Firefox\\/(\\d+)\\./, 1);\n } else if (navigator.webkitGetUserMedia) {\n // Chrome, Chromium, Webview, Opera, all use the chrome shim for now\n if (window.webkitRTCPeerConnection) {\n result.browser = 'chrome';\n result.version = this.extractVersion(navigator.userAgent,\n /Chrom(e|ium)\\/(\\d+)\\./, 2);\n } else { // Safari (in an unpublished version) or unknown webkit-based.\n if (navigator.userAgent.match(/Version\\/(\\d+).(\\d+)/)) {\n result.browser = 'safari';\n result.version = this.extractVersion(navigator.userAgent,\n /AppleWebKit\\/(\\d+)\\./, 1);\n } else { // unknown webkit-based browser.\n result.browser = 'Unsupported webkit-based browser ' +\n 'with GUM support but no WebRTC support.';\n return result;\n }\n }\n } else if (navigator.mediaDevices &&\n navigator.userAgent.match(/Edge\\/(\\d+).(\\d+)$/)) { // Edge.\n result.browser = 'edge';\n result.version = this.extractVersion(navigator.userAgent,\n /Edge\\/(\\d+).(\\d+)$/, 2);\n } else if (navigator.mediaDevices &&\n navigator.userAgent.match(/AppleWebKit\\/(\\d+)\\./)) {\n // Safari, with webkitGetUserMedia removed.\n result.browser = 'safari';\n result.version = this.extractVersion(navigator.userAgent,\n /AppleWebKit\\/(\\d+)\\./, 1);\n } else { // Default fallthrough: not supported.\n result.browser = 'Not a supported browser.';\n return result;\n }\n\n return result;\n },\n\n};\n\n// Export.\nmodule.exports = {\n log: utils.log,\n deprecated: utils.deprecated,\n disableLog: utils.disableLog,\n disableWarnings: utils.disableWarnings,\n extractVersion: utils.extractVersion,\n shimCreateObjectURL: utils.shimCreateObjectURL,\n detectBrowser: utils.detectBrowser.bind(utils)\n};\n","/*\r\nWildEmitter.js is a slim little event emitter by @henrikjoreteg largely based\r\non @visionmedia's Emitter from UI Kit.\r\n\r\nWhy? I wanted it standalone.\r\n\r\nI also wanted support for wildcard emitters like this:\r\n\r\nemitter.on('*', function (eventName, other, event, payloads) {\r\n\r\n});\r\n\r\nemitter.on('somenamespace*', function (eventName, payloads) {\r\n\r\n});\r\n\r\nPlease note that callbacks triggered by wildcard registered events also get\r\nthe event name as the first argument.\r\n*/\r\n\r\nmodule.exports = WildEmitter;\r\n\r\nfunction WildEmitter() { }\r\n\r\nWildEmitter.mixin = function (constructor) {\r\n var prototype = constructor.prototype || constructor;\r\n\r\n prototype.isWildEmitter= true;\r\n\r\n // Listen on the given `event` with `fn`. Store a group name if present.\r\n prototype.on = function (event, groupName, fn) {\r\n this.callbacks = this.callbacks || {};\r\n var hasGroup = (arguments.length === 3),\r\n group = hasGroup ? arguments[1] : undefined,\r\n func = hasGroup ? arguments[2] : arguments[1];\r\n func._groupName = group;\r\n (this.callbacks[event] = this.callbacks[event] || []).push(func);\r\n return this;\r\n };\r\n\r\n // Adds an `event` listener that will be invoked a single\r\n // time then automatically removed.\r\n prototype.once = function (event, groupName, fn) {\r\n var self = this,\r\n hasGroup = (arguments.length === 3),\r\n group = hasGroup ? arguments[1] : undefined,\r\n func = hasGroup ? arguments[2] : arguments[1];\r\n function on() {\r\n self.off(event, on);\r\n func.apply(this, arguments);\r\n }\r\n this.on(event, group, on);\r\n return this;\r\n };\r\n\r\n // Unbinds an entire group\r\n prototype.releaseGroup = function (groupName) {\r\n this.callbacks = this.callbacks || {};\r\n var item, i, len, handlers;\r\n for (item in this.callbacks) {\r\n handlers = this.callbacks[item];\r\n for (i = 0, len = handlers.length; i < len; i++) {\r\n if (handlers[i]._groupName === groupName) {\r\n //console.log('removing');\r\n // remove it and shorten the array we're looping through\r\n handlers.splice(i, 1);\r\n i--;\r\n len--;\r\n }\r\n }\r\n }\r\n return this;\r\n };\r\n\r\n // Remove the given callback for `event` or all\r\n // registered callbacks.\r\n prototype.off = function (event, fn) {\r\n this.callbacks = this.callbacks || {};\r\n var callbacks = this.callbacks[event],\r\n i;\r\n\r\n if (!callbacks) return this;\r\n\r\n // remove all handlers\r\n if (arguments.length === 1) {\r\n delete this.callbacks[event];\r\n return this;\r\n }\r\n\r\n // remove specific handler\r\n i = callbacks.indexOf(fn);\r\n callbacks.splice(i, 1);\r\n if (callbacks.length === 0) {\r\n delete this.callbacks[event];\r\n }\r\n return this;\r\n };\r\n\r\n /// Emit `event` with the given args.\r\n // also calls any `*` handlers\r\n prototype.emit = function (event) {\r\n this.callbacks = this.callbacks || {};\r\n var args = [].slice.call(arguments, 1),\r\n callbacks = this.callbacks[event],\r\n specialCallbacks = this.getWildcardCallbacks(event),\r\n i,\r\n len,\r\n item,\r\n listeners;\r\n\r\n if (callbacks) {\r\n listeners = callbacks.slice();\r\n for (i = 0, len = listeners.length; i < len; ++i) {\r\n if (!listeners[i]) {\r\n break;\r\n }\r\n listeners[i].apply(this, args);\r\n }\r\n }\r\n\r\n if (specialCallbacks) {\r\n len = specialCallbacks.length;\r\n listeners = specialCallbacks.slice();\r\n for (i = 0, len = listeners.length; i < len; ++i) {\r\n if (!listeners[i]) {\r\n break;\r\n }\r\n listeners[i].apply(this, [event].concat(args));\r\n }\r\n }\r\n\r\n return this;\r\n };\r\n\r\n // Helper for for finding special wildcard event handlers that match the event\r\n prototype.getWildcardCallbacks = function (eventName) {\r\n this.callbacks = this.callbacks || {};\r\n var item,\r\n split,\r\n result = [];\r\n\r\n for (item in this.callbacks) {\r\n split = item.split('*');\r\n if (item === '*' || (split.length === 2 && eventName.slice(0, split[0].length) === split[0])) {\r\n result = result.concat(this.callbacks[item]);\r\n }\r\n }\r\n return result;\r\n };\r\n\r\n};\r\n\r\nWildEmitter.mixin(WildEmitter);\r\n","/*!\n * EventEmitter v4.2.9 - git.io/ee\n * Oliver Caldwell\n * MIT license\n * @preserve\n */\n\n(function () {\n 'use strict';\n\n /**\n * Class for managing events.\n * Can be extended to provide event functionality in other classes.\n *\n * @class EventEmitter Manages event registering and emitting.\n */\n function EventEmitter() {}\n\n // Shortcuts to improve speed and size\n var proto = EventEmitter.prototype;\n var exports = this;\n var originalGlobalValue = exports.EventEmitter;\n\n /**\n * Finds the index of the listener for the event in its storage array.\n *\n * @param {Function[]} listeners Array of listeners to search through.\n * @param {Function} listener Method to look for.\n * @return {Number} Index of the specified listener, -1 if not found\n * @api private\n */\n function indexOfListener(listeners, listener) {\n var i = listeners.length;\n while (i--) {\n if (listeners[i].listener === listener) {\n return i;\n }\n }\n\n return -1;\n }\n\n /**\n * Alias a method while keeping the context correct, to allow for overwriting of target method.\n *\n * @param {String} name The name of the target method.\n * @return {Function} The aliased method\n * @api private\n */\n function alias(name) {\n return function aliasClosure() {\n return this[name].apply(this, arguments);\n };\n }\n\n /**\n * Returns the listener array for the specified event.\n * Will initialise the event object and listener arrays if required.\n * Will return an object if you use a regex search. The object contains keys for each matched event. So /ba[rz]/ might return an object containing bar and baz. But only if you have either defined them with defineEvent or added some listeners to them.\n * Each property in the object response is an array of listener functions.\n *\n * @param {String|RegExp} evt Name of the event to return the listeners from.\n * @return {Function[]|Object} All listener functions for the event.\n */\n proto.getListeners = function getListeners(evt) {\n var events = this._getEvents();\n var response;\n var key;\n\n // Return a concatenated array of all matching events if\n // the selector is a regular expression.\n if (evt instanceof RegExp) {\n response = {};\n for (key in events) {\n if (events.hasOwnProperty(key) && evt.test(key)) {\n response[key] = events[key];\n }\n }\n }\n else {\n response = events[evt] || (events[evt] = []);\n }\n\n return response;\n };\n\n /**\n * Takes a list of listener objects and flattens it into a list of listener functions.\n *\n * @param {Object[]} listeners Raw listener objects.\n * @return {Function[]} Just the listener functions.\n */\n proto.flattenListeners = function flattenListeners(listeners) {\n var flatListeners = [];\n var i;\n\n for (i = 0; i < listeners.length; i += 1) {\n flatListeners.push(listeners[i].listener);\n }\n\n return flatListeners;\n };\n\n /**\n * Fetches the requested listeners via getListeners but will always return the results inside an object. This is mainly for internal use but others may find it useful.\n *\n * @param {String|RegExp} evt Name of the event to return the listeners from.\n * @return {Object} All listener functions for an event in an object.\n */\n proto.getListenersAsObject = function getListenersAsObject(evt) {\n var listeners = this.getListeners(evt);\n var response;\n\n if (listeners instanceof Array) {\n response = {};\n response[evt] = listeners;\n }\n\n return response || listeners;\n };\n\n /**\n * Adds a listener function to the specified event.\n * The listener will not be added if it is a duplicate.\n * If the listener returns true then it will be removed after it is called.\n * If you pass a regular expression as the event name then the listener will be added to all events that match it.\n *\n * @param {String|RegExp} evt Name of the event to attach the listener to.\n * @param {Function} listener Method to be called when the event is emitted. If the function returns true then it will be removed after calling.\n * @return {Object} Current instance of EventEmitter for chaining.\n */\n proto.addListener = function addListener(evt, listener) {\n var listeners = this.getListenersAsObject(evt);\n var listenerIsWrapped = typeof listener === 'object';\n var key;\n\n for (key in listeners) {\n if (listeners.hasOwnProperty(key) && indexOfListener(listeners[key], listener) === -1) {\n listeners[key].push(listenerIsWrapped ? listener : {\n listener: listener,\n once: false\n });\n }\n }\n\n return this;\n };\n\n /**\n * Alias of addListener\n */\n proto.on = alias('addListener');\n\n /**\n * Semi-alias of addListener. It will add a listener that will be\n * automatically removed after its first execution.\n *\n * @param {String|RegExp} evt Name of the event to attach the listener to.\n * @param {Function} listener Method to be called when the event is emitted. If the function returns true then it will be removed after calling.\n * @return {Object} Current instance of EventEmitter for chaining.\n */\n proto.addOnceListener = function addOnceListener(evt, listener) {\n return this.addListener(evt, {\n listener: listener,\n once: true\n });\n };\n\n /**\n * Alias of addOnceListener.\n */\n proto.once = alias('addOnceListener');\n\n /**\n * Defines an event name. This is required if you want to use a regex to add a listener to multiple events at once. If you don't do this then how do you expect it to know what event to add to? Should it just add to every possible match for a regex? No. That is scary and bad.\n * You need to tell it what event names should be matched by a regex.\n *\n * @param {String} evt Name of the event to create.\n * @return {Object} Current instance of EventEmitter for chaining.\n */\n proto.defineEvent = function defineEvent(evt) {\n this.getListeners(evt);\n return this;\n };\n\n /**\n * Uses defineEvent to define multiple events.\n *\n * @param {String[]} evts An array of event names to define.\n * @return {Object} Current instance of EventEmitter for chaining.\n */\n proto.defineEvents = function defineEvents(evts) {\n for (var i = 0; i < evts.length; i += 1) {\n this.defineEvent(evts[i]);\n }\n return this;\n };\n\n /**\n * Removes a listener function from the specified event.\n * When passed a regular expression as the event name, it will remove the listener from all events that match it.\n *\n * @param {String|RegExp} evt Name of the event to remove the listener from.\n * @param {Function} listener Method to remove from the event.\n * @return {Object} Current instance of EventEmitter for chaining.\n */\n proto.removeListener = function removeListener(evt, listener) {\n var listeners = this.getListenersAsObject(evt);\n var index;\n var key;\n\n for (key in listeners) {\n if (listeners.hasOwnProperty(key)) {\n index = indexOfListener(listeners[key], listener);\n\n if (index !== -1) {\n listeners[key].splice(index, 1);\n }\n }\n }\n\n return this;\n };\n\n /**\n * Alias of removeListener\n */\n proto.off = alias('removeListener');\n\n /**\n * Adds listeners in bulk using the manipulateListeners method.\n * If you pass an object as the second argument you can add to multiple events at once. The object should contain key value pairs of events and listeners or listener arrays. You can also pass it an event name and an array of listeners to be added.\n * You can also pass it a regular expression to add the array of listeners to all events that match it.\n * Yeah, this function does quite a bit. That's probably a bad thing.\n *\n * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to add to multiple events at once.\n * @param {Function[]} [listeners] An optional array of listener functions to add.\n * @return {Object} Current instance of EventEmitter for chaining.\n */\n proto.addListeners = function addListeners(evt, listeners) {\n // Pass through to manipulateListeners\n return this.manipulateListeners(false, evt, listeners);\n };\n\n /**\n * Removes listeners in bulk using the manipulateListeners method.\n * If you pass an object as the second argument you can remove from multiple events at once. The object should contain key value pairs of events and listeners or listener arrays.\n * You can also pass it an event name and an array of listeners to be removed.\n * You can also pass it a regular expression to remove the listeners from all events that match it.\n *\n * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to remove from multiple events at once.\n * @param {Function[]} [listeners] An optional array of listener functions to remove.\n * @return {Object} Current instance of EventEmitter for chaining.\n */\n proto.removeListeners = function removeListeners(evt, listeners) {\n // Pass through to manipulateListeners\n return this.manipulateListeners(true, evt, listeners);\n };\n\n /**\n * Edits listeners in bulk. The addListeners and removeListeners methods both use this to do their job. You should really use those instead, this is a little lower level.\n * The first argument will determine if the listeners are removed (true) or added (false).\n * If you pass an object as the second argument you can add/remove from multiple events at once. The object should contain key value pairs of events and listeners or listener arrays.\n * You can also pass it an event name and an array of listeners to be added/removed.\n * You can also pass it a regular expression to manipulate the listeners of all events that match it.\n *\n * @param {Boolean} remove True if you want to remove listeners, false if you want to add.\n * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to add/remove from multiple events at once.\n * @param {Function[]} [listeners] An optional array of listener functions to add/remove.\n * @return {Object} Current instance of EventEmitter for chaining.\n */\n proto.manipulateListeners = function manipulateListeners(remove, evt, listeners) {\n var i;\n var value;\n var single = remove ? this.removeListener : this.addListener;\n var multiple = remove ? this.removeListeners : this.addListeners;\n\n // If evt is an object then pass each of its properties to this method\n if (typeof evt === 'object' && !(evt instanceof RegExp)) {\n for (i in evt) {\n if (evt.hasOwnProperty(i) && (value = evt[i])) {\n // Pass the single listener straight through to the singular method\n if (typeof value === 'function') {\n single.call(this, i, value);\n }\n else {\n // Otherwise pass back to the multiple function\n multiple.call(this, i, value);\n }\n }\n }\n }\n else {\n // So evt must be a string\n // And listeners must be an array of listeners\n // Loop over it and pass each one to the multiple method\n i = listeners.length;\n while (i--) {\n single.call(this, evt, listeners[i]);\n }\n }\n\n return this;\n };\n\n /**\n * Removes all listeners from a specified event.\n * If you do not specify an event then all listeners will be removed.\n * That means every event will be emptied.\n * You can also pass a regex to remove all events that match it.\n *\n * @param {String|RegExp} [evt] Optional name of the event to remove all listeners for. Will remove from every event if not passed.\n * @return {Object} Current instance of EventEmitter for chaining.\n */\n proto.removeEvent = function removeEvent(evt) {\n var type = typeof evt;\n var events = this._getEvents();\n var key;\n\n // Remove different things depending on the state of evt\n if (type === 'string') {\n // Remove all listeners for the specified event\n delete events[evt];\n }\n else if (evt instanceof RegExp) {\n // Remove all events matching the regex.\n for (key in events) {\n if (events.hasOwnProperty(key) && evt.test(key)) {\n delete events[key];\n }\n }\n }\n else {\n // Remove all listeners in all events\n delete this._events;\n }\n\n return this;\n };\n\n /**\n * Alias of removeEvent.\n *\n * Added to mirror the node API.\n */\n proto.removeAllListeners = alias('removeEvent');\n\n /**\n * Emits an event of your choice.\n * When emitted, every listener attached to that event will be executed.\n * If you pass the optional argument array then those arguments will be passed to every listener upon execution.\n * Because it uses `apply`, your array of arguments will be passed as if you wrote them out separately.\n * So they will not arrive within the array on the other side, they will be separate.\n * You can also pass a regular expression to emit to all events that match it.\n *\n * @param {String|RegExp} evt Name of the event to emit and execute listeners for.\n * @param {Array} [args] Optional array of arguments to be passed to each listener.\n * @return {Object} Current instance of EventEmitter for chaining.\n */\n proto.emitEvent = function emitEvent(evt, args) {\n var listeners = this.getListenersAsObject(evt);\n var listener;\n var i;\n var key;\n var response;\n\n for (key in listeners) {\n if (listeners.hasOwnProperty(key)) {\n i = listeners[key].length;\n\n while (i--) {\n // If the listener returns true then it shall be removed from the event\n // The function is executed either with a basic call or an apply if there is an args array\n listener = listeners[key][i];\n\n if (listener.once === true) {\n this.removeListener(evt, listener.listener);\n }\n\n response = listener.listener.apply(this, args || []);\n\n if (response === this._getOnceReturnValue()) {\n this.removeListener(evt, listener.listener);\n }\n }\n }\n }\n\n return this;\n };\n\n /**\n * Alias of emitEvent\n */\n proto.trigger = alias('emitEvent');\n\n /**\n * Subtly different from emitEvent in that it will pass its arguments on to the listeners, as opposed to taking a single array of arguments to pass on.\n * As with emitEvent, you can pass a regex in place of the event name to emit to all events that match it.\n *\n * @param {String|RegExp} evt Name of the event to emit and execute listeners for.\n * @param {...*} Optional additional arguments to be passed to each listener.\n * @return {Object} Current instance of EventEmitter for chaining.\n */\n proto.emit = function emit(evt) {\n var args = Array.prototype.slice.call(arguments, 1);\n return this.emitEvent(evt, args);\n };\n\n /**\n * Sets the current value to check against when executing listeners. If a\n * listeners return value matches the one set here then it will be removed\n * after execution. This value defaults to true.\n *\n * @param {*} value The new value to check for when executing listeners.\n * @return {Object} Current instance of EventEmitter for chaining.\n */\n proto.setOnceReturnValue = function setOnceReturnValue(value) {\n this._onceReturnValue = value;\n return this;\n };\n\n /**\n * Fetches the current value to check against when executing listeners. If\n * the listeners return value matches this one then it should be removed\n * automatically. It will return true by default.\n *\n * @return {*|Boolean} The current value to check for or the default, true.\n * @api private\n */\n proto._getOnceReturnValue = function _getOnceReturnValue() {\n if (this.hasOwnProperty('_onceReturnValue')) {\n return this._onceReturnValue;\n }\n else {\n return true;\n }\n };\n\n /**\n * Fetches the events object and creates one if required.\n *\n * @return {Object} The events storage object.\n * @api private\n */\n proto._getEvents = function _getEvents() {\n return this._events || (this._events = {});\n };\n\n /**\n * Reverts the global {@link EventEmitter} to its previous value and returns a reference to this version.\n *\n * @return {Function} Non conflicting EventEmitter class.\n */\n EventEmitter.noConflict = function noConflict() {\n exports.EventEmitter = originalGlobalValue;\n return EventEmitter;\n };\n\n // Expose the class either via AMD, CommonJS or the global object\n if (typeof define === 'function' && define.amd) {\n define(function () {\n return EventEmitter;\n });\n }\n else if (typeof module === 'object' && module.exports){\n module.exports = EventEmitter;\n }\n else {\n exports.EventEmitter = EventEmitter;\n }\n}.call(this));\n","function Mapper()\n{\n var sources = {};\n\n\n this.forEach = function(callback)\n {\n for(var key in sources)\n {\n var source = sources[key];\n\n for(var key2 in source)\n callback(source[key2]);\n };\n };\n\n this.get = function(id, source)\n {\n var ids = sources[source];\n if(ids == undefined)\n return undefined;\n\n return ids[id];\n };\n\n this.remove = function(id, source)\n {\n var ids = sources[source];\n if(ids == undefined)\n return;\n\n delete ids[id];\n\n // Check it's empty\n for(var i in ids){return false}\n\n delete sources[source];\n };\n\n this.set = function(value, id, source)\n {\n if(value == undefined)\n return this.remove(id, source);\n\n var ids = sources[source];\n if(ids == undefined)\n sources[source] = ids = {};\n\n ids[id] = value;\n };\n};\n\n\nMapper.prototype.pop = function(id, source)\n{\n var value = this.get(id, source);\n if(value == undefined)\n return undefined;\n\n this.remove(id, source);\n\n return value;\n};\n\n\nmodule.exports = Mapper;\n","/*\n * (C) Copyright 2014 Kurento (http://kurento.org/)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n */\n\nvar JsonRpcClient = require('./jsonrpcclient');\n\n\nexports.JsonRpcClient = JsonRpcClient;","/*\n * (C) Copyright 2014 Kurento (http://kurento.org/)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n */\n\nvar RpcBuilder = require('../');\nvar WebSocketWithReconnection = require('./transports/webSocketWithReconnection');\n\nDate.now = Date.now || function() {\n return +new Date;\n};\n\nvar PING_INTERVAL = 5000;\n\nvar RECONNECTING = 'RECONNECTING';\nvar CONNECTED = 'CONNECTED';\nvar DISCONNECTED = 'DISCONNECTED';\n\nvar Logger = console;\n\n/**\n *\n * heartbeat: interval in ms for each heartbeat message,\n * sendCloseMessage : true / false, before closing the connection, it sends a closeSession message\n *
\n * ws : {\n * \turi : URI to conntect to,\n *  useSockJS : true (use SockJS) / false (use WebSocket) by default,\n * \tonconnected : callback method to invoke when connection is successful,\n * \tondisconnect : callback method to invoke when the connection is lost,\n * \tonreconnecting : callback method to invoke when the client is reconnecting,\n * \tonreconnected : callback method to invoke when the client succesfully reconnects,\n * \tonerror : callback method to invoke when there is an error\n * },\n * rpc : {\n * \trequestTimeout : timeout for a request,\n * \tsessionStatusChanged: callback method for changes in session status,\n * \tmediaRenegotiation: mediaRenegotiation\n * }\n * 
\n */\nfunction JsonRpcClient(configuration) {\n\n var self = this;\n\n var wsConfig = configuration.ws;\n\n var notReconnectIfNumLessThan = -1;\n\n var pingNextNum = 0;\n var enabledPings = true;\n var pingPongStarted = false;\n var pingInterval;\n\n var status = DISCONNECTED;\n\n var onreconnecting = wsConfig.onreconnecting;\n var onreconnected = wsConfig.onreconnected;\n var onconnected = wsConfig.onconnected;\n var onerror = wsConfig.onerror;\n\n configuration.rpc.pull = function(params, request) {\n request.reply(null, \"push\");\n }\n\n wsConfig.onreconnecting = function() {\n Logger.debug(\"--------- ONRECONNECTING -----------\");\n if (status === RECONNECTING) {\n Logger.error(\"Websocket already in RECONNECTING state when receiving a new ONRECONNECTING message. Ignoring it\");\n return;\n }\n\n status = RECONNECTING;\n if (onreconnecting) {\n onreconnecting();\n }\n }\n\n wsConfig.onreconnected = function() {\n Logger.debug(\"--------- ONRECONNECTED -----------\");\n if (status === CONNECTED) {\n Logger.error(\"Websocket already in CONNECTED state when receiving a new ONRECONNECTED message. Ignoring it\");\n return;\n }\n status = CONNECTED;\n\n enabledPings = true;\n updateNotReconnectIfLessThan();\n usePing();\n\n if (onreconnected) {\n onreconnected();\n }\n }\n\n wsConfig.onconnected = function() {\n Logger.debug(\"--------- ONCONNECTED -----------\");\n if (status === CONNECTED) {\n Logger.error(\"Websocket already in CONNECTED state when receiving a new ONCONNECTED message. Ignoring it\");\n return;\n }\n status = CONNECTED;\n\n enabledPings = true;\n usePing();\n\n if (onconnected) {\n onconnected();\n }\n }\n\n wsConfig.onerror = function(error) {\n Logger.debug(\"--------- ONERROR -----------\");\n\n status = DISCONNECTED;\n\n if (onerror) {\n onerror(error);\n }\n }\n\n var ws = new WebSocketWithReconnection(wsConfig);\n\n Logger.debug('Connecting websocket to URI: ' + wsConfig.uri);\n\n var rpcBuilderOptions = {\n request_timeout: configuration.rpc.requestTimeout,\n ping_request_timeout: configuration.rpc.heartbeatRequestTimeout\n };\n\n var rpc = new RpcBuilder(RpcBuilder.packers.JsonRPC, rpcBuilderOptions, ws,\n function(request) {\n\n Logger.debug('Received request: ' + JSON.stringify(request));\n\n try {\n var func = configuration.rpc[request.method];\n\n if (func === undefined) {\n Logger.error(\"Method \" + request.method + \" not registered in client\");\n } else {\n func(request.params, request);\n }\n } catch (err) {\n Logger.error('Exception processing request: ' + JSON.stringify(request));\n Logger.error(err);\n }\n });\n\n this.send = function(method, params, callback) {\n if (method !== 'ping') {\n Logger.debug('Request: method:' + method + \" params:\" + JSON.stringify(params));\n }\n\n var requestTime = Date.now();\n\n rpc.encode(method, params, function(error, result) {\n if (error) {\n try {\n Logger.error(\"ERROR:\" + error.message + \" in Request: method:\" +\n method + \" params:\" + JSON.stringify(params) + \" request:\" +\n error.request);\n if (error.data) {\n Logger.error(\"ERROR DATA:\" + JSON.stringify(error.data));\n }\n } catch (e) {}\n error.requestTime = requestTime;\n }\n if (callback) {\n if (result != undefined && result.value !== 'pong') {\n Logger.debug('Response: ' + JSON.stringify(result));\n }\n callback(error, result);\n }\n });\n }\n\n function updateNotReconnectIfLessThan() {\n Logger.debug(\"notReconnectIfNumLessThan = \" + pingNextNum + ' (old=' +\n notReconnectIfNumLessThan + ')');\n notReconnectIfNumLessThan = pingNextNum;\n }\n\n function sendPing() {\n if (enabledPings) {\n var params = null;\n if (pingNextNum == 0 || pingNextNum == notReconnectIfNumLessThan) {\n params = {\n interval: configuration.heartbeat || PING_INTERVAL\n };\n }\n pingNextNum++;\n\n self.send('ping', params, (function(pingNum) {\n return function(error, result) {\n if (error) {\n Logger.debug(\"Error in ping request #\" + pingNum + \" (\" +\n error.message + \")\");\n if (pingNum > notReconnectIfNumLessThan) {\n enabledPings = false;\n updateNotReconnectIfLessThan();\n Logger.debug(\"Server did not respond to ping message #\" +\n pingNum + \". Reconnecting... \");\n ws.reconnectWs();\n }\n }\n }\n })(pingNextNum));\n } else {\n Logger.debug(\"Trying to send ping, but ping is not enabled\");\n }\n }\n\n /*\n * If configuration.hearbeat has any value, the ping-pong will work with the interval\n * of configuration.hearbeat\n */\n function usePing() {\n if (!pingPongStarted) {\n Logger.debug(\"Starting ping (if configured)\")\n pingPongStarted = true;\n\n if (configuration.heartbeat != undefined) {\n pingInterval = setInterval(sendPing, configuration.heartbeat);\n sendPing();\n }\n }\n }\n\n this.close = function() {\n Logger.debug(\"Closing jsonRpcClient explicitly by client\");\n\n if (pingInterval != undefined) {\n Logger.debug(\"Clearing ping interval\");\n clearInterval(pingInterval);\n }\n pingPongStarted = false;\n enabledPings = false;\n\n if (configuration.sendCloseMessage) {\n Logger.debug(\"Sending close message\")\n this.send('closeSession', null, function(error, result) {\n if (error) {\n Logger.error(\"Error sending close message: \" + JSON.stringify(error));\n }\n ws.close();\n });\n } else {\n\t\t\tws.close();\n }\n }\n\n // This method is only for testing\n this.forceClose = function(millis) {\n ws.forceClose(millis);\n }\n\n this.reconnect = function() {\n ws.reconnectWs();\n }\n}\n\n\nmodule.exports = JsonRpcClient;\n","/*\n * (C) Copyright 2014 Kurento (http://kurento.org/)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n */\n\nvar WebSocketWithReconnection = require('./webSocketWithReconnection');\n\n\nexports.WebSocketWithReconnection = WebSocketWithReconnection;","/*\n * (C) Copyright 2013-2015 Kurento (http://kurento.org/)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n\"use strict\";\n\nvar BrowserWebSocket = global.WebSocket || global.MozWebSocket;\n\nvar Logger = console;\n\n/**\n * Get either the `WebSocket` or `MozWebSocket` globals\n * in the browser or try to resolve WebSocket-compatible\n * interface exposed by `ws` for Node-like environment.\n */\n\n/*var WebSocket = BrowserWebSocket;\nif (!WebSocket && typeof window === 'undefined') {\n try {\n WebSocket = require('ws');\n } catch (e) { }\n}*/\n\n//var SockJS = require('sockjs-client');\n\nvar MAX_RETRIES = 2000; // Forever...\nvar RETRY_TIME_MS = 3000; // FIXME: Implement exponential wait times...\n\nvar CONNECTING = 0;\nvar OPEN = 1;\nvar CLOSING = 2;\nvar CLOSED = 3;\n\n/*\nconfig = {\n\t\turi : wsUri,\n\t\tuseSockJS : true (use SockJS) / false (use WebSocket) by default,\n\t\tonconnected : callback method to invoke when connection is successful,\n\t\tondisconnect : callback method to invoke when the connection is lost,\n\t\tonreconnecting : callback method to invoke when the client is reconnecting,\n\t\tonreconnected : callback method to invoke when the client succesfully reconnects,\n\t};\n*/\nfunction WebSocketWithReconnection(config) {\n\n var closing = false;\n var registerMessageHandler;\n var wsUri = config.uri;\n var useSockJS = config.useSockJS;\n var reconnecting = false;\n\n var forcingDisconnection = false;\n\n var ws;\n\n if (useSockJS) {\n ws = new SockJS(wsUri);\n } else {\n ws = new WebSocket(wsUri);\n }\n\n ws.onopen = function() {\n logConnected(ws, wsUri);\n if (config.onconnected) {\n config.onconnected();\n }\n };\n\n ws.onerror = function(error) {\n Logger.error(\"Could not connect to \" + wsUri + \" (invoking onerror if defined)\", error);\n if (config.onerror) {\n config.onerror(error);\n }\n };\n\n function logConnected(ws, wsUri) {\n try {\n Logger.debug(\"WebSocket connected to \" + wsUri);\n } catch (e) {\n Logger.error(e);\n }\n }\n\n var reconnectionOnClose = function() {\n if (ws.readyState === CLOSED) {\n if (closing) {\n Logger.debug(\"Connection closed by user\");\n } else {\n Logger.debug(\"Connection closed unexpectecly. Reconnecting...\");\n reconnectToSameUri(MAX_RETRIES, 1);\n }\n } else {\n Logger.debug(\"Close callback from previous websocket. Ignoring it\");\n }\n };\n\n ws.onclose = reconnectionOnClose;\n\n function reconnectToSameUri(maxRetries, numRetries) {\n Logger.debug(\"reconnectToSameUri (attempt #\" + numRetries + \", max=\" + maxRetries + \")\");\n\n if (numRetries === 1) {\n if (reconnecting) {\n Logger.warn(\"Trying to reconnectToNewUri when reconnecting... Ignoring this reconnection.\")\n return;\n } else {\n reconnecting = true;\n }\n\n if (config.onreconnecting) {\n config.onreconnecting();\n }\n }\n\n if (forcingDisconnection) {\n reconnectToNewUri(maxRetries, numRetries, wsUri);\n\n } else {\n if (config.newWsUriOnReconnection) {\n config.newWsUriOnReconnection(function(error, newWsUri) {\n\n if (error) {\n Logger.debug(error);\n setTimeout(function() {\n reconnectToSameUri(maxRetries, numRetries + 1);\n }, RETRY_TIME_MS);\n } else {\n reconnectToNewUri(maxRetries, numRetries, newWsUri);\n }\n })\n } else {\n reconnectToNewUri(maxRetries, numRetries, wsUri);\n }\n }\n }\n\n // TODO Test retries. How to force not connection?\n function reconnectToNewUri(maxRetries, numRetries, reconnectWsUri) {\n Logger.debug(\"Reconnection attempt #\" + numRetries);\n\n ws.close();\n\n wsUri = reconnectWsUri || wsUri;\n\n var newWs;\n if (useSockJS) {\n newWs = new SockJS(wsUri);\n } else {\n newWs = new WebSocket(wsUri);\n }\n\n newWs.onopen = function() {\n Logger.debug(\"Reconnected after \" + numRetries + \" attempts...\");\n logConnected(newWs, wsUri);\n reconnecting = false;\n registerMessageHandler();\n if (config.onreconnected()) {\n config.onreconnected();\n }\n\n newWs.onclose = reconnectionOnClose;\n };\n\n var onErrorOrClose = function(error) {\n Logger.warn(\"Reconnection error: \", error);\n\n if (numRetries === maxRetries) {\n if (config.ondisconnect) {\n config.ondisconnect();\n }\n } else {\n setTimeout(function() {\n reconnectToSameUri(maxRetries, numRetries + 1);\n }, RETRY_TIME_MS);\n }\n };\n\n newWs.onerror = onErrorOrClose;\n\n ws = newWs;\n }\n\n this.close = function() {\n closing = true;\n ws.close();\n };\n\n\n // This method is only for testing\n this.forceClose = function(millis) {\n Logger.debug(\"Testing: Force WebSocket close\");\n\n if (millis) {\n Logger.debug(\"Testing: Change wsUri for \" + millis + \" millis to simulate net failure\");\n var goodWsUri = wsUri;\n wsUri = \"wss://21.234.12.34.4:443/\";\n\n forcingDisconnection = true;\n\n setTimeout(function() {\n Logger.debug(\"Testing: Recover good wsUri \" + goodWsUri);\n wsUri = goodWsUri;\n\n forcingDisconnection = false;\n\n }, millis);\n }\n\n ws.close();\n };\n\n this.reconnectWs = function() {\n Logger.debug(\"reconnectWs\");\n reconnectToSameUri(MAX_RETRIES, 1, wsUri);\n };\n\n this.send = function(message) {\n ws.send(message);\n };\n\n this.addEventListener = function(type, callback) {\n registerMessageHandler = function() {\n ws.addEventListener(type, callback);\n };\n\n registerMessageHandler();\n };\n}\n\nmodule.exports = WebSocketWithReconnection;\n","/*\n * (C) Copyright 2014 Kurento (http://kurento.org/)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n */\n\n\nvar defineProperty_IE8 = false\nif(Object.defineProperty)\n{\n try\n {\n Object.defineProperty({}, \"x\", {});\n }\n catch(e)\n {\n defineProperty_IE8 = true\n }\n}\n\n// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind\nif (!Function.prototype.bind) {\n Function.prototype.bind = function(oThis) {\n if (typeof this !== 'function') {\n // closest thing possible to the ECMAScript 5\n // internal IsCallable function\n throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable');\n }\n\n var aArgs = Array.prototype.slice.call(arguments, 1),\n fToBind = this,\n fNOP = function() {},\n fBound = function() {\n return fToBind.apply(this instanceof fNOP && oThis\n ? this\n : oThis,\n aArgs.concat(Array.prototype.slice.call(arguments)));\n };\n\n fNOP.prototype = this.prototype;\n fBound.prototype = new fNOP();\n\n return fBound;\n };\n}\n\n\nvar EventEmitter = require('events').EventEmitter;\n\nvar inherits = require('inherits');\n\nvar packers = require('./packers');\nvar Mapper = require('./Mapper');\n\n\nvar BASE_TIMEOUT = 5000;\n\n\nfunction unifyResponseMethods(responseMethods)\n{\n if(!responseMethods) return {};\n\n for(var key in responseMethods)\n {\n var value = responseMethods[key];\n\n if(typeof value == 'string')\n responseMethods[key] =\n {\n response: value\n }\n };\n\n return responseMethods;\n};\n\nfunction unifyTransport(transport)\n{\n if(!transport) return;\n\n // Transport as a function\n if(transport instanceof Function)\n return {send: transport};\n\n // WebSocket & DataChannel\n if(transport.send instanceof Function)\n return transport;\n\n // Message API (Inter-window & WebWorker)\n if(transport.postMessage instanceof Function)\n {\n transport.send = transport.postMessage;\n return transport;\n }\n\n // Stream API\n if(transport.write instanceof Function)\n {\n transport.send = transport.write;\n return transport;\n }\n\n // Transports that only can receive messages, but not send\n if(transport.onmessage !== undefined) return;\n if(transport.pause instanceof Function) return;\n\n throw new SyntaxError(\"Transport is not a function nor a valid object\");\n};\n\n\n/**\n * Representation of a RPC notification\n *\n * @class\n *\n * @constructor\n *\n * @param {String} method -method of the notification\n * @param params - parameters of the notification\n */\nfunction RpcNotification(method, params)\n{\n if(defineProperty_IE8)\n {\n this.method = method\n this.params = params\n }\n else\n {\n Object.defineProperty(this, 'method', {value: method, enumerable: true});\n Object.defineProperty(this, 'params', {value: params, enumerable: true});\n }\n};\n\n\n/**\n * @class\n *\n * @constructor\n *\n * @param {object} packer\n *\n * @param {object} [options]\n *\n * @param {object} [transport]\n *\n * @param {Function} [onRequest]\n */\nfunction RpcBuilder(packer, options, transport, onRequest)\n{\n var self = this;\n\n if(!packer)\n throw new SyntaxError('Packer is not defined');\n\n if(!packer.pack || !packer.unpack)\n throw new SyntaxError('Packer is invalid');\n\n var responseMethods = unifyResponseMethods(packer.responseMethods);\n\n\n if(options instanceof Function)\n {\n if(transport != undefined)\n throw new SyntaxError(\"There can't be parameters after onRequest\");\n\n onRequest = options;\n transport = undefined;\n options = undefined;\n };\n\n if(options && options.send instanceof Function)\n {\n if(transport && !(transport instanceof Function))\n throw new SyntaxError(\"Only a function can be after transport\");\n\n onRequest = transport;\n transport = options;\n options = undefined;\n };\n\n if(transport instanceof Function)\n {\n if(onRequest != undefined)\n throw new SyntaxError(\"There can't be parameters after onRequest\");\n\n onRequest = transport;\n transport = undefined;\n };\n\n if(transport && transport.send instanceof Function)\n if(onRequest && !(onRequest instanceof Function))\n throw new SyntaxError(\"Only a function can be after transport\");\n\n options = options || {};\n\n\n EventEmitter.call(this);\n\n if(onRequest)\n this.on('request', onRequest);\n\n\n if(defineProperty_IE8)\n this.peerID = options.peerID\n else\n Object.defineProperty(this, 'peerID', {value: options.peerID});\n\n var max_retries = options.max_retries || 0;\n\n\n function transportMessage(event)\n {\n self.decode(event.data || event);\n };\n\n this.getTransport = function()\n {\n return transport;\n }\n this.setTransport = function(value)\n {\n // Remove listener from old transport\n if(transport)\n {\n // W3C transports\n if(transport.removeEventListener)\n transport.removeEventListener('message', transportMessage);\n\n // Node.js Streams API\n else if(transport.removeListener)\n transport.removeListener('data', transportMessage);\n };\n\n // Set listener on new transport\n if(value)\n {\n // W3C transports\n if(value.addEventListener)\n value.addEventListener('message', transportMessage);\n\n // Node.js Streams API\n else if(value.addListener)\n value.addListener('data', transportMessage);\n };\n\n transport = unifyTransport(value);\n }\n\n if(!defineProperty_IE8)\n Object.defineProperty(this, 'transport',\n {\n get: this.getTransport.bind(this),\n set: this.setTransport.bind(this)\n })\n\n this.setTransport(transport);\n\n\n var request_timeout = options.request_timeout || BASE_TIMEOUT;\n var ping_request_timeout = options.ping_request_timeout || request_timeout;\n var response_timeout = options.response_timeout || BASE_TIMEOUT;\n var duplicates_timeout = options.duplicates_timeout || BASE_TIMEOUT;\n\n\n var requestID = 0;\n\n var requests = new Mapper();\n var responses = new Mapper();\n var processedResponses = new Mapper();\n\n var message2Key = {};\n\n\n /**\n * Store the response to prevent to process duplicate request later\n */\n function storeResponse(message, id, dest)\n {\n var response =\n {\n message: message,\n /** Timeout to auto-clean old responses */\n timeout: setTimeout(function()\n {\n responses.remove(id, dest);\n },\n response_timeout)\n };\n\n responses.set(response, id, dest);\n };\n\n /**\n * Store the response to ignore duplicated messages later\n */\n function storeProcessedResponse(ack, from)\n {\n var timeout = setTimeout(function()\n {\n processedResponses.remove(ack, from);\n },\n duplicates_timeout);\n\n processedResponses.set(timeout, ack, from);\n };\n\n\n /**\n * Representation of a RPC request\n *\n * @class\n * @extends RpcNotification\n *\n * @constructor\n *\n * @param {String} method -method of the notification\n * @param params - parameters of the notification\n * @param {Integer} id - identifier of the request\n * @param [from] - source of the notification\n */\n function RpcRequest(method, params, id, from, transport)\n {\n RpcNotification.call(this, method, params);\n\n this.getTransport = function()\n {\n return transport;\n }\n this.setTransport = function(value)\n {\n transport = unifyTransport(value);\n }\n\n if(!defineProperty_IE8)\n Object.defineProperty(this, 'transport',\n {\n get: this.getTransport.bind(this),\n set: this.setTransport.bind(this)\n })\n\n var response = responses.get(id, from);\n\n /**\n * @constant {Boolean} duplicated\n */\n if(!(transport || self.getTransport()))\n {\n if(defineProperty_IE8)\n this.duplicated = Boolean(response)\n else\n Object.defineProperty(this, 'duplicated',\n {\n value: Boolean(response)\n });\n }\n\n var responseMethod = responseMethods[method];\n\n this.pack = packer.pack.bind(packer, this, id)\n\n /**\n * Generate a response to this request\n *\n * @param {Error} [error]\n * @param {*} [result]\n *\n * @returns {string}\n */\n this.reply = function(error, result, transport)\n {\n // Fix optional parameters\n if(error instanceof Function || error && error.send instanceof Function)\n {\n if(result != undefined)\n throw new SyntaxError(\"There can't be parameters after callback\");\n\n transport = error;\n result = null;\n error = undefined;\n }\n\n else if(result instanceof Function\n || result && result.send instanceof Function)\n {\n if(transport != undefined)\n throw new SyntaxError(\"There can't be parameters after callback\");\n\n transport = result;\n result = null;\n };\n\n transport = unifyTransport(transport);\n\n // Duplicated request, remove old response timeout\n if(response)\n clearTimeout(response.timeout);\n\n if(from != undefined)\n {\n if(error)\n error.dest = from;\n\n if(result)\n result.dest = from;\n };\n\n var message;\n\n // New request or overriden one, create new response with provided data\n if(error || result != undefined)\n {\n if(self.peerID != undefined)\n {\n if(error)\n error.from = self.peerID;\n else\n result.from = self.peerID;\n }\n\n // Protocol indicates that responses has own request methods\n if(responseMethod)\n {\n if(responseMethod.error == undefined && error)\n message =\n {\n error: error\n };\n\n else\n {\n var method = error\n ? responseMethod.error\n : responseMethod.response;\n\n message =\n {\n method: method,\n params: error || result\n };\n }\n }\n else\n message =\n {\n error: error,\n result: result\n };\n\n message = packer.pack(message, id);\n }\n\n // Duplicate & not-overriden request, re-send old response\n else if(response)\n message = response.message;\n\n // New empty reply, response null value\n else\n message = packer.pack({result: null}, id);\n\n // Store the response to prevent to process a duplicated request later\n storeResponse(message, id, from);\n\n // Return the stored response so it can be directly send back\n transport = transport || this.getTransport() || self.getTransport();\n\n if(transport)\n return transport.send(message);\n\n return message;\n }\n };\n inherits(RpcRequest, RpcNotification);\n\n\n function cancel(message)\n {\n var key = message2Key[message];\n if(!key) return;\n\n delete message2Key[message];\n\n var request = requests.pop(key.id, key.dest);\n if(!request) return;\n\n clearTimeout(request.timeout);\n\n // Start duplicated responses timeout\n storeProcessedResponse(key.id, key.dest);\n };\n\n /**\n * Allow to cancel a request and don't wait for a response\n *\n * If `message` is not given, cancel all the request\n */\n this.cancel = function(message)\n {\n if(message) return cancel(message);\n\n for(var message in message2Key)\n cancel(message);\n };\n\n\n this.close = function()\n {\n // Prevent to receive new messages\n var transport = this.getTransport();\n if(transport && transport.close)\n transport.close();\n\n // Request & processed responses\n this.cancel();\n\n processedResponses.forEach(clearTimeout);\n\n // Responses\n responses.forEach(function(response)\n {\n clearTimeout(response.timeout);\n });\n };\n\n\n /**\n * Generates and encode a JsonRPC 2.0 message\n *\n * @param {String} method -method of the notification\n * @param params - parameters of the notification\n * @param [dest] - destination of the notification\n * @param {object} [transport] - transport where to send the message\n * @param [callback] - function called when a response to this request is\n * received. If not defined, a notification will be send instead\n *\n * @returns {string} A raw JsonRPC 2.0 request or notification string\n */\n this.encode = function(method, params, dest, transport, callback)\n {\n // Fix optional parameters\n if(params instanceof Function)\n {\n if(dest != undefined)\n throw new SyntaxError(\"There can't be parameters after callback\");\n\n callback = params;\n transport = undefined;\n dest = undefined;\n params = undefined;\n }\n\n else if(dest instanceof Function)\n {\n if(transport != undefined)\n throw new SyntaxError(\"There can't be parameters after callback\");\n\n callback = dest;\n transport = undefined;\n dest = undefined;\n }\n\n else if(transport instanceof Function)\n {\n if(callback != undefined)\n throw new SyntaxError(\"There can't be parameters after callback\");\n\n callback = transport;\n transport = undefined;\n };\n\n if(self.peerID != undefined)\n {\n params = params || {};\n\n params.from = self.peerID;\n };\n\n if(dest != undefined)\n {\n params = params || {};\n\n params.dest = dest;\n };\n\n // Encode message\n var message =\n {\n method: method,\n params: params\n };\n\n if(callback)\n {\n var id = requestID++;\n var retried = 0;\n\n message = packer.pack(message, id);\n\n function dispatchCallback(error, result)\n {\n self.cancel(message);\n\n callback(error, result);\n };\n\n var request =\n {\n message: message,\n callback: dispatchCallback,\n responseMethods: responseMethods[method] || {}\n };\n\n var encode_transport = unifyTransport(transport);\n\n function sendRequest(transport)\n {\n var rt = (method === 'ping' ? ping_request_timeout : request_timeout);\n request.timeout = setTimeout(timeout, rt*Math.pow(2, retried++));\n message2Key[message] = {id: id, dest: dest};\n requests.set(request, id, dest);\n\n transport = transport || encode_transport || self.getTransport();\n if(transport)\n return transport.send(message);\n\n return message;\n };\n\n function retry(transport)\n {\n transport = unifyTransport(transport);\n\n console.warn(retried+' retry for request message:',message);\n\n var timeout = processedResponses.pop(id, dest);\n clearTimeout(timeout);\n\n return sendRequest(transport);\n };\n\n function timeout()\n {\n if(retried < max_retries)\n return retry(transport);\n\n var error = new Error('Request has timed out');\n error.request = message;\n\n error.retry = retry;\n\n dispatchCallback(error)\n };\n\n return sendRequest(transport);\n };\n\n // Return the packed message\n message = packer.pack(message);\n\n transport = transport || this.getTransport();\n if(transport)\n return transport.send(message);\n\n return message;\n };\n\n /**\n * Decode and process a JsonRPC 2.0 message\n *\n * @param {string} message - string with the content of the message\n *\n * @returns {RpcNotification|RpcRequest|undefined} - the representation of the\n * notification or the request. If a response was processed, it will return\n * `undefined` to notify that it was processed\n *\n * @throws {TypeError} - Message is not defined\n */\n this.decode = function(message, transport)\n {\n if(!message)\n throw new TypeError(\"Message is not defined\");\n\n try\n {\n message = packer.unpack(message);\n }\n catch(e)\n {\n // Ignore invalid messages\n return console.debug(e, message);\n };\n\n var id = message.id;\n var ack = message.ack;\n var method = message.method;\n var params = message.params || {};\n\n var from = params.from;\n var dest = params.dest;\n\n // Ignore messages send by us\n if(self.peerID != undefined && from == self.peerID) return;\n\n // Notification\n if(id == undefined && ack == undefined)\n {\n var notification = new RpcNotification(method, params);\n\n if(self.emit('request', notification)) return;\n return notification;\n };\n\n\n function processRequest()\n {\n // If we have a transport and it's a duplicated request, reply inmediatly\n transport = unifyTransport(transport) || self.getTransport();\n if(transport)\n {\n var response = responses.get(id, from);\n if(response)\n return transport.send(response.message);\n };\n\n var idAck = (id != undefined) ? id : ack;\n var request = new RpcRequest(method, params, idAck, from, transport);\n\n if(self.emit('request', request)) return;\n return request;\n };\n\n function processResponse(request, error, result)\n {\n request.callback(error, result);\n };\n\n function duplicatedResponse(timeout)\n {\n console.warn(\"Response already processed\", message);\n\n // Update duplicated responses timeout\n clearTimeout(timeout);\n storeProcessedResponse(ack, from);\n };\n\n\n // Request, or response with own method\n if(method)\n {\n // Check if it's a response with own method\n if(dest == undefined || dest == self.peerID)\n {\n var request = requests.get(ack, from);\n if(request)\n {\n var responseMethods = request.responseMethods;\n\n if(method == responseMethods.error)\n return processResponse(request, params);\n\n if(method == responseMethods.response)\n return processResponse(request, null, params);\n\n return processRequest();\n }\n\n var processed = processedResponses.get(ack, from);\n if(processed)\n return duplicatedResponse(processed);\n }\n\n // Request\n return processRequest();\n };\n\n var error = message.error;\n var result = message.result;\n\n // Ignore responses not send to us\n if(error && error.dest && error.dest != self.peerID) return;\n if(result && result.dest && result.dest != self.peerID) return;\n\n // Response\n var request = requests.get(ack, from);\n if(!request)\n {\n var processed = processedResponses.get(ack, from);\n if(processed)\n return duplicatedResponse(processed);\n\n return console.warn(\"No callback was defined for this message\", message);\n };\n\n // Process response\n processResponse(request, error, result);\n };\n};\ninherits(RpcBuilder, EventEmitter);\n\n\nRpcBuilder.RpcNotification = RpcNotification;\n\n\nmodule.exports = RpcBuilder;\n\nvar clients = require('./clients');\nvar transports = require('./clients/transports');\n\nRpcBuilder.clients = clients;\nRpcBuilder.clients.transports = transports;\nRpcBuilder.packers = packers;\n","/**\n * JsonRPC 2.0 packer\n */\n\n/**\n * Pack a JsonRPC 2.0 message\n *\n * @param {Object} message - object to be packaged. It requires to have all the\n * fields needed by the JsonRPC 2.0 message that it's going to be generated\n *\n * @return {String} - the stringified JsonRPC 2.0 message\n */\nfunction pack(message, id)\n{\n var result =\n {\n jsonrpc: \"2.0\"\n };\n\n // Request\n if(message.method)\n {\n result.method = message.method;\n\n if(message.params)\n result.params = message.params;\n\n // Request is a notification\n if(id != undefined)\n result.id = id;\n }\n\n // Response\n else if(id != undefined)\n {\n if(message.error)\n {\n if(message.result !== undefined)\n throw new TypeError(\"Both result and error are defined\");\n\n result.error = message.error;\n }\n else if(message.result !== undefined)\n result.result = message.result;\n else\n throw new TypeError(\"No result or error is defined\");\n\n result.id = id;\n };\n\n return JSON.stringify(result);\n};\n\n/**\n * Unpack a JsonRPC 2.0 message\n *\n * @param {String} message - string with the content of the JsonRPC 2.0 message\n *\n * @throws {TypeError} - Invalid JsonRPC version\n *\n * @return {Object} - object filled with the JsonRPC 2.0 message content\n */\nfunction unpack(message)\n{\n var result = message;\n\n if(typeof message === 'string' || message instanceof String) {\n result = JSON.parse(message);\n }\n\n // Check if it's a valid message\n\n var version = result.jsonrpc;\n if(version !== '2.0')\n throw new TypeError(\"Invalid JsonRPC version '\" + version + \"': \" + message);\n\n // Response\n if(result.method == undefined)\n {\n if(result.id == undefined)\n throw new TypeError(\"Invalid message: \"+message);\n\n var result_defined = result.result !== undefined;\n var error_defined = result.error !== undefined;\n\n // Check only result or error is defined, not both or none\n if(result_defined && error_defined)\n throw new TypeError(\"Both result and error are defined: \"+message);\n\n if(!result_defined && !error_defined)\n throw new TypeError(\"No result or error is defined: \"+message);\n\n result.ack = result.id;\n delete result.id;\n }\n\n // Return unpacked message\n return result;\n};\n\n\nexports.pack = pack;\nexports.unpack = unpack;\n","function pack(message)\n{\n throw new TypeError(\"Not yet implemented\");\n};\n\nfunction unpack(message)\n{\n throw new TypeError(\"Not yet implemented\");\n};\n\n\nexports.pack = pack;\nexports.unpack = unpack;\n","var JsonRPC = require('./JsonRPC');\nvar XmlRPC = require('./XmlRPC');\n\n\nexports.JsonRPC = JsonRPC;\nexports.XmlRPC = XmlRPC;\n","/*\n * (C) Copyright 2014-2015 Kurento (http://kurento.org/)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nvar freeice = require('freeice')\nvar inherits = require('inherits')\nvar UAParser = require('ua-parser-js')\nvar uuid = require('uuid')\nvar hark = require('hark')\n\nvar EventEmitter = require('events').EventEmitter\nvar recursive = require('merge').recursive.bind(undefined, true)\nvar sdpTranslator = require('sdp-translator')\nvar logger = window.Logger || console\n\n// var gUM = navigator.mediaDevices.getUserMedia || function (constraints) {\n// return new Promise(navigator.getUserMedia(constraints, function (stream) {\n// videoStream = stream\n// start()\n// }).eror(callback));\n// }\n\n/*try {\n require('kurento-browser-extensions')\n} catch (error) {\n if (typeof getScreenConstraints === 'undefined') {\n logger.warn('screen sharing is not available')\n\n getScreenConstraints = function getScreenConstraints(sendSource, callback) {\n callback(new Error(\"This library is not enabled for screen sharing\"))\n }\n }\n}*/\n\nvar MEDIA_CONSTRAINTS = {\n audio: true,\n video: {\n width: 640,\n framerate: 15\n }\n}\n\n// Somehow, the UAParser constructor gets an empty window object.\n// We need to pass the user agent string in order to get information\nvar ua = (window && window.navigator) ? window.navigator.userAgent : ''\nvar parser = new UAParser(ua)\nvar browser = parser.getBrowser()\n\nvar usePlanB = false\nif (browser.name === 'Chrome' || browser.name === 'Chromium') {\n logger.debug(browser.name + \": using SDP PlanB\")\n usePlanB = true\n}\n\nfunction noop(error) {\n if (error) logger.error(error)\n}\n\nfunction trackStop(track) {\n track.stop && track.stop()\n}\n\nfunction streamStop(stream) {\n stream.getTracks().forEach(trackStop)\n}\n\n/**\n * Returns a string representation of a SessionDescription object.\n */\nvar dumpSDP = function (description) {\n if (typeof description === 'undefined' || description === null) {\n return ''\n }\n\n return 'type: ' + description.type + '\\r\\n' + description.sdp\n}\n\nfunction bufferizeCandidates(pc, onerror) {\n var candidatesQueue = []\n\n pc.addEventListener('signalingstatechange', function () {\n if (this.signalingState === 'stable') {\n while (candidatesQueue.length) {\n var entry = candidatesQueue.shift()\n\n this.addIceCandidate(entry.candidate, entry.callback, entry.callback)\n }\n }\n })\n\n return function (candidate, callback) {\n callback = callback || onerror\n\n switch (pc.signalingState) {\n case 'closed':\n callback(new Error('PeerConnection object is closed'))\n break\n case 'stable':\n if (pc.remoteDescription) {\n pc.addIceCandidate(candidate, callback, callback)\n break\n }\n default:\n candidatesQueue.push({\n candidate: candidate,\n callback: callback\n })\n }\n }\n}\n\n/* Simulcast utilities */\n\nfunction removeFIDFromOffer(sdp) {\n var n = sdp.indexOf(\"a=ssrc-group:FID\");\n\n if (n > 0) {\n return sdp.slice(0, n);\n } else {\n return sdp;\n }\n}\n\nfunction getSimulcastInfo(videoStream) {\n var videoTracks = videoStream.getVideoTracks();\n if (!videoTracks.length) {\n logger.warn('No video tracks available in the video stream')\n return ''\n }\n var lines = [\n 'a=x-google-flag:conference',\n 'a=ssrc-group:SIM 1 2 3',\n 'a=ssrc:1 cname:localVideo',\n 'a=ssrc:1 msid:' + videoStream.id + ' ' + videoTracks[0].id,\n 'a=ssrc:1 mslabel:' + videoStream.id,\n 'a=ssrc:1 label:' + videoTracks[0].id,\n 'a=ssrc:2 cname:localVideo',\n 'a=ssrc:2 msid:' + videoStream.id + ' ' + videoTracks[0].id,\n 'a=ssrc:2 mslabel:' + videoStream.id,\n 'a=ssrc:2 label:' + videoTracks[0].id,\n 'a=ssrc:3 cname:localVideo',\n 'a=ssrc:3 msid:' + videoStream.id + ' ' + videoTracks[0].id,\n 'a=ssrc:3 mslabel:' + videoStream.id,\n 'a=ssrc:3 label:' + videoTracks[0].id\n ];\n\n lines.push('');\n\n return lines.join('\\n');\n}\n\n/**\n * Wrapper object of an RTCPeerConnection. This object is aimed to simplify the\n * development of WebRTC-based applications.\n *\n * @constructor module:kurentoUtils.WebRtcPeer\n *\n * @param {String} mode Mode in which the PeerConnection will be configured.\n * Valid values are: 'recv', 'send', and 'sendRecv'\n * @param localVideo Video tag for the local stream\n * @param remoteVideo Video tag for the remote stream\n * @param {MediaStream} videoStream Stream to be used as primary source\n * (typically video and audio, or only video if combined with audioStream) for\n * localVideo and to be added as stream to the RTCPeerConnection\n * @param {MediaStream} audioStream Stream to be used as second source\n * (typically for audio) for localVideo and to be added as stream to the\n * RTCPeerConnection\n */\nfunction WebRtcPeer(mode, options, callback) {\n if (!(this instanceof WebRtcPeer)) {\n return new WebRtcPeer(mode, options, callback)\n }\n\n WebRtcPeer.super_.call(this)\n\n if (options instanceof Function) {\n callback = options\n options = undefined\n }\n\n options = options || {}\n callback = (callback || noop).bind(this)\n\n var self = this\n var localVideo = options.localVideo\n var remoteVideo = options.remoteVideo\n var videoStream = options.videoStream\n var audioStream = options.audioStream\n var mediaConstraints = options.mediaConstraints\n\n var connectionConstraints = options.connectionConstraints\n var pc = options.peerConnection\n var sendSource = options.sendSource || 'webcam'\n\n var dataChannelConfig = options.dataChannelConfig\n var useDataChannels = options.dataChannels || false\n var dataChannel\n\n var guid = uuid.v4()\n var configuration = recursive({\n iceServers: freeice()\n },\n options.configuration)\n\n var onicecandidate = options.onicecandidate\n if (onicecandidate) this.on('icecandidate', onicecandidate)\n\n var oncandidategatheringdone = options.oncandidategatheringdone\n if (oncandidategatheringdone) {\n this.on('candidategatheringdone', oncandidategatheringdone)\n }\n\n var simulcast = options.simulcast\n var multistream = options.multistream\n var interop = new sdpTranslator.Interop()\n var candidatesQueueOut = []\n var candidategatheringdone = false\n\n Object.defineProperties(this, {\n 'peerConnection': {\n get: function () {\n return pc\n }\n },\n\n 'id': {\n value: options.id || guid,\n writable: false\n },\n\n 'remoteVideo': {\n get: function () {\n return remoteVideo\n }\n },\n\n 'localVideo': {\n get: function () {\n return localVideo\n }\n },\n\n 'dataChannel': {\n get: function () {\n return dataChannel\n }\n },\n\n /**\n * @member {(external:ImageData|undefined)} currentFrame\n */\n 'currentFrame': {\n get: function () {\n // [ToDo] Find solution when we have a remote stream but we didn't set\n // a remoteVideo tag\n if (!remoteVideo) return;\n\n if (remoteVideo.readyState < remoteVideo.HAVE_CURRENT_DATA)\n throw new Error('No video stream data available')\n\n var canvas = document.createElement('canvas')\n canvas.width = remoteVideo.videoWidth\n canvas.height = remoteVideo.videoHeight\n\n canvas.getContext('2d').drawImage(remoteVideo, 0, 0)\n\n return canvas\n }\n }\n })\n\n // Init PeerConnection\n if (!pc) {\n pc = new RTCPeerConnection(configuration);\n if (useDataChannels && !dataChannel) {\n var dcId = 'WebRtcPeer-' + self.id\n var dcOptions = undefined\n if (dataChannelConfig) {\n dcId = dataChannelConfig.id || dcId\n dcOptions = dataChannelConfig.options\n }\n dataChannel = pc.createDataChannel(dcId, dcOptions);\n if (dataChannelConfig) {\n dataChannel.onopen = dataChannelConfig.onopen;\n dataChannel.onclose = dataChannelConfig.onclose;\n dataChannel.onmessage = dataChannelConfig.onmessage;\n dataChannel.onbufferedamountlow = dataChannelConfig.onbufferedamountlow;\n dataChannel.onerror = dataChannelConfig.onerror || noop;\n }\n }\n }\n\n pc.addEventListener('icecandidate', function (event) {\n var candidate = event.candidate\n\n if (EventEmitter.listenerCount(self, 'icecandidate') ||\n EventEmitter.listenerCount(\n self, 'candidategatheringdone')) {\n if (candidate) {\n var cand\n\n if (multistream && usePlanB) {\n cand = interop.candidateToUnifiedPlan(candidate)\n } else {\n cand = candidate\n }\n\n self.emit('icecandidate', cand)\n candidategatheringdone = false\n } else if (!candidategatheringdone) {\n self.emit('candidategatheringdone')\n candidategatheringdone = true\n }\n } else if (!candidategatheringdone) {\n // Not listening to 'icecandidate' or 'candidategatheringdone' events, queue\n // the candidate until one of them is listened\n candidatesQueueOut.push(candidate)\n\n if (!candidate) candidategatheringdone = true\n }\n })\n\n pc.ontrack = options.onaddstream\n pc.onnegotiationneeded = options.onnegotiationneeded\n this.on('newListener', function (event, listener) {\n if (event === 'icecandidate' || event === 'candidategatheringdone') {\n while (candidatesQueueOut.length) {\n var candidate = candidatesQueueOut.shift()\n\n if (!candidate === (event === 'candidategatheringdone')) {\n listener(candidate)\n }\n }\n }\n })\n\n var addIceCandidate = bufferizeCandidates(pc)\n\n /**\n * Callback function invoked when an ICE candidate is received. Developers are\n * expected to invoke this function in order to complete the SDP negotiation.\n *\n * @function module:kurentoUtils.WebRtcPeer.prototype.addIceCandidate\n *\n * @param iceCandidate - Literal object with the ICE candidate description\n * @param callback - Called when the ICE candidate has been added.\n */\n this.addIceCandidate = function (iceCandidate, callback) {\n var candidate\n\n if (multistream && usePlanB) {\n candidate = interop.candidateToPlanB(iceCandidate)\n } else {\n candidate = new RTCIceCandidate(iceCandidate)\n }\n\n logger.debug('Remote ICE candidate received', iceCandidate)\n callback = (callback || noop).bind(this)\n addIceCandidate(candidate, callback)\n }\n\n this.generateOffer = function (callback) {\n callback = callback.bind(this)\n\n var offerAudio = true\n var offerVideo = true\n // Constraints must have both blocks\n if (mediaConstraints) {\n offerAudio = (typeof mediaConstraints.audio === 'boolean') ?\n mediaConstraints.audio : true\n offerVideo = (typeof mediaConstraints.video === 'boolean') ?\n mediaConstraints.video : true\n }\n\n var browserDependantConstraints = {\n offerToReceiveAudio: (mode !== 'sendonly' && offerAudio),\n offerToReceiveVideo: (mode !== 'sendonly' && offerVideo)\n }\n\n //FIXME: clarify possible constraints passed to createOffer()\n /*var constraints = recursive(browserDependantConstraints,\n connectionConstraints)*/\n\n var constraints = browserDependantConstraints;\n\n logger.debug('constraints: ' + JSON.stringify(constraints))\n\n pc.createOffer(constraints).then(function (offer) {\n logger.debug('Created SDP offer')\n offer = mangleSdpToAddSimulcast(offer)\n return pc.setLocalDescription(offer)\n }).then(function () {\n var localDescription = pc.localDescription\n logger.debug('Local description set', localDescription.sdp)\n if (multistream && usePlanB) {\n localDescription = interop.toUnifiedPlan(localDescription)\n logger.debug('offer::origPlanB->UnifiedPlan', dumpSDP(\n localDescription))\n }\n callback(null, localDescription.sdp, self.processAnswer.bind(\n self))\n }).catch(callback)\n }\n\n this.getLocalSessionDescriptor = function () {\n return pc.localDescription\n }\n\n this.getRemoteSessionDescriptor = function () {\n return pc.remoteDescription\n }\n\n function setRemoteVideo() {\n if (remoteVideo) {\n var stream = pc.getRemoteStreams()[0]\n var url = stream ? URL.createObjectURL(stream) : ''\n\n remoteVideo.pause()\n remoteVideo.src = url\n remoteVideo.load()\n\n logger.debug('Remote URL:', url)\n }\n }\n\n this.showLocalVideo = function () {\n localVideo.src = URL.createObjectURL(videoStream)\n localVideo.muted = true\n }\n\n this.send = function (data) {\n if (dataChannel && dataChannel.readyState === 'open') {\n dataChannel.send(data)\n } else {\n logger.warn(\n 'Trying to send data over a non-existing or closed data channel')\n }\n }\n\n /**\n * Callback function invoked when a SDP answer is received. Developers are\n * expected to invoke this function in order to complete the SDP negotiation.\n *\n * @function module:kurentoUtils.WebRtcPeer.prototype.processAnswer\n *\n * @param sdpAnswer - Description of sdpAnswer\n * @param callback -\n * Invoked after the SDP answer is processed, or there is an error.\n */\n this.processAnswer = function (sdpAnswer, callback) {\n callback = (callback || noop).bind(this)\n\n var answer = new RTCSessionDescription({\n type: 'answer',\n sdp: sdpAnswer\n })\n\n if (multistream && usePlanB) {\n var planBAnswer = interop.toPlanB(answer)\n logger.debug('asnwer::planB', dumpSDP(planBAnswer))\n answer = planBAnswer\n }\n\n logger.debug('SDP answer received, setting remote description')\n\n if (pc.signalingState === 'closed') {\n return callback('PeerConnection is closed')\n }\n\n pc.setRemoteDescription(answer, function () {\n setRemoteVideo()\n\n callback()\n },\n callback)\n }\n\n /**\n * Callback function invoked when a SDP offer is received. Developers are\n * expected to invoke this function in order to complete the SDP negotiation.\n *\n * @function module:kurentoUtils.WebRtcPeer.prototype.processOffer\n *\n * @param sdpOffer - Description of sdpOffer\n * @param callback - Called when the remote description has been set\n * successfully.\n */\n this.processOffer = function (sdpOffer, callback) {\n callback = callback.bind(this)\n\n var offer = new RTCSessionDescription({\n type: 'offer',\n sdp: sdpOffer\n })\n\n if (multistream && usePlanB) {\n var planBOffer = interop.toPlanB(offer)\n logger.debug('offer::planB', dumpSDP(planBOffer))\n offer = planBOffer\n }\n\n logger.debug('SDP offer received, setting remote description')\n\n if (pc.signalingState === 'closed') {\n return callback('PeerConnection is closed')\n }\n\n pc.setRemoteDescription(offer).then(function () {\n return setRemoteVideo()\n }).then(function () {\n return pc.createAnswer()\n }).then(function (answer) {\n answer = mangleSdpToAddSimulcast(answer)\n logger.debug('Created SDP answer')\n return pc.setLocalDescription(answer)\n }).then(function () {\n var localDescription = pc.localDescription\n if (multistream && usePlanB) {\n localDescription = interop.toUnifiedPlan(localDescription)\n logger.debug('answer::origPlanB->UnifiedPlan', dumpSDP(\n localDescription))\n }\n logger.debug('Local description set', localDescription.sdp)\n callback(null, localDescription.sdp)\n }).catch(callback)\n }\n\n function mangleSdpToAddSimulcast(answer) {\n if (simulcast) {\n if (browser.name === 'Chrome' || browser.name === 'Chromium') {\n logger.debug('Adding multicast info')\n answer = new RTCSessionDescription({\n 'type': answer.type,\n 'sdp': removeFIDFromOffer(answer.sdp) + getSimulcastInfo(\n videoStream)\n })\n } else {\n logger.warn('Simulcast is only available in Chrome browser.')\n }\n }\n\n return answer\n }\n\n /**\n * This function creates the RTCPeerConnection object taking into account the\n * properties received in the constructor. It starts the SDP negotiation\n * process: generates the SDP offer and invokes the onsdpoffer callback. This\n * callback is expected to send the SDP offer, in order to obtain an SDP\n * answer from another peer.\n */\n function start() {\n if (pc.signalingState === 'closed') {\n callback(\n 'The peer connection object is in \"closed\" state. This is most likely due to an invocation of the dispose method before accepting in the dialogue'\n )\n }\n\n if (videoStream && localVideo) {\n self.showLocalVideo()\n }\n\n if (videoStream) {\n pc.addStream(videoStream)\n }\n\n if (audioStream) {\n pc.addStream(audioStream)\n }\n\n // [Hack] https://code.google.com/p/chromium/issues/detail?id=443558\n var browser = parser.getBrowser()\n if (mode === 'sendonly' &&\n (browser.name === 'Chrome' || browser.name === 'Chromium') &&\n browser.major === 39) {\n mode = 'sendrecv'\n }\n\n callback()\n }\n\n if (mode !== 'recvonly' && !videoStream && !audioStream) {\n function getMedia(constraints) {\n if (constraints === undefined) {\n constraints = MEDIA_CONSTRAINTS\n }\n\n navigator.mediaDevices.getUserMedia(constraints).then(function (stream) {\n videoStream = stream\n start()\n }).catch(callback);\n }\n if (sendSource === 'webcam') {\n getMedia(mediaConstraints)\n } else {\n getScreenConstraints(sendSource, function (error, constraints_) {\n if (error)\n return callback(error)\n\n constraints = [mediaConstraints]\n constraints.unshift(constraints_)\n getMedia(recursive.apply(undefined, constraints))\n }, guid)\n }\n } else {\n setTimeout(start, 0)\n }\n\n this.on('_dispose', function () {\n if (localVideo) {\n localVideo.pause()\n localVideo.src = ''\n localVideo.load()\n //Unmute local video in case the video tag is later used for remote video\n localVideo.muted = false\n }\n if (remoteVideo) {\n remoteVideo.pause()\n remoteVideo.src = ''\n remoteVideo.load()\n }\n self.removeAllListeners()\n\n if (window.cancelChooseDesktopMedia !== undefined) {\n window.cancelChooseDesktopMedia(guid)\n }\n })\n}\ninherits(WebRtcPeer, EventEmitter)\n\nfunction createEnableDescriptor(type) {\n var method = 'get' + type + 'Tracks'\n\n return {\n enumerable: true,\n get: function () {\n // [ToDo] Should return undefined if not all tracks have the same value?\n\n if (!this.peerConnection) return\n\n var streams = this.peerConnection.getLocalStreams()\n if (!streams.length) return\n\n for (var i = 0, stream; stream = streams[i]; i++) {\n var tracks = stream[method]()\n for (var j = 0, track; track = tracks[j]; j++)\n if (!track.enabled) return false\n }\n\n return true\n },\n set: function (value) {\n function trackSetEnable(track) {\n track.enabled = value\n }\n\n this.peerConnection.getLocalStreams().forEach(function (stream) {\n stream[method]().forEach(trackSetEnable)\n })\n }\n }\n}\n\nObject.defineProperties(WebRtcPeer.prototype, {\n 'enabled': {\n enumerable: true,\n get: function () {\n return this.audioEnabled && this.videoEnabled\n },\n set: function (value) {\n this.audioEnabled = this.videoEnabled = value\n }\n },\n 'audioEnabled': createEnableDescriptor('Audio'),\n 'videoEnabled': createEnableDescriptor('Video')\n})\n\nWebRtcPeer.prototype.getLocalStream = function (index) {\n if (this.peerConnection) {\n return this.peerConnection.getLocalStreams()[index || 0]\n }\n}\n\nWebRtcPeer.prototype.getRemoteStream = function (index) {\n if (this.peerConnection) {\n return this.peerConnection.getRemoteStreams()[index || 0]\n }\n}\n\n/**\n * @description This method frees the resources used by WebRtcPeer.\n *\n * @function module:kurentoUtils.WebRtcPeer.prototype.dispose\n */\nWebRtcPeer.prototype.dispose = function () {\n logger.debug('Disposing WebRtcPeer')\n\n var pc = this.peerConnection\n var dc = this.dataChannel\n try {\n if (dc) {\n if (dc.signalingState === 'closed') return\n\n dc.close()\n }\n\n if (pc) {\n if (pc.signalingState === 'closed') return\n\n pc.getLocalStreams().forEach(streamStop)\n\n // FIXME This is not yet implemented in firefox\n // if(videoStream) pc.removeStream(videoStream);\n // if(audioStream) pc.removeStream(audioStream);\n\n pc.close()\n }\n } catch (err) {\n logger.warn('Exception disposing webrtc peer ' + err)\n }\n\n this.emit('_dispose')\n}\n\n//\n// Specialized child classes\n//\n\nfunction WebRtcPeerRecvonly(options, callback) {\n if (!(this instanceof WebRtcPeerRecvonly)) {\n return new WebRtcPeerRecvonly(options, callback)\n }\n\n WebRtcPeerRecvonly.super_.call(this, 'recvonly', options, callback)\n}\ninherits(WebRtcPeerRecvonly, WebRtcPeer)\n\nfunction WebRtcPeerSendonly(options, callback) {\n if (!(this instanceof WebRtcPeerSendonly)) {\n return new WebRtcPeerSendonly(options, callback)\n }\n\n WebRtcPeerSendonly.super_.call(this, 'sendonly', options, callback)\n}\ninherits(WebRtcPeerSendonly, WebRtcPeer)\n\nfunction WebRtcPeerSendrecv(options, callback) {\n if (!(this instanceof WebRtcPeerSendrecv)) {\n return new WebRtcPeerSendrecv(options, callback)\n }\n\n WebRtcPeerSendrecv.super_.call(this, 'sendrecv', options, callback)\n}\ninherits(WebRtcPeerSendrecv, WebRtcPeer)\n\nfunction harkUtils(stream, options) {\n return hark(stream, options);\n}\n\nexports.bufferizeCandidates = bufferizeCandidates\n\nexports.WebRtcPeerRecvonly = WebRtcPeerRecvonly\nexports.WebRtcPeerSendonly = WebRtcPeerSendonly\nexports.WebRtcPeerSendrecv = WebRtcPeerSendrecv\nexports.hark = harkUtils\n","/*\n * (C) Copyright 2014 Kurento (http://kurento.org/)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n */\n\n/**\n * This module contains a set of reusable components that have been found useful\n * during the development of the WebRTC applications with Kurento.\n * \n * @module kurentoUtils\n * \n * @copyright 2014 Kurento (http://kurento.org/)\n * @license ALv2\n */\n\nvar WebRtcPeer = require('./WebRtcPeer');\n\nexports.WebRtcPeer = WebRtcPeer;\n","import { OpenVidu } from './OpenVidu';\n\n//This export with --standalone option allows using OpenVidu from bowser with namespace\n//export { OpenVidu } from './OpenVidu';\n\n//This \"hack\" allows to use OpenVidu from the global space window\nif(window){\n window[\"OpenVidu\"] = OpenVidu;\n}\n\n//Command to generate bundle.js without namespace\n//watchify Main.ts -p [ tsify ] --exclude kurento-browser-extensions --debug -o ../static/js/OpenVidu.js -v","/*\n * (C) Copyright 2017 OpenVidu (http://openvidu.io/)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n */\nimport { OpenViduInternal } from '../OpenViduInternal/OpenViduInternal';\n\nimport { Session } from './Session';\nimport { Publisher } from './Publisher';\n\nimport * as adapter from 'webrtc-adapter';\n\nif (window) {\n window[\"adapter\"] = adapter;\n}\n\nexport class OpenVidu {\n\n openVidu: OpenViduInternal;\n\n constructor() {\n this.openVidu = new OpenViduInternal();\n console.info(\"'OpenVidu' initialized\");\n };\n\n initSession(apiKey: string, sessionId: string): Session;\n initSession(sessionId: string): Session;\n\n initSession(param1, param2?): any {\n if (this.checkSystemRequirements()) {\n if (typeof param2 == \"string\") {\n return new Session(this.openVidu.initSession(param2), this);\n } else {\n return new Session(this.openVidu.initSession(param1), this);\n }\n } else {\n alert(\"Browser not supported\");\n }\n }\n\n initPublisher(parentId: string): Publisher;\n initPublisher(parentId: string, cameraOptions: any): Publisher;\n initPublisher(parentId: string, cameraOptions: any, callback: any): Publisher;\n\n initPublisher(parentId: string, cameraOptions?: any, callback?: Function): any {\n if (this.checkSystemRequirements()) {\n if (cameraOptions != null) {\n let cameraOptionsAux = {\n sendAudio: cameraOptions.audio != null ? cameraOptions.audio : true,\n sendVideo: cameraOptions.video != null ? cameraOptions.video : true,\n activeAudio: cameraOptions.activeAudio != null ? cameraOptions.activeAudio : true,\n activeVideo: cameraOptions.activeVideo != null ? cameraOptions.activeVideo : true,\n data: true,\n mediaConstraints: this.openVidu.generateMediaConstraints(cameraOptions)\n };\n cameraOptions = cameraOptionsAux;\n } else {\n cameraOptions = {\n sendAudio: true,\n sendVideo: true,\n activeAudio: true,\n activeVideo: true,\n data: true,\n mediaConstraints: {\n audio: true,\n video: { width: { ideal: 1280 } }\n }\n }\n }\n var publisher = new Publisher(this.openVidu.initPublisherTagged(parentId, cameraOptions, callback), parentId);\n \n console.info(\"'Publisher' initialized\");\n return publisher;\n\n } else {\n alert(\"Browser not supported\");\n }\n }\n\n checkSystemRequirements(): number {\n let browser = adapter.browserDetails.browser;\n let version = adapter.browserDetails.version;\n\n //Bug fix: 'navigator.userAgent' in Firefox for Ubuntu 14.04 does not return \"Firefox/[version]\" in the string, so version returned is null\n if ((browser == 'firefox') && (version == null)) {\n return 1;\n }\n if (((browser == 'chrome') && (version >= 28)) || ((browser == 'edge') && (version >= 12)) || ((browser == 'firefox') && (version >= 22))) {\n return 1;\n } else {\n return 0;\n }\n }\n\n getDevices(callback) {\n navigator.mediaDevices.enumerateDevices().then((deviceInfos) => {\n callback(null, deviceInfos);\n }).catch((error) => {\n console.error(\"Error getting devices\", error);\n callback(error, null);\n });\n }\n\n enableProdMode() {\n console.log = function() {};\n console.debug = function() {};\n console.info = function() {};\n console.warn = function() {};\n }\n\n}\n","/*\n * options: name: XXX data: true (Maybe this is based on webrtc) audio: true,\n * video: true, url: \"file:///...\" > Player screen: true > Desktop (implicit\n * video:true, audio:false) audio: true, video: true > Webcam\n *\n * stream.hasAudio(); stream.hasVideo(); stream.hasData();\n */\nimport { Stream, StreamOptions, VideoOptions } from '../OpenViduInternal/Stream';\nimport { Session } from './Session';\n\nimport EventEmitter = require('wolfy87-eventemitter');\n\nexport class Publisher {\n\n private ee = new EventEmitter();\n\n accessAllowed = false;\n element: Element;\n id: string;\n stream: Stream;\n session: Session; //Initialized by Session.publish(Publisher)\n\n constructor(stream: Stream, parentId: string) {\n this.stream = stream;\n\n this.stream.addEventListener('camera-access-changed', (event) => {\n this.accessAllowed = event.accessAllowed;\n if (this.accessAllowed) {\n this.ee.emitEvent('accessAllowed');\n } else {\n this.ee.emitEvent('accessDenied');\n }\n });\n\n if (document.getElementById(parentId) != null) {\n this.element = document.getElementById(parentId)!!;\n }\n }\n\n publishAudio(value: boolean) {\n this.stream.getWebRtcPeer().audioEnabled = value;\n }\n\n publishVideo(value: boolean) {\n this.stream.getWebRtcPeer().videoEnabled = value;\n }\n\n destroy() {\n this.session.unpublish(this);\n this.stream.dispose();\n this.stream.removeVideo(this.element);\n return this;\n }\n\n subscribeToRemote() {\n this.stream.subscribeToMyRemote();\n }\n\n on(eventName: string, callback) {\n this.ee.addListener(eventName, event => {\n if (event) {\n console.info(\"Event '\" + eventName + \"' triggered by 'Publisher'\", event);\n } else {\n console.info(\"Event '\" + eventName + \"' triggered by 'Publisher'\");\n }\n callback(event);\n });\n if (eventName == 'videoElementCreated') {\n if (this.stream.isVideoELementCreated) {\n this.ee.emitEvent('videoElementCreated', [{\n element: this.stream.getVideoElement()\n }]);\n } else {\n this.stream.addOnceEventListener('video-element-created-by-stream', (element) => {\n this.id = element.id;\n this.ee.emitEvent('videoElementCreated', [{\n element: element.element\n }]);\n });\n }\n }\n if (eventName == 'videoPlaying') {\n var video = this.stream.getVideoElement();\n if (!this.stream.displayMyRemote() && video &&\n video.currentTime > 0 && \n video.paused == false && \n video.ended == false &&\n video.readyState == 4) {\n this.ee.emitEvent('videoPlaying', [{\n element: this.stream.getVideoElement()\n }]);\n } else {\n this.stream.addOnceEventListener('video-is-playing', (element) => {\n this.ee.emitEvent('videoPlaying', [{\n element: element.element\n }]);\n });\n }\n }\n if (eventName == 'remoteVideoPlaying') {\n var video = this.stream.getVideoElement();\n if (this.stream.displayMyRemote() && video &&\n video.currentTime > 0 && \n video.paused == false && \n video.ended == false &&\n video.readyState == 4) {\n this.ee.emitEvent('remoteVideoPlaying', [{\n element: this.stream.getVideoElement()\n }]);\n } else {\n this.stream.addOnceEventListener('remote-video-is-playing', (element) => {\n this.ee.emitEvent('remoteVideoPlaying', [{\n element: element.element\n }]);\n });\n }\n }\n if (eventName == 'streamCreated') {\n if (this.stream.isReady) {\n this.ee.emitEvent('streamCreated', [{ stream: this.stream }]);\n } else {\n this.stream.addEventListener('stream-created-by-publisher', () => {\n console.warn('Publisher emitting streamCreated');\n this.ee.emitEvent('streamCreated', [{ stream: this.stream }]);\n });\n }\n }\n if (eventName == 'accessAllowed') {\n if (this.stream.accessIsAllowed) {\n this.ee.emitEvent('accessAllowed');\n } else {\n this.stream.addEventListener('access-allowed-by-publisher', () => {\n this.ee.emitEvent('accessAllowed');\n });\n }\n }\n if (eventName == 'accessDenied') {\n if (this.stream.accessIsDenied) {\n this.ee.emitEvent('accessDenied');\n } else {\n this.stream.addEventListener('access-denied-by-publisher', () => {\n this.ee.emitEvent('accessDenied');\n });\n }\n }\n }\n}","import { SessionInternal, SessionOptions } from '../OpenViduInternal/SessionInternal';\nimport { Stream } from '../OpenViduInternal/Stream';\nimport { Connection } from \"../OpenViduInternal/Connection\";\n\nimport { OpenVidu } from './OpenVidu';\nimport { Publisher } from './Publisher';\nimport { Subscriber } from './Subscriber';\n\nimport EventEmitter = require('wolfy87-eventemitter');\n\nexport class Session {\n\n sessionId: String;\n //capabilities: Capabilities\n connection: Connection;\n\n private ee = new EventEmitter();\n\n constructor(private session: SessionInternal, private openVidu: OpenVidu) {\n this.sessionId = session.getSessionId();\n\n // Listens to the deactivation of the default behaviour upon the deletion of a Stream object\n this.session.addEventListener('stream-destroyed-default', event => {\n event.stream.removeVideo();\n });\n\n // Listens to the deactivation of the default behaviour upon the disconnection of a Session\n this.session.addEventListener('session-disconnected-default', () => {\n let s: Stream;\n for (s of this.openVidu.openVidu.getRemoteStreams()) {\n s.removeVideo();\n }\n if (this.connection) {\n for (let streamId in this.connection.getStreams()) {\n this.connection.getStreams()[streamId].removeVideo();\n }\n }\n });\n\n // Sets or updates the value of 'connection' property. Triggered by SessionInternal when succesful connection\n this.session.addEventListener('update-connection-object', event => {\n this.connection = event.connection;\n });\n }\n\n connect(token: string, callback: any);\n connect(token: string, metadata: any, callback: any);\n\n connect(param1, param2, param3?) {\n // Early configuration to deactivate automatic subscription to streams\n if (param3) {\n this.session.configure({\n sessionId: this.session.getSessionId(),\n participantId: param1,\n metadata: this.session.stringClientMetadata(param2),\n subscribeToStreams: false\n });\n this.session.connect(param1, param3);\n } else {\n this.session.configure({\n sessionId: this.session.getSessionId(),\n participantId: param1,\n metadata: '',\n subscribeToStreams: false\n });\n this.session.connect(param1, param2);\n }\n }\n\n disconnect() {\n this.openVidu.openVidu.close(false);\n this.session.emitEvent('sessionDisconnected', [{\n preventDefault: () => { this.session.removeEvent('session-disconnected-default'); }\n }]);\n this.session.emitEvent('session-disconnected-default', [{}]);\n }\n\n publish(publisher: Publisher) {\n publisher.session = this;\n publisher.stream.publish();\n }\n\n unpublish(publisher: Publisher) {\n this.session.unpublish(publisher.stream);\n }\n\n on(eventName: string, callback) {\n this.session.addEventListener(eventName, event => {\n if (event) {\n console.info(\"Event '\" + eventName + \"' triggered by 'Session'\", event);\n } else {\n console.info(\"Event '\" + eventName + \"' triggered by 'Session'\");\n }\n callback(event);\n });\n }\n\n once(eventName: string, callback) {\n this.session.addOnceEventListener(eventName, event => {\n callback(event);\n });\n }\n\n off(eventName: string, eventHandler) {\n this.session.removeListener(eventName, eventHandler);\n }\n\n subscribe(stream: Stream, htmlId: string, videoOptions: any): Subscriber;\n subscribe(stream: Stream, htmlId: string): Subscriber;\n\n subscribe(param1, param2, param3?): Subscriber {\n // Subscription\n this.session.subscribe(param1);\n let subscriber = new Subscriber(param1, param2);\n param1.playOnlyVideo(param2, null);\n return subscriber;\n }\n\n unsubscribe(subscriber: Subscriber) {\n this.session.unsuscribe(subscriber.stream);\n subscriber.stream.removeVideo();\n }\n\n\n\n\n /* Shortcut event API */\n\n onStreamCreated(callback) {\n this.session.addEventListener(\"streamCreated\", streamEvent => {\n callback(streamEvent.stream);\n });\n }\n\n onStreamDestroyed(callback) {\n this.session.addEventListener(\"streamDestroyed\", streamEvent => {\n callback(streamEvent.stream);\n });\n }\n\n onParticipantJoined(callback) {\n this.session.addEventListener(\"participant-joined\", participantEvent => {\n callback(participantEvent.connection);\n });\n }\n\n onParticipantLeft(callback) {\n this.session.addEventListener(\"participant-left\", participantEvent => {\n callback(participantEvent.connection);\n });\n }\n\n onParticipantPublished(callback) {\n this.session.addEventListener(\"participant-published\", participantEvent => {\n callback(participantEvent.connection);\n });\n }\n\n onParticipantEvicted(callback) {\n this.session.addEventListener(\"participant-evicted\", participantEvent => {\n callback(participantEvent.connection);\n });\n }\n\n onRoomClosed(callback) {\n this.session.addEventListener(\"room-closed\", roomEvent => {\n callback(roomEvent.room);\n });\n }\n\n onLostConnection(callback) {\n this.session.addEventListener(\"lost-connection\", roomEvent => {\n callback(roomEvent.room);\n });\n }\n\n onMediaError(callback) {\n this.session.addEventListener(\"error-media\", errorEvent => {\n callback(errorEvent.error)\n });\n }\n\n /* Shortcut event API */\n}\n","import { Stream, StreamOptions, VideoOptions } from '../OpenViduInternal/Stream';\n\nimport EventEmitter = require('wolfy87-eventemitter');\n\nexport class Subscriber {\n\n private ee = new EventEmitter();\n\n element: Element;\n id: string;\n stream: Stream;\n\n constructor(stream: Stream, parentId: string) {\n this.stream = stream;\n if (document.getElementById(parentId) != null) {\n this.element = document.getElementById(parentId)!!;\n }\n }\n\n on(eventName: string, callback) {\n this.ee.addListener(eventName, event => {\n if (event) {\n console.info(\"Event '\" + eventName + \"' triggered by 'Subscriber'\", event);\n } else {\n console.info(\"Event '\" + eventName + \"' triggered by 'Subscriber'\");\n }\n callback(event);\n });\n if (eventName == 'videoElementCreated') {\n if (this.stream.isVideoELementCreated) {\n this.ee.emitEvent('videoElementCreated', [{\n element: this.stream.getVideoElement()\n }]);\n } else {\n this.stream.addOnceEventListener('video-element-created-by-stream', element => {\n console.warn(\"Subscriber emitting videoElementCreated\");\n this.id = element.id;\n this.ee.emitEvent('videoElementCreated', [{\n element: element\n }]);\n });\n }\n }\n if (eventName == 'videoPlaying') {\n var video = this.stream.getVideoElement();\n if (!this.stream.displayMyRemote() && video &&\n video.currentTime > 0 && \n video.paused == false && \n video.ended == false &&\n video.readyState == 4) {\n this.ee.emitEvent('videoPlaying', [{\n element: this.stream.getVideoElement()\n }]);\n } else {\n this.stream.addOnceEventListener('video-is-playing', (element) => {\n this.ee.emitEvent('videoPlaying', [{\n element: element.element\n }]);\n });\n }\n }\n }\n}","import { Stream, StreamOptions } from './Stream';\nimport { OpenViduInternal } from './OpenViduInternal';\nimport { SessionInternal } from './SessionInternal';\n\ntype ObjMap = { [s: string]: T; }\n\nexport interface ConnectionOptions {\n id: string;\n metadata: string;\n streams?: StreamOptions[];\n audioActive: boolean;\n videoActive: boolean;\n}\n\nexport class Connection {\n\n public connectionId: string;\n public data: string;\n public creationTime: number;\n private streams: ObjMap = {};\n private streamsOpts: StreamOptions[] = [];\n\n constructor( private openVidu: OpenViduInternal, private local: boolean, private room: SessionInternal, private options?: ConnectionOptions ) {\n\n console.info( \"'Connection' created (\" + ( local ? \"local\" : \"remote\" ) + \")\" + ( local ? \"\" : \", with 'connectionId' [\" + (options ? options.id : '') + \"] \" ));\n\n if ( options ) {\n\n this.connectionId = options.id;\n this.data = options.metadata;\n\n if ( options.streams ) {\n this.initStreams(options);\n }\n }\n \n }\n\n addStream( stream: Stream ) {\n this.streams[stream.getIdInParticipant()] = stream;\n this.room.getStreams()[stream.getIdInParticipant()] = stream;\n }\n\n getStreams() {\n return this.streams;\n }\n\n dispose() {\n for ( let key in this.streams ) {\n this.streams[key].dispose();\n }\n }\n\n sendIceCandidate( candidate ) {\n\n console.debug(( this.local ? \"Local\" : \"Remote\" ), \"candidate for\",\n this.connectionId, JSON.stringify( candidate ) );\n\n this.openVidu.sendRequest( \"onIceCandidate\", {\n endpointName: this.connectionId,\n candidate: candidate.candidate,\n sdpMid: candidate.sdpMid,\n sdpMLineIndex: candidate.sdpMLineIndex\n }, function( error, response ) {\n if ( error ) {\n console.error( \"Error sending ICE candidate: \"\n + JSON.stringify( error ) );\n }\n });\n }\n\n initStreams(options) {\n for ( let streamOptions of options.streams ) {\n \n let streamOpts = {\n id: streamOptions.id,\n connection: this,\n sendAudio: streamOptions.sendAudio,\n sendVideo: streamOptions.sendVideo,\n recvAudio: ( streamOptions.audioActive == undefined ? true : streamOptions.audioActive ),\n recvVideo: ( streamOptions.videoActive == undefined ? true : streamOptions.videoActive ),\n activeAudio: streamOptions.activeAudio,\n activeVideo: streamOptions.activeVideo,\n data: streamOptions.data,\n mediaConstraints: streamOptions.mediaConstraints\n }\n let stream = new Stream(this.openVidu, false, this.room, streamOpts );\n\n this.addStream( stream );\n this.streamsOpts.push( streamOpts );\n }\n\n console.info(\"Remote 'Connection' with 'connectionId' [\" + this.connectionId + \"] is now configured for receiving Streams with options: \", this.streamsOpts );\n }\n}","/*\n * (C) Copyright 2017 OpenVidu (http://openvidu.io/)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n */\nimport { SessionInternal, SessionOptions } from './SessionInternal';\nimport { Stream } from './Stream';\nimport * as RpcBuilder from '../KurentoUtils/kurento-jsonrpc';\n\nexport type Callback = (error?: any, openVidu?: T) => void;\n\nexport class OpenViduInternal {\n\n private wsUri;\n private session: SessionInternal;\n private jsonRpcClient: any;\n private rpcParams: any;\n private callback: Callback;\n private camera: Stream;\n private remoteStreams: Stream[] = [];\n\n private secret: string;\n\n constructor() { };\n\n\n /* NEW METHODS */\n initSession(sessionId) {\n console.info(\"'Session' initialized with 'sessionId' [\" + sessionId + \"]\");\n this.session = new SessionInternal(this, sessionId);\n return this.session;\n }\n\n initPublisherTagged(parentId: string, cameraOptions: any, callback?) {\n\n this.getCamera(cameraOptions);\n\n if (callback == null) {\n this.camera.requestCameraAccess((error, camera) => {\n if (error) {\n console.error(\"Error accessing the camera\", error);\n }\n else {\n this.camera.setVideoElement(this.cameraReady(camera!, parentId));\n }\n });\n return this.camera;\n } else {\n this.camera.requestCameraAccess((error, camera) => {\n if (error) {\n callback(error);\n }\n else {\n this.camera.setVideoElement(this.cameraReady(camera!, parentId));\n callback(undefined);\n }\n });\n return this.camera;\n }\n }\n\n cameraReady(camera: Stream, parentId: string) {\n this.camera = camera;\n let videoElement = this.camera.playOnlyVideo(parentId, null);\n this.camera.emitStreamReadyEvent();\n return videoElement;\n }\n\n initPublisher(cameraOptions: any, callback) {\n this.getCamera(cameraOptions);\n this.camera.requestCameraAccess((error, camera) => {\n if (error) callback(error);\n else callback(undefined);\n });\n }\n\n getLocalStream() {\n return this.camera;\n }\n\n getRemoteStreams() {\n return this.remoteStreams;\n }\n /* NEW METHODS */\n\n getWsUri() {\n return this.wsUri;\n }\n\n setWsUri(wsUri: string) {\n this.wsUri = wsUri;\n }\n\n getSecret() {\n return this.secret;\n }\n\n setSecret(secret: string) {\n this.secret = secret;\n }\n\n getOpenViduServerURL() {\n return 'https://' + this.wsUri.split(\"wss://\")[1].split(\"/room\")[0];\n }\n\n getRoom() {\n return this.session;\n }\n\n connect(callback: Callback): void {\n\n this.callback = callback;\n\n this.initJsonRpcClient(this.wsUri);\n }\n\n private initJsonRpcClient(wsUri: string): void {\n\n let config = {\n heartbeat: 3000,\n sendCloseMessage: false,\n ws: {\n uri: wsUri,\n useSockJS: false,\n onconnected: this.connectCallback.bind(this),\n ondisconnect: this.disconnectCallback.bind(this),\n onreconnecting: this.reconnectingCallback.bind(this),\n onreconnected: this.reconnectedCallback.bind(this)\n },\n rpc: {\n requestTimeout: 15000,\n //notifications\n participantJoined: this.onParticipantJoined.bind(this),\n participantPublished: this.onParticipantPublished.bind(this),\n participantUnpublished: this.onParticipantLeft.bind(this),\n participantLeft: this.onParticipantLeft.bind(this),\n participantEvicted: this.onParticipantEvicted.bind(this),\n sendMessage: this.onNewMessage.bind(this),\n iceCandidate: this.iceCandidateEvent.bind(this),\n mediaError: this.onMediaError.bind(this),\n custonNotification: this.customNotification.bind(this)\n }\n };\n\n this.jsonRpcClient = new RpcBuilder.clients.JsonRpcClient(config);\n }\n\n\n private customNotification(params) {\n if (this.isRoomAvailable()) {\n this.session.emitEvent(\"custom-message-received\", [{ params: params }]);\n }\n }\n\n private connectCallback(error) {\n if (error) {\n this.callback(error);\n } else {\n this.callback(null);\n }\n }\n\n private isRoomAvailable() {\n if (this.session !== undefined && this.session instanceof SessionInternal) {\n return true;\n } else {\n console.warn('Room instance not found');\n return false;\n }\n }\n\n private disconnectCallback() {\n console.warn('Websocket connection lost');\n if (this.isRoomAvailable()) {\n this.session.onLostConnection();\n } else {\n alert('Connection error. Please reload page.');\n }\n }\n\n private reconnectingCallback() {\n console.warn('Websocket connection lost (reconnecting)');\n if (this.isRoomAvailable()) {\n this.session.onLostConnection();\n } else {\n alert('Connection error. Please reload page.');\n }\n }\n\n private reconnectedCallback() {\n console.warn('Websocket reconnected');\n }\n\n private onParticipantJoined(params) {\n if (this.isRoomAvailable()) {\n this.session.onParticipantJoined(params);\n }\n }\n\n private onParticipantPublished(params) {\n if (this.isRoomAvailable()) {\n this.session.onParticipantPublished(params);\n }\n }\n\n private onParticipantLeft(params) {\n if (this.isRoomAvailable()) {\n this.session.onParticipantLeft(params);\n }\n }\n\n private onParticipantEvicted(params) {\n if (this.isRoomAvailable()) {\n this.session.onParticipantEvicted(params);\n }\n }\n\n private onNewMessage(params) {\n if (this.isRoomAvailable()) {\n this.session.onNewMessage(params);\n }\n }\n\n private iceCandidateEvent(params) {\n if (this.isRoomAvailable()) {\n this.session.recvIceCandidate(params);\n }\n }\n\n private onRoomClosed(params) {\n if (this.isRoomAvailable()) {\n this.session.onRoomClosed(params);\n }\n }\n\n private onMediaError(params) {\n if (this.isRoomAvailable()) {\n this.session.onMediaError(params);\n }\n }\n\n\n setRpcParams(params: any) {\n this.rpcParams = params;\n }\n\n sendRequest(method, params, callback?) {\n\n if (params && params instanceof Function) {\n callback = params;\n params = undefined;\n }\n\n params = params || {};\n\n if (this.rpcParams && this.rpcParams !== null && this.rpcParams !== undefined) {\n for (let index in this.rpcParams) {\n if (this.rpcParams.hasOwnProperty(index)) {\n params[index] = this.rpcParams[index];\n console.debug('RPC param added to request {' + index + ': ' + this.rpcParams[index] + '}');\n }\n }\n }\n\n console.debug('Sending request: {method:\"' + method + '\", params: ' + JSON.stringify(params) + '}');\n\n this.jsonRpcClient.send(method, params, callback);\n }\n\n close(forced) {\n if (this.isRoomAvailable()) {\n this.session.leave(forced, this.jsonRpcClient);\n }\n };\n\n disconnectParticipant(stream) {\n if (this.isRoomAvailable()) {\n this.session.disconnect(stream);\n }\n }\n\n getCamera(options?) {\n\n if (this.camera) {\n return this.camera;\n }\n\n options = options || {\n sendAudio: true,\n sendVideo: true,\n activeAudio: true,\n activeVideo: true,\n data: true,\n mediaConstraints: {\n audio: true,\n video: { width: { ideal: 1280 } }\n }\n }\n options.connection = this.session.getLocalParticipant();\n\n this.camera = new Stream(this, true, this.session, options);\n return this.camera;\n };\n\n //CHAT\n sendMessage(room, user, message) {\n this.sendRequest('sendMessage', {\n message: message,\n userMessage: user,\n roomMessage: room\n }, function (error, response) {\n if (error) {\n console.error(error);\n }\n });\n };\n\n sendCustomRequest(params, callback) {\n this.sendRequest('customRequest', params, callback);\n };\n\n\n\n\n toggleLocalVideoTrack(activate: boolean) {\n this.getCamera().getWebRtcPeer().videoEnabled = activate;\n }\n\n toggleLocalAudioTrack(activate: boolean) {\n this.getCamera().getWebRtcPeer().audioEnabled = activate;\n }\n\n publishLocalVideoAudio() {\n this.toggleLocalVideoTrack(true);\n this.toggleLocalAudioTrack(true);\n }\n\n unpublishLocalVideoAudio() {\n this.toggleLocalVideoTrack(false);\n this.toggleLocalAudioTrack(false);\n }\n\n generateMediaConstraints(cameraOptions: any) {\n let mediaConstraints = {\n audio: cameraOptions.audio,\n video: {}\n }\n if (!cameraOptions.video) {\n mediaConstraints.video = false\n } else {\n let w, h;\n switch (cameraOptions.quality) {\n case 'LOW':\n w = 320;\n h = 240;\n break;\n case 'MEDIUM':\n w = 640;\n h = 480;\n break;\n case 'HIGH':\n w = 1280;\n h = 720;\n break;\n default:\n w = 640;\n h = 480;\n }\n mediaConstraints.video['width'] = { exact: w };\n mediaConstraints.video['height'] = { exact: h };\n //mediaConstraints.video['frameRate'] = { ideal: Number((document.getElementById('frameRate')).value) };\n }\n return mediaConstraints;\n }\n\n}\n","import { Stream } from './Stream';\nimport { OpenViduInternal } from './OpenViduInternal';\nimport { Connection, ConnectionOptions } from './Connection';\nimport EventEmitter = require('wolfy87-eventemitter');\n\nconst SECRET_PARAM = '?secret=';\n\nexport interface SessionOptions {\n sessionId: string;\n participantId: string;\n metadata: string;\n subscribeToStreams?: boolean;\n updateSpeakerInterval?: number;\n thresholdSpeaker?: number;\n}\n\nexport class SessionInternal {\n\n private id: string;\n private sessionId: string;\n private ee = new EventEmitter();\n private streams = {};\n private participants = {};\n private participantsSpeaking: Connection[] = [];\n private connected = false;\n public localParticipant: Connection;\n private subscribeToStreams: boolean;\n private updateSpeakerInterval: number;\n public thresholdSpeaker: number;\n private options: SessionOptions;\n\n constructor(private openVidu: OpenViduInternal, sessionId: string) {\n this.sessionId = this.getUrlWithoutSecret(sessionId);\n this.localParticipant = new Connection(this.openVidu, true, this);\n if (!this.openVidu.getWsUri()) {\n this.processOpenViduUrl(sessionId);\n }\n }\n\n private processOpenViduUrl(url: string) {\n this.openVidu.setSecret(this.getSecretFromUrl(url));\n this.openVidu.setWsUri(this.getFinalUrl(url));\n }\n\n private getSecretFromUrl(url: string): string {\n let secret = '';\n if (url.indexOf(SECRET_PARAM) !== -1) {\n secret = url.substring(url.lastIndexOf(SECRET_PARAM) + SECRET_PARAM.length, url.length);\n }\n return secret;\n }\n\n private getUrlWithoutSecret(url: string): string {\n if (url.indexOf(SECRET_PARAM) !== -1) {\n url = url.substring(0, url.lastIndexOf(SECRET_PARAM));\n }\n return url;\n }\n\n private getFinalUrl(url: string): string {\n url = this.getUrlWithoutSecret(url).substring(0, url.lastIndexOf('/')) + '/room';\n if (url.indexOf(\".ngrok.io\") !== -1) {\n // OpenVidu server URL referes to a ngrok IP: secure wss protocol and delete port of URL\n url = url.replace(\"ws://\", \"wss://\");\n let regex = /\\.ngrok\\.io:\\d+/;\n url = url.replace(regex, \".ngrok.io\");\n } else if ((url.indexOf(\"localhost\") !== -1) || (url.indexOf(\"127.0.0.1\") != -1)) {\n // OpenVidu server URL referes to localhost IP\n\n }\n return url;\n }\n\n\n\n /* NEW METHODS */\n connect(token, callback) {\n\n this.openVidu.connect((error) => {\n if (error) {\n callback('ERROR CONNECTING TO OPENVIDU');\n }\n else {\n\n if (!token) {\n token = this.randomToken();\n }\n\n let joinParams = {\n token: token,\n session: this.sessionId,\n metadata: this.options.metadata,\n secret: this.openVidu.getSecret(),\n dataChannels: false\n }\n\n if (this.localParticipant) {\n if (Object.keys(this.localParticipant.getStreams()).some(streamId =>\n this.streams[streamId].isDataChannelEnabled())) {\n joinParams.dataChannels = true;\n }\n }\n\n this.openVidu.sendRequest('joinRoom', joinParams, (error, response) => {\n\n if (error) {\n callback(error);\n } else {\n\n this.connected = true;\n\n let exParticipants = response.value;\n\n // IMPORTANT: Update connectionId with value send by server\n this.localParticipant.connectionId = response.id;\n this.participants[response.id] = this.localParticipant;\n\n let roomEvent = {\n participants: new Array(),\n streams: new Array()\n }\n\n let length = exParticipants.length;\n for (let i = 0; i < length; i++) {\n\n let connection = new Connection(this.openVidu, false, this,\n exParticipants[i]);\n connection.creationTime = new Date().getTime();\n\n this.participants[connection.connectionId] = connection;\n\n roomEvent.participants.push(connection);\n\n let streams = connection.getStreams();\n for (let key in streams) {\n roomEvent.streams.push(streams[key]);\n if (this.subscribeToStreams) {\n streams[key].subscribe();\n }\n }\n }\n\n // Update local Connection object properties with values returned by server\n this.localParticipant.data = response.metadata;\n this.localParticipant.creationTime = new Date().getTime();\n\n // Updates the value of property 'connection' in Session object\n this.ee.emitEvent('update-connection-object', [{ connection: this.localParticipant }]);\n // Own connection created event\n this.ee.emitEvent('connectionCreated', [{ connection: this.localParticipant }]);\n\n // One connection created event for each existing connection in the session\n for (let part of roomEvent.participants) {\n this.ee.emitEvent('connectionCreated', [{ connection: part }]);\n }\n\n //if (this.subscribeToStreams) {\n for (let stream of roomEvent.streams) {\n this.ee.emitEvent('streamCreated', [{ stream }]);\n\n // Adding the remote stream to the OpenVidu object\n this.openVidu.getRemoteStreams().push(stream);\n }\n //}\n\n callback(undefined);\n }\n });\n }\n });\n }\n\n publish() {\n this.openVidu.getCamera().publish();\n }\n /* NEW METHODS */\n\n\n\n\n\n configure(options: SessionOptions) {\n this.options = options;\n this.id = options.sessionId;\n this.subscribeToStreams = options.subscribeToStreams == null ? true : options.subscribeToStreams;\n this.updateSpeakerInterval = options.updateSpeakerInterval || 1500;\n this.thresholdSpeaker = options.thresholdSpeaker || -50;\n this.activateUpdateMainSpeaker();\n }\n\n getId() {\n return this.id;\n }\n\n getSessionId() {\n return this.sessionId;\n }\n\n private activateUpdateMainSpeaker() {\n\n setInterval(() => {\n if (this.participantsSpeaking.length > 0) {\n this.ee.emitEvent('update-main-speaker', [{\n participantId: this.participantsSpeaking[this.participantsSpeaking.length - 1]\n }]);\n }\n }, this.updateSpeakerInterval);\n }\n\n getLocalParticipant() {\n return this.localParticipant;\n }\n\n addEventListener(eventName, listener) {\n this.ee.on(eventName, listener);\n }\n\n addOnceEventListener(eventName, listener) {\n this.ee.once(eventName, listener);\n }\n\n removeListener(eventName, listener) {\n this.ee.off(eventName, listener);\n }\n\n removeEvent(eventName) {\n this.ee.removeEvent(eventName);\n }\n\n emitEvent(eventName, eventsArray) {\n this.ee.emitEvent(eventName, eventsArray);\n }\n\n\n subscribe(stream: Stream) {\n stream.subscribe();\n }\n\n unsuscribe(stream) {\n console.info(\"Unsubscribing from \" + stream.getId());\n this.openVidu.sendRequest('unsubscribeFromVideo', {\n sender: stream.getId()\n },\n function (error, response) {\n if (error) {\n console.error(\"Error unsubscribing from Subscriber\", error);\n } else {\n console.info(\"Unsubscribed correctly from \" + stream.getId());\n }\n });\n }\n\n onParticipantPublished(options) {\n\n options.metadata = this.participants[options.id].data;\n\n // Get the existing Connection created on 'onParticipantJoined' for\n // existing participants or create a new one for new participants\n let connection = this.participants[options.id];\n if (connection) {\n // Update existing Connection\n connection.options = options;\n connection.initStreams(options);\n } else {\n // Create new Connection\n connection = new Connection(this.openVidu, false, this, options);\n }\n\n let pid = connection.connectionId;\n if (!(pid in this.participants)) {\n console.debug(\"Remote Connection not found in connections list by its id [\" + pid + \"]\");\n } else {\n console.debug(\"Remote Connection found in connections list by its id [\" + pid + \"]\");\n }\n\n connection.creationTime = this.participants[pid].creationTime;\n this.participants[pid] = connection;\n\n this.ee.emitEvent('participant-published', [{ connection }]);\n\n let streams = connection.getStreams();\n for (let key in streams) {\n let stream = streams[key];\n\n if (this.subscribeToStreams) {\n stream.subscribe();\n }\n this.ee.emitEvent('streamCreated', [{ stream }]);\n // Adding the remote stream to the OpenVidu object\n this.openVidu.getRemoteStreams().push(stream);\n }\n }\n\n onParticipantJoined(msg) {\n\n let connection = new Connection(this.openVidu, false, this, msg);\n connection.creationTime = new Date().getTime();\n\n let pid = connection.connectionId;\n if (!(pid in this.participants)) {\n this.participants[pid] = connection;\n } else {\n //use existing so that we don't lose streams info\n console.warn(\"Connection already exists in connections list with \" +\n \"the same connectionId, old:\", this.participants[pid], \", joined now:\", connection);\n connection = this.participants[pid];\n }\n\n this.ee.emitEvent('participant-joined', [{\n connection: connection\n }]);\n\n this.ee.emitEvent('connectionCreated', [{\n connection: connection\n }]);\n\n }\n\n onParticipantLeft(msg) {\n\n let connection = this.participants[msg.name];\n\n if (connection !== undefined) {\n delete this.participants[msg.name];\n\n this.ee.emitEvent('participant-left', [{\n connection: connection\n }]);\n\n let streams = connection.getStreams();\n for (let key in streams) {\n this.ee.emitEvent('streamDestroyed', [{\n stream: streams[key],\n preventDefault: () => { this.ee.removeEvent('stream-destroyed-default'); }\n }]);\n this.ee.emitEvent('stream-destroyed-default', [{\n stream: streams[key]\n }]);\n\n // Deleting the removed stream from the OpenVidu object\n let index = this.openVidu.getRemoteStreams().indexOf(streams[key]);\n this.openVidu.getRemoteStreams().splice(index, 1);\n }\n\n connection.dispose();\n\n this.ee.emitEvent('connectionDestroyed', [{\n connection: connection\n }]);\n\n } else {\n console.warn(\"Participant \" + msg.name\n + \" unknown. Participants: \"\n + JSON.stringify(this.participants));\n }\n };\n\n onParticipantEvicted(msg) {\n this.ee.emitEvent('participant-evicted', [{\n localParticipant: this.localParticipant\n }]);\n };\n\n onNewMessage(msg) {\n\n console.info(\"New message: \" + JSON.stringify(msg));\n let room = msg.room;\n let user = msg.user;\n let message = msg.message;\n\n if (user !== undefined) {\n this.ee.emitEvent('newMessage', [{\n room: room,\n user: user,\n message: message\n }]);\n } else {\n console.warn(\"User undefined in new message:\", msg);\n }\n }\n\n recvIceCandidate(msg) {\n\n let candidate = {\n candidate: msg.candidate,\n sdpMid: msg.sdpMid,\n sdpMLineIndex: msg.sdpMLineIndex\n }\n\n let connection = this.participants[msg.endpointName];\n if (!connection) {\n console.error(\"Participant not found for endpoint \" +\n msg.endpointName + \". Ice candidate will be ignored.\",\n candidate);\n return;\n }\n\n let streams = connection.getStreams();\n for (let key in streams) {\n let stream = streams[key];\n stream.getWebRtcPeer().addIceCandidate(candidate, function (error) {\n if (error) {\n console.error(\"Error adding candidate for \" + key\n + \" stream of endpoint \" + msg.endpointName\n + \": \" + error);\n }\n });\n }\n }\n\n onRoomClosed(msg) {\n\n console.info(\"Room closed: \" + JSON.stringify(msg));\n let room = msg.room;\n if (room !== undefined) {\n this.ee.emitEvent('room-closed', [{\n room: room\n }]);\n } else {\n console.warn(\"Room undefined in on room closed\", msg);\n }\n }\n\n onLostConnection() {\n\n if (!this.connected) {\n console.warn('Not connected to room: if you are not debugging, this is probably a certificate error');\n if (window.confirm('If you are not debugging, this is probably a certificate error at \\\"' + this.openVidu.getOpenViduServerURL() + '\\\"\\n\\nClick OK to navigate and accept it')) {\n location.assign(this.openVidu.getOpenViduServerURL() + '/accept-certificate');\n };\n return;\n }\n\n console.warn('Lost connection in Session ' + this.id);\n let room = this.id;\n if (room !== undefined) {\n this.ee.emitEvent('lost-connection', [{ room }]);\n } else {\n console.warn('Room undefined when lost connection');\n }\n }\n\n onMediaError(params) {\n\n console.error(\"Media error: \" + JSON.stringify(params));\n let error = params.error;\n if (error) {\n this.ee.emitEvent('error-media', [{\n error: error\n }]);\n } else {\n console.warn(\"Received undefined media error. Params:\", params);\n }\n }\n\n /*\n * forced means the user was evicted, no need to send the 'leaveRoom' request\n */\n leave(forced, jsonRpcClient) {\n\n forced = !!forced;\n\n console.info(\"Leaving Session (forced=\" + forced + \")\");\n\n if (this.connected && !forced) {\n this.openVidu.sendRequest('leaveRoom', function (error, response) {\n if (error) {\n console.error(error);\n }\n jsonRpcClient.close();\n });\n } else {\n jsonRpcClient.close();\n }\n this.connected = false;\n if (this.participants) {\n for (let pid in this.participants) {\n this.participants[pid].dispose();\n delete this.participants[pid];\n }\n }\n }\n\n disconnect(stream: Stream) {\n\n let connection = stream.getParticipant();\n if (!connection) {\n console.error(\"Stream to disconnect has no participant\", stream);\n return;\n }\n\n delete this.participants[connection.connectionId];\n connection.dispose();\n\n if (connection === this.localParticipant) {\n\n console.info(\"Unpublishing my media (I'm \" + connection.connectionId + \")\");\n delete this.localParticipant;\n this.openVidu.sendRequest('unpublishVideo', function (error, response) {\n if (error) {\n console.error(error);\n } else {\n console.info(\"Media unpublished correctly\");\n }\n });\n\n } else {\n this.unsuscribe(stream);\n }\n }\n\n unpublish(stream: Stream) {\n\n let connection = stream.getParticipant();\n if (!connection) {\n console.error(\"Stream to disconnect has no participant\", stream);\n return;\n }\n\n if (connection === this.localParticipant) {\n\n delete this.participants[connection.connectionId];\n connection.dispose();\n\n console.info(\"Unpublishing my media (I'm \" + connection.connectionId + \")\");\n delete this.localParticipant;\n this.openVidu.sendRequest('unpublishVideo', function (error, response) {\n if (error) {\n console.error(error);\n } else {\n console.info(\"Media unpublished correctly\");\n }\n });\n }\n }\n\n getStreams() {\n return this.streams;\n }\n\n addParticipantSpeaking(participantId) {\n this.participantsSpeaking.push(participantId);\n }\n\n removeParticipantSpeaking(participantId) {\n let pos = -1;\n for (let i = 0; i < this.participantsSpeaking.length; i++) {\n if (this.participantsSpeaking[i] == participantId) {\n pos = i;\n break;\n }\n }\n if (pos != -1) {\n this.participantsSpeaking.splice(pos, 1);\n }\n }\n\n stringClientMetadata(metadata): string {\n if (!(typeof metadata === 'string')) {\n return JSON.stringify(metadata);\n } else {\n return metadata;\n }\n }\n \n private randomToken(): string {\n return Math.random().toString(36).slice(2) + Math.random().toString(36).slice(2);\n }\n\n}\n","/*\n * options: name: XXX data: true (Maybe this is based on webrtc) audio: true,\n * video: true, url: \"file:///...\" > Player screen: true > Desktop (implicit\n * video:true, audio:false) audio: true, video: true > Webcam\n *\n * stream.hasAudio(); stream.hasVideo(); stream.hasData();\n */\nimport { Connection } from './Connection';\nimport { SessionInternal } from './SessionInternal';\nimport { OpenViduInternal, Callback } from './OpenViduInternal';\nimport EventEmitter = require('wolfy87-eventemitter');\nimport * as kurentoUtils from '../KurentoUtils/kurento-utils-js';\n\nimport * as adapter from 'webrtc-adapter';\ndeclare var navigator: any;\ndeclare var RTCSessionDescription: any;\n\nif (window) {\n window[\"adapter\"] = adapter;\n}\n\nfunction jq(id: string): string {\n return id.replace(/(@|:|\\.|\\[|\\]|,)/g, \"\\\\$1\");\n}\n\nfunction show(id: string) {\n document.getElementById(jq(id))!.style.display = 'block';\n}\n\nfunction hide(id: string) {\n document.getElementById(jq(id))!.style.display = 'none';\n}\n\nexport interface StreamOptions {\n id: string;\n connection: Connection;\n recvVideo: boolean;\n recvAudio: boolean;\n sendVideo: boolean;\n sendAudio: boolean;\n activeAudio: boolean;\n activeVideo: boolean;\n data: boolean;\n mediaConstraints: any;\n}\n\nexport interface VideoOptions {\n thumb: string;\n video: HTMLVideoElement;\n}\n\nexport class Stream {\n\n public connection: Connection;\n\n private ee = new EventEmitter();\n private wrStream: any;\n private wp: any;\n private id: string;\n private video: HTMLVideoElement;\n private videoElements: VideoOptions[] = [];\n private elements: HTMLDivElement[] = [];\n private speechEvent: any;\n private recvVideo: boolean;\n private recvAudio: boolean;\n private sendVideo: boolean;\n private sendAudio: boolean;\n private mediaConstraints: any;\n private showMyRemote = false;\n private localMirrored = false;\n private chanId = 0;\n private dataChannel: boolean;\n private dataChannelOpened = false;\n\n private activeAudio = true;\n private activeVideo = true;\n\n private videoSrcObject: MediaStream | null;\n private parentId: string;\n public isReady: boolean = false;\n public isVideoELementCreated: boolean = false;\n public accessIsAllowed: boolean = false;\n public accessIsDenied: boolean = false;\n\n constructor(private openVidu: OpenViduInternal, private local: boolean, private room: SessionInternal, options: StreamOptions) {\n\n if (options.id) {\n this.id = options.id;\n } else {\n this.id = \"webcam\";\n }\n\n this.connection = options.connection;\n this.recvVideo = options.recvVideo || false;\n this.recvAudio = options.recvAudio || false;\n this.sendVideo = options.sendVideo;\n this.sendAudio = options.sendAudio;\n this.activeAudio = options.activeAudio;\n this.activeVideo = options.activeVideo;\n this.dataChannel = options.data || false;\n this.mediaConstraints = options.mediaConstraints;\n\n this.addEventListener('src-added', (srcEvent) => {\n this.videoSrcObject = srcEvent.srcObject;\n if (this.video) this.video.srcObject = srcEvent.srcObject;\n console.debug(\"Video srcObject [\" + srcEvent.srcObject + \"] added to stream [\" + this.getId() + \"]\");\n });\n }\n\n emitSrcEvent(wrstream) {\n this.ee.emitEvent('src-added', [{\n srcObject: wrstream\n }]);\n }\n\n emitStreamReadyEvent() {\n this.ee.emitEvent('stream-ready'), [{}];\n }\n\n getVideoSrcObject() {\n return this.videoSrcObject;\n }\n\n removeVideo(parentElement: string);\n removeVideo(parentElement: Element);\n removeVideo();\n\n removeVideo(parentElement?) {\n if (typeof parentElement === \"string\") {\n document.getElementById(parentElement)!.removeChild(this.video);\n } else if (parentElement instanceof Element) {\n parentElement.removeChild(this.video);\n }\n else if (!parentElement) {\n if (document.getElementById(this.parentId)) {\n document.getElementById(this.parentId)!.removeChild(this.video);\n }\n }\n }\n\n getVideoElement(): HTMLVideoElement {\n return this.video;\n }\n\n setVideoElement(video: HTMLVideoElement) {\n this.video = video;\n }\n\n\n\n\n\n\n getRecvVideo() {\n return this.recvVideo;\n }\n\n getRecvAudio() {\n return this.recvAudio;\n }\n\n\n subscribeToMyRemote() {\n this.showMyRemote = true;\n }\n\n displayMyRemote() {\n return this.showMyRemote;\n }\n\n mirrorLocalStream(wr) {\n this.showMyRemote = true;\n this.localMirrored = true;\n if (wr) {\n this.wrStream = wr;\n this.emitSrcEvent(this.wrStream);\n }\n }\n\n isLocalMirrored() {\n return this.localMirrored;\n }\n\n getChannelName() {\n return this.getId() + '_' + this.chanId++;\n }\n\n\n isDataChannelEnabled() {\n return this.dataChannel;\n }\n\n\n isDataChannelOpened() {\n return this.dataChannelOpened;\n }\n\n onDataChannelOpen(event) {\n console.debug('Data channel is opened');\n this.dataChannelOpened = true;\n }\n\n onDataChannelClosed(event) {\n console.debug('Data channel is closed');\n this.dataChannelOpened = false;\n }\n\n sendData(data) {\n if (this.wp === undefined) {\n throw new Error('WebRTC peer has not been created yet');\n }\n if (!this.dataChannelOpened) {\n throw new Error('Data channel is not opened');\n }\n console.info(\"Sending through data channel: \" + data);\n this.wp.send(data);\n }\n\n getWrStream() {\n return this.wrStream;\n }\n\n getWebRtcPeer() {\n return this.wp;\n }\n\n addEventListener(eventName: string, listener: any) {\n this.ee.addListener(eventName, listener);\n }\n\n addOnceEventListener(eventName: string, listener: any) {\n this.ee.addOnceListener(eventName, listener);\n }\n\n removeListener(eventName) {\n this.ee.removeAllListeners(eventName);\n }\n\n showSpinner(spinnerParentId: string) {\n let progress = document.createElement('div');\n progress.id = 'progress-' + this.getId();\n progress.style.background = \"center transparent url('img/spinner.gif') no-repeat\";\n let spinnerParent = document.getElementById(spinnerParentId);\n if (spinnerParent) {\n spinnerParent.appendChild(progress);\n }\n }\n\n hideSpinner(spinnerId?: string) {\n spinnerId = (spinnerId === undefined) ? this.getId() : spinnerId;\n hide('progress-' + spinnerId);\n }\n\n playOnlyVideo(parentElement, thumbnailId) {\n\n // TO-DO: check somehow if the stream is audio only, so the element created is