diff --git a/CHANGES.md b/CHANGES.md index 6a619005..f9c0868f 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -9,6 +9,10 @@ - FIX - バグ修正 +## 2021.1.7 +- [ADD] SoraCloseEvent 関連の type を export する + - @yuitowest + ## 2021.1.6 - [FIX] timeline ログに re-answer のログが出力されていなかったので修正する - @yuitowest diff --git a/dist/sora.d.ts b/dist/sora.d.ts index 56b8393c..a9290e83 100644 --- a/dist/sora.d.ts +++ b/dist/sora.d.ts @@ -2,7 +2,7 @@ import ConnectionBase from "./base"; import ConnectionPublisher from "./publisher"; import ConnectionSubscriber from "./subscriber"; import { applyMediaStreamConstraints } from "./helpers"; -import type { AudioCodecType, Callbacks, ConnectionOptions, JSONType, Role, SignalingEvent, SignalingNotifyConnectionCreated, SignalingNotifyConnectionDestroyed, SignalingNotifyConnectionUpdated, SignalingNotifyMessage, SignalingNotifyMetadata, SignalingNotifyNetworkStatus, SignalingNotifySpotlightChanged, SignalingNotifySpotlightFocused, SignalingNotifySpotlightUnfocused, Simulcast, SimulcastRid, SpotlightFocusRid, TimelineEvent, TimelineEventLogType, TransportType, VideoCodecType } from "./types"; +import type { AudioCodecType, Callbacks, ConnectionOptions, JSONType, Role, SignalingEvent, SignalingNotifyConnectionCreated, SignalingNotifyConnectionDestroyed, SignalingNotifyConnectionUpdated, SignalingNotifyMessage, SignalingNotifyMetadata, SignalingNotifyNetworkStatus, SignalingNotifySpotlightChanged, SignalingNotifySpotlightFocused, SignalingNotifySpotlightUnfocused, Simulcast, SimulcastRid, SoraAbendTitle, SoraCloseEvent, SoraCloseEventInitDict, SoraCloseEventType, SpotlightFocusRid, TimelineEvent, TimelineEventLogType, TransportType, VideoCodecType } from "./types"; declare class SoraConnection { signalingUrl: string; debug: boolean; @@ -20,4 +20,4 @@ declare const _default: { }; }; export default _default; -export type { AudioCodecType, Callbacks, ConnectionBase, ConnectionOptions, ConnectionPublisher, ConnectionSubscriber, Role, SignalingEvent, SignalingNotifyConnectionCreated, SignalingNotifyConnectionDestroyed, SignalingNotifyConnectionUpdated, SignalingNotifyMessage, SignalingNotifyMetadata, SignalingNotifyNetworkStatus, SignalingNotifySpotlightChanged, SignalingNotifySpotlightFocused, SignalingNotifySpotlightUnfocused, Simulcast, SimulcastRid, SoraConnection, SpotlightFocusRid, TimelineEvent, TimelineEventLogType, TransportType, VideoCodecType, }; +export type { AudioCodecType, Callbacks, ConnectionBase, ConnectionOptions, ConnectionPublisher, ConnectionSubscriber, Role, SignalingEvent, SignalingNotifyConnectionCreated, SignalingNotifyConnectionDestroyed, SignalingNotifyConnectionUpdated, SignalingNotifyMessage, SignalingNotifyMetadata, SignalingNotifyNetworkStatus, SignalingNotifySpotlightChanged, SignalingNotifySpotlightFocused, SignalingNotifySpotlightUnfocused, Simulcast, SimulcastRid, SoraAbendTitle, SoraCloseEvent, SoraCloseEventInitDict, SoraCloseEventType, SoraConnection, SpotlightFocusRid, TimelineEvent, TimelineEventLogType, TransportType, VideoCodecType, }; diff --git a/dist/sora.js b/dist/sora.js index cdadfe81..b166b4d8 100644 --- a/dist/sora.js +++ b/dist/sora.js @@ -1,7 +1,7 @@ /** * @sora/sdk * undefined - * @version: 2021.1.6 + * @version: 2021.1.7 * @author: Shiguredo Inc. * @license: Apache-2.0 **/ @@ -1599,7 +1599,7 @@ } const message = { type: "connect", - sora_client: "Sora JavaScript SDK 2021.1.6", + sora_client: "Sora JavaScript SDK 2021.1.7", environment: window.navigator.userAgent, role: role, channel_id: channelId, @@ -3516,7 +3516,7 @@ return new SoraConnection(signalingUrl, debug); }, version: function () { - return "2021.1.6"; + return "2021.1.7"; }, helpers: { applyMediaStreamConstraints, diff --git a/dist/sora.min.js b/dist/sora.min.js index 71fde73a..3ad6ba2f 100644 --- a/dist/sora.min.js +++ b/dist/sora.min.js @@ -1,8 +1,8 @@ /** * @sora/sdk * undefined - * @version: 2021.1.6 + * @version: 2021.1.7 * @author: Shiguredo Inc. * @license: Apache-2.0 - **/(function(e,n){"object"==typeof exports&&"undefined"!=typeof module?module.exports=n():"function"==typeof define&&define.amd?define(n):(e="undefined"==typeof globalThis?e||self:globalThis,e.Sora=n())})(this,function(){'use strict';var n=Math.min,t=Math.ceil,a=Math.max;function g(){(()=>{if("undefined"!=typeof global);else if("undefined"!=typeof window)window.global=window;else if("undefined"!=typeof self)self.global=self;else throw new Error("cannot export Go (neither global, window nor self is defined)");if(global.require||"undefined"==typeof require||(global.require=require),!global.fs&&global.require){const e=require("fs");0!==Object.keys(e)&&(global.fs=e)}const e=()=>{const e=new Error("not implemented");return e.code="ENOSYS",e};if(!global.fs){let n="";global.fs={constants:{O_WRONLY:-1,O_RDWR:-1,O_CREAT:-1,O_TRUNC:-1,O_APPEND:-1,O_EXCL:-1},writeSync(e,t){n+=i.decode(t);const a=n.lastIndexOf("\n");return-1!=a&&(console.log(n.substr(0,a)),n=n.substr(a+1)),t.length},write(i,t,a,g,o,l){if(0!==a||g!==t.length||null!==o)return void l(e());const d=this.writeSync(i,t);l(null,d)},chmod(n,i,t){t(e())},chown(n,i,t,a){a(e())},close(n,i){i(e())},fchmod(n,i,t){t(e())},fchown(n,i,t,a){a(e())},fstat(n,i){i(e())},fsync(e,n){n(null)},ftruncate(n,i,t){t(e())},lchown(n,i,t,a){a(e())},link(n,i,t){t(e())},lstat(n,i){i(e())},mkdir(n,i,t){t(e())},open(n,i,t,a){a(e())},read(n,i,t,a,g,o){o(e())},readdir(n,i){i(e())},readlink(n,i){i(e())},rename(n,i,t){t(e())},rmdir(n,i){i(e())},stat(n,i){i(e())},symlink(n,i,t){t(e())},truncate(n,i,t){t(e())},unlink(n,i){i(e())},utimes(n,i,t,a){a(e())}}}if(global.process||(global.process={getuid(){return-1},getgid(){return-1},geteuid(){return-1},getegid(){return-1},getgroups(){throw e()},pid:-1,ppid:-1,umask(){throw e()},cwd(){throw e()},chdir(){throw e()}}),!global.crypto){const e=require("crypto");global.crypto={getRandomValues(n){e.randomFillSync(n)}}}global.performance||(global.performance={now(){const[e,n]=process.hrtime();return 1e3*e+n/1e6}}),global.TextEncoder||(global.TextEncoder=require("util").TextEncoder),global.TextDecoder||(global.TextDecoder=require("util").TextDecoder);const n=new TextEncoder("utf-8"),i=new TextDecoder("utf-8");if(global.Go=class{constructor(){this.argv=["js"],this.env={},this.exit=e=>{0!==e&&console.warn("exit code:",e)},this._exitPromise=new Promise(e=>{this._resolveExitPromise=e}),this._pendingEvent=null,this._scheduledTimeouts=new Map,this._nextCallbackTimeoutID=1;const e=(e,n)=>{var i=Math.floor;this.mem.setUint32(e+0,n,!0),this.mem.setUint32(e+4,i(n/4294967296),!0)},t=e=>{const n=this.mem.getUint32(e+0,!0),i=this.mem.getInt32(e+4,!0);return n+4294967296*i},g=e=>{const n=this.mem.getFloat64(e,!0);if(0!==n){if(!isNaN(n))return n;const i=this.mem.getUint32(e,!0);return this._values[i]}},o=(e,n)=>{if("number"==typeof n&&0!==n)return isNaN(n)?(this.mem.setUint32(e+4,2146959360,!0),void this.mem.setUint32(e,0,!0)):void this.mem.setFloat64(e,n,!0);if(void 0===n)return void this.mem.setFloat64(e,0,!0);let i=this._ids.get(n);void 0===i&&(i=this._idPool.pop(),void 0===i&&(i=this._values.length),this._values[i]=n,this._goRefCounts[i]=0,this._ids.set(n,i)),this._goRefCounts[i]++;let t=0;switch(typeof n){case"object":null!==n&&(t=1);break;case"string":t=2;break;case"symbol":t=3;break;case"function":t=4;}this.mem.setUint32(e+4,2146959360|t,!0),this.mem.setUint32(e,i,!0)},l=e=>{const n=t(e+0),i=t(e+8);return new Uint8Array(this._inst.exports.mem.buffer,n,i)},d=e=>{const n=t(e+0),o=t(e+8),l=Array(o);for(let t=0;t{const n=t(e+0),a=t(e+8);return i.decode(new DataView(this._inst.exports.mem.buffer,n,a))},s=Date.now()-performance.now();this.importObject={go:{"runtime.wasmExit":e=>{const n=this.mem.getInt32(e+8,!0);this.exited=!0,delete this._inst,delete this._values,delete this._goRefCounts,delete this._ids,delete this._idPool,this.exit(n)},"runtime.wasmWrite":e=>{const i=t(e+8),a=t(e+16),g=this.mem.getInt32(e+24,!0);fs.writeSync(i,new Uint8Array(this._inst.exports.mem.buffer,a,g))},"runtime.resetMemoryDataView":()=>{this.mem=new DataView(this._inst.exports.mem.buffer)},"runtime.nanotime1":n=>{e(n+8,1e6*(s+performance.now()))},"runtime.walltime1":n=>{const i=new Date().getTime();e(n+8,i/1e3),this.mem.setInt32(n+16,1e6*(i%1e3),!0)},"runtime.scheduleTimeoutEvent":e=>{const n=this._nextCallbackTimeoutID;this._nextCallbackTimeoutID++,this._scheduledTimeouts.set(n,setTimeout(()=>{for(this._resume();this._scheduledTimeouts.has(n);)console.warn("scheduleTimeoutEvent: missed timeout event"),this._resume()},t(e+8)+1)),this.mem.setInt32(e+16,n,!0)},"runtime.clearTimeoutEvent":e=>{const n=this.mem.getInt32(e+8,!0);clearTimeout(this._scheduledTimeouts.get(n)),this._scheduledTimeouts.delete(n)},"runtime.getRandomData":e=>{crypto.getRandomValues(l(e+8))},"syscall/js.finalizeRef":e=>{const n=this.mem.getUint32(e+8,!0);if(this._goRefCounts[n]--,0===this._goRefCounts[n]){const e=this._values[n];this._values[n]=null,this._ids.delete(e),this._idPool.push(n)}},"syscall/js.stringVal":e=>{o(e+24,c(e+8))},"syscall/js.valueGet":e=>{const n=Reflect.get(g(e+8),c(e+16));e=this._inst.exports.getsp(),o(e+32,n)},"syscall/js.valueSet":e=>{Reflect.set(g(e+8),c(e+16),g(e+32))},"syscall/js.valueDelete":e=>{Reflect.deleteProperty(g(e+8),c(e+16))},"syscall/js.valueIndex":e=>{o(e+24,Reflect.get(g(e+8),t(e+16)))},"syscall/js.valueSetIndex":e=>{Reflect.set(g(e+8),t(e+16),g(e+24))},"syscall/js.valueCall":e=>{try{const n=g(e+8),i=Reflect.get(n,c(e+16)),t=d(e+32),a=Reflect.apply(i,n,t);e=this._inst.exports.getsp(),o(e+56,a),this.mem.setUint8(e+64,1)}catch(n){o(e+56,n),this.mem.setUint8(e+64,0)}},"syscall/js.valueInvoke":e=>{try{const n=g(e+8),i=d(e+16),t=Reflect.apply(n,void 0,i);e=this._inst.exports.getsp(),o(e+40,t),this.mem.setUint8(e+48,1)}catch(n){o(e+40,n),this.mem.setUint8(e+48,0)}},"syscall/js.valueNew":e=>{try{const n=g(e+8),i=d(e+16),t=Reflect.construct(n,i);e=this._inst.exports.getsp(),o(e+40,t),this.mem.setUint8(e+48,1)}catch(n){o(e+40,n),this.mem.setUint8(e+48,0)}},"syscall/js.valueLength":n=>{e(n+16,parseInt(g(n+8).length))},"syscall/js.valuePrepareString":i=>{const t=n.encode(g(i+8)+"");o(i+16,t),e(i+24,t.length)},"syscall/js.valueLoadString":e=>{const n=g(e+8);l(e+16).set(n)},"syscall/js.valueInstanceOf":e=>{this.mem.setUint8(e+24,g(e+8)instanceof g(e+16)?1:0)},"syscall/js.copyBytesToGo":n=>{const i=l(n+8),t=g(n+32);if(!(t instanceof Uint8Array||t instanceof Uint8ClampedArray))return void this.mem.setUint8(n+48,0);const a=t.subarray(0,i.length);i.set(a),e(n+40,a.length),this.mem.setUint8(n+48,1)},"syscall/js.copyBytesToJS":n=>{const i=g(n+8),t=l(n+16);if(!(i instanceof Uint8Array||i instanceof Uint8ClampedArray))return void this.mem.setUint8(n+48,0);const a=t.subarray(0,i.length);i.set(a),e(n+40,a.length),this.mem.setUint8(n+48,1)},debug:e=>{console.log(e)}}}}async run(e){this._inst=e,this.mem=new DataView(this._inst.exports.mem.buffer),this._values=[NaN,0,null,!0,!1,global,this],this._goRefCounts=Array(this._values.length).fill(1/0),this._ids=new Map([[0,1],[null,2],[!0,3],[!1,4],[global,5],[this,6]]),this._idPool=[],this.exited=!1;let i=4096;const t=e=>{const t=i,a=n.encode(e+"\0");return new Uint8Array(this.mem.buffer,i,a.length).set(a),i+=a.length,0!=i%8&&(i+=8-i%8),t},a=this.argv.length,g=[];this.argv.forEach(e=>{g.push(t(e))}),g.push(0);const o=Object.keys(this.env).sort();o.forEach(e=>{g.push(t(`${e}=${this.env[e]}`))}),g.push(0);const l=i;g.forEach(e=>{this.mem.setUint32(i,e,!0),this.mem.setUint32(i+4,0,!0),i+=8}),this._inst.exports.run(a,l),this.exited&&this._resolveExitPromise(),await this._exitPromise}_resume(){if(this.exited)throw new Error("Go program has already exited");this._inst.exports.resume(),this.exited&&this._resolveExitPromise()}_makeFuncWrapper(e){const n=this;return function(){const i={id:e,this:this,args:arguments};return n._pendingEvent=i,n._resume(),i.result}}},global.require&&global.require.main===module&&global.process&&global.process.versions&&!global.process.versions.electron){3>process.argv.length&&(console.error("usage: go_js_wasm_exec [wasm binary] [arguments]"),process.exit(1));const e=new Go;e.argv=process.argv.slice(2),e.env=Object.assign({TMPDIR:require("os").tmpdir()},process.env),e.exit=process.exit,WebAssembly.instantiate(fs.readFileSync(process.argv[2]),e.importObject).then(n=>(process.on("exit",n=>{0!==n||e.exited||(e._pendingEvent={id:0},e._resume())}),e.run(n.instance))).catch(e=>{console.error(e),process.exit(1)})}})()}function o(e,n){n||(n={});var i=de();i.p(e);var t=ce(e,n,2,4);return Ce(t,n),se(t,t.length-4,i.d()),t}function l(e,n){return z((Ie(e),e.subarray(2,-4)),n)}function d(){const e=window.navigator.userAgent.toLocaleLowerCase();if(-1!==e.indexOf("edge"))return"edge";return-1!==e.indexOf("chrome")&&-1===e.indexOf("edge")?"chrome":-1!==e.indexOf("safari")&&-1===e.indexOf("chrome")?"safari":-1===e.indexOf("opera")?-1===e.indexOf("firefox")?null:"firefox":"opera"}function c(){if(!window.RTCRtpSender)return!1;if(!RTCRtpSender.getCapabilities)return!1;const e=RTCRtpSender.getCapabilities("video");if(!e)return!1;const n=e.headerExtensions.map(e=>e.uri),i=["urn:ietf:params:rtp-hdrext:sdes:mid","urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id","urn:ietf:params:rtp-hdrext:sdes:repaired-rtp-stream-id"].every(e=>n.includes(e));return i}function s(){return"safari"===d()}function C(e,n,i,t,a){if("sendrecv"!==n&&"sendonly"!==n&&"recvonly"!==n)throw new Error("Unknown role type");if(null===i||void 0===i)throw new Error("channelId can not be null or undefined");const g={type:"connect",sora_client:"Sora JavaScript SDK 2021.1.6",environment:window.navigator.userAgent,role:n,channel_id:i,sdp:e,audio:!0,video:!0};if(void 0!==t&&(g.metadata=t),"signalingNotifyMetadata"in a&&(g.signaling_notify_metadata=a.signalingNotifyMetadata),"multistream"in a&&!0===a.multistream&&(g.multistream=!0,"spotlight"in a&&(g.spotlight=a.spotlight,"spotlightNumber"in a&&(g.spotlight_number=a.spotlightNumber)),!0===g.spotlight)){const e=["none","r0","r1","r2"];void 0!==a.spotlightFocusRid&&0<=e.indexOf(a.spotlightFocusRid)&&(g.spotlight_focus_rid=a.spotlightFocusRid),void 0!==a.spotlightUnfocusRid&&0<=e.indexOf(a.spotlightUnfocusRid)&&(g.spotlight_unfocus_rid=a.spotlightUnfocusRid)}if("simulcast"in a||"simulcastRid"in a){"simulcast"in a&&!0===a.simulcast&&(g.simulcast=!0);void 0!==a.simulcastRid&&0<=["r0","r1","r2"].indexOf(a.simulcastRid)&&(g.simulcast_rid=a.simulcastRid)}"clientId"in a&&void 0!==a.clientId&&(g.client_id=a.clientId),"dataChannelSignaling"in a&&"boolean"==typeof a.dataChannelSignaling&&(g.data_channel_signaling=a.dataChannelSignaling),"ignoreDisconnectWebSocket"in a&&"boolean"==typeof a.ignoreDisconnectWebSocket&&(g.ignore_disconnect_websocket=a.ignoreDisconnectWebSocket);const o=["audioCodecType","audioBitRate"],l=["audioOpusParamsChannels","audioOpusParamsClockRate","audioOpusParamsMaxplaybackrate","audioOpusParamsStereo","audioOpusParamsSpropStereo","audioOpusParamsMinptime","audioOpusParamsPtime","audioOpusParamsUseinbandfec","audioOpusParamsUsedtx"],d=["videoCodecType","videoBitRate"],s=Object.assign({},a);Object.keys(s).forEach(e=>{"audio"===e&&"boolean"==typeof s[e]||"video"===e&&"boolean"==typeof s[e]||0<=o.indexOf(e)&&null!==s[e]||0<=l.indexOf(e)&&null!==s[e]||0<=d.indexOf(e)&&null!==s[e]||delete s[e]}),void 0!==s.audio&&(g.audio=s.audio);const C=Object.keys(s).some(e=>0<=o.indexOf(e));g.audio&&C&&(g.audio={},"audioCodecType"in s&&(g.audio.codec_type=s.audioCodecType),"audioBitRate"in s&&(g.audio.bit_rate=s.audioBitRate));const I=Object.keys(s).some(e=>0<=l.indexOf(e));g.audio&&I&&("object"!=typeof g.audio&&(g.audio={}),g.audio.opus_params={},"audioOpusParamsChannels"in s&&(g.audio.opus_params.channels=s.audioOpusParamsChannels),"audioOpusParamsClockRate"in s&&(g.audio.opus_params.clock_rate=s.audioOpusParamsClockRate),"audioOpusParamsMaxplaybackrate"in s&&(g.audio.opus_params.maxplaybackrate=s.audioOpusParamsMaxplaybackrate),"audioOpusParamsStereo"in s&&(g.audio.opus_params.stereo=s.audioOpusParamsStereo),"audioOpusParamsSpropStereo"in s&&(g.audio.opus_params.sprop_stereo=s.audioOpusParamsSpropStereo),"audioOpusParamsMinptime"in s&&(g.audio.opus_params.minptime=s.audioOpusParamsMinptime),"audioOpusParamsPtime"in s&&(g.audio.opus_params.ptime=s.audioOpusParamsPtime),"audioOpusParamsUseinbandfec"in s&&(g.audio.opus_params.useinbandfec=s.audioOpusParamsUseinbandfec),"audioOpusParamsUsedtx"in s&&(g.audio.opus_params.usedtx=s.audioOpusParamsUsedtx)),void 0!==s.video&&(g.video=s.video);const r=Object.keys(s).some(e=>0<=d.indexOf(e));if(g.video&&r&&(g.video={},"videoCodecType"in s&&(g.video.codec_type=s.videoCodecType),"videoBitRate"in s&&(g.video.bit_rate=s.videoBitRate)),g.simulcast&&!c()&&"recvonly"!==n)throw new Error("Simulcast can not be used with this browser");if(!0===a.e2ee){if(void 0===g.signaling_notify_metadata&&(g.signaling_notify_metadata={}),null===g.signaling_notify_metadata||"object"!=typeof g.signaling_notify_metadata)throw new Error("E2EE failed. Options signalingNotifyMetadata must be type 'object'");!0===g.video&&(g.video={}),g.video&&(g.video.codec_type="VP8"),g.e2ee=!0}return g}function I(e){if(e.authn_metadata!==void 0)return e.authn_metadata;return void 0===e.metadata?null:e.metadata}function r(e){if(e.data&&Array.isArray(e.data))return e.data;return e.metadata_list&&Array.isArray(e.metadata_list)?e.metadata_list:[]}function m(e){return"object"==typeof e&&null!==e&&"pre_key_bundle"in e?e.pre_key_bundle:null}function A(e,n,i){const t=e=>{if(e&&"object"==typeof e){let n=null;try{n=Object.keys(JSON.parse(JSON.stringify(e)))}catch(e){}n&&Array.isArray(n)?n.forEach(n=>{console.group(n),t(e[n]),console.groupEnd()}):console.info(e)}else console.info(e)};let a="";window.performance&&(a="["+(window.performance.now()/1e3).toFixed(3)+"]"),e&&(a=a+"["+e+"]"),console.info!==void 0&&console.group!==void 0?(console.group(a+" "+n),t(i),console.groupEnd()):console.log(a+" "+n+"\n",i)}function Z(e,n,i){const t=new Event(e);try{t.data=JSON.parse(JSON.stringify(n))}catch(e){t.data=n}return t.transportType=i,t}function u(e){return{binaryType:e.binaryType,bufferedAmount:e.bufferedAmount,bufferedAmountLowThreshold:e.bufferedAmountLowThreshold,id:e.id,label:e.label,maxPacketLifeTime:e.maxPacketLifeTime,maxRetransmits:e.maxRetransmits,negotiated:e.negotiated,ordered:e.ordered,protocol:e.protocol,readyState:e.readyState,reliable:e.reliable}}function b(e,n,i,t,a){const g=new Event(e);try{g.data=JSON.parse(JSON.stringify(n))}catch(e){g.data=n}return g.logType=i,g.dataChannelId=t,g.dataChannelLabel=a,g}class p{constructor(){const e=!!RTCRtpSender.prototype.createEncodedStreams;if(!e)throw new Error("E2EE is not supported in this browser.");this.worker=null,this.onWorkerDisconnect=null}startWorker(){const e=atob("InVzZSBzdHJpY3QiOwovKiBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnMgKi8KY29uc3QgY29ubmVjdGlvbklkTGVuZ3RoID0gMjY7CmZ1bmN0aW9uIGJ5dGVDb3VudChuKSB7CiAgICBpZiAobiA9PSAwKSB7CiAgICAgICAgcmV0dXJuIDE7CiAgICB9CiAgICAvLyBsb2cyNTYoeCkgPSBsb2coeCkgLyBsb2coMjU2KQogICAgcmV0dXJuIE1hdGguZmxvb3IoTWF0aC5sb2cobikgLyBNYXRoLmxvZygyICoqIDgpICsgMSk7Cn0KZnVuY3Rpb24gYXJyYXlCdWZmZXJUb051bWJlcihhcnJheUJ1ZmZlcikgewogICAgLy8gMzJiaXQg44G+44Gn44KS5oOz5a6aIChCaWdJbnQg44G444Gu5pu444GN5o+b44GI5pmC44Gr6KaB5L+u5q2jKQogICAgY29uc3QgbmV3QXJyYXlCdWZmZXIgPSBuZXcgQXJyYXlCdWZmZXIoVWludDMyQXJyYXkuQllURVNfUEVSX0VMRU1FTlQpOwogICAgY29uc3QgbmV3RGF0YVZpZXcgPSBuZXcgRGF0YVZpZXcobmV3QXJyYXlCdWZmZXIpOwogICAgY29uc3QgZGF0YVZpZXcgPSBuZXcgRGF0YVZpZXcoYXJyYXlCdWZmZXIpOwogICAgY29uc3QgcGFkZGluZ0xlbmd0aCA9IFVpbnQzMkFycmF5LkJZVEVTX1BFUl9FTEVNRU5UIC0gZGF0YVZpZXcuYnl0ZUxlbmd0aDsKICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcGFkZGluZ0xlbmd0aDsgaSArPSAxKSB7CiAgICAgICAgbmV3RGF0YVZpZXcuc2V0VWludDgoaSwgMCk7CiAgICB9CiAgICBmb3IgKGxldCBpID0gcGFkZGluZ0xlbmd0aCwgaiA9IDA7IGkgPCBVaW50MzJBcnJheS5CWVRFU19QRVJfRUxFTUVOVDsgaSArPSAxLCBqICs9IDEpIHsKICAgICAgICBuZXdEYXRhVmlldy5zZXRVaW50OChpLCBkYXRhVmlldy5nZXRVaW50OChqKSk7CiAgICB9CiAgICByZXR1cm4gbmV3RGF0YVZpZXcuZ2V0VWludDMyKDApOwp9CmZ1bmN0aW9uIGVuY29kZVNGcmFtZUhlYWRlcihzLCBjb3VudCwga2V5SWQpIHsKICAgIC8vICAwIDEgMiAzIDQgNSA2IDcKICAgIC8vICstKy0rLSstKy0rLSstKy0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSsKICAgIC8vIHxTfExFTiAgfDF8S0xFTiB8ICAgS0lELi4uIChsZW5ndGg9S0xFTikgICAgfCAgICBDVFIuLi4gKGxlbmd0aD1MRU4pICAgIHwKICAgIC8vICstKy0rLSstKy0rLSstKy0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSsKICAgIC8vIFM6IDEgYml0CiAgICAvLyBMRU46IDMgYml0CiAgICAvLyBYOiAxIGJpdAogICAgLy8gS0xFTjogMyBiaXQKICAgIC8vIEtJRDogS0xFTiBieXRlCiAgICAvLyBDVFI6IExFTiBieXRlCiAgICAvLyBUT0RPOiBrZXlJZCAoS0lEKSDjgYwgTnVtYmVyLk1BWF9TQUZFX0lOVEVHRVIsIDcgYnl0ZSDjgpLotoXjgYjjgabjgYTjgZ/loLTlkIjjga/jgqjjg6njg7zjgYvkvovlpJYKICAgIC8vIFRPRE86IGNvdW50IChDVFIpIOOBjCBOdW1iZXIuTUFYX1NBRkVfSU5URUdFUiwgNyBieXRlIOOCkui2heOBiOOBpuOBhOOBn+WgtOWQiOOBr+OCqOODqeODvOOBi+S+i+WklgogICAgaWYgKG1heEtleUlkIDwga2V5SWQgfHwgbWF4Q291bnQgPCBjb3VudCkgewogICAgICAgIHRocm93IG5ldyBFcnJvcigiRVhDRUVERUQtTUFYSU1VTS1CUk9BRENBU1RJTkctVElNRSIpOwogICAgfQogICAgY29uc3Qga2xlbiA9IGJ5dGVDb3VudChrZXlJZCk7CiAgICBjb25zdCBsZW4gPSBieXRlQ291bnQoY291bnQpOwogICAgY29uc3QgaGVhZGVyQnVmZmVyID0gbmV3IEFycmF5QnVmZmVyKDEgKyBrbGVuICsgbGVuKTsKICAgIGNvbnN0IGhlYWRlckRhdGFWaWV3ID0gbmV3IERhdGFWaWV3KGhlYWRlckJ1ZmZlcik7CiAgICAvLyBTLCBMRU4sIDEsIEtMRU4g44GnIDEgYnl0ZQogICAgaGVhZGVyRGF0YVZpZXcuc2V0VWludDgoMCwgKHMgPDwgNykgKyAobGVuIDw8IDQpICsgKDEgPDwgMykgKyBrbGVuKTsKICAgIGNvbnN0IGhlYWRlclVpbnQ4QXJyYXkgPSBuZXcgVWludDhBcnJheShoZWFkZXJCdWZmZXIpOwogICAgY29uc3Qga2V5SWRCdWZmZXIgPSBuZXcgQXJyYXlCdWZmZXIoVWludDMyQXJyYXkuQllURVNfUEVSX0VMRU1FTlQpOwogICAgY29uc3Qga2V5SWREYXRhVmlldyA9IG5ldyBEYXRhVmlldyhrZXlJZEJ1ZmZlcik7CiAgICBrZXlJZERhdGFWaWV3LnNldFVpbnQzMigwLCBrZXlJZCk7CiAgICBjb25zdCBrZXlJZFVpbnQ4QXJyYXkgPSBuZXcgVWludDhBcnJheShrZXlJZEJ1ZmZlcik7CiAgICBoZWFkZXJVaW50OEFycmF5LnNldChrZXlJZFVpbnQ4QXJyYXkuc3ViYXJyYXkoVWludDMyQXJyYXkuQllURVNfUEVSX0VMRU1FTlQgLSBrbGVuKSwgMSk7CiAgICBjb25zdCBjb3VudEJ1ZmZlciA9IG5ldyBBcnJheUJ1ZmZlcihVaW50MzJBcnJheS5CWVRFU19QRVJfRUxFTUVOVCk7CiAgICBjb25zdCBjb3VudERhdGFWaWV3ID0gbmV3IERhdGFWaWV3KGNvdW50QnVmZmVyKTsKICAgIGNvdW50RGF0YVZpZXcuc2V0VWludDMyKDAsIGNvdW50KTsKICAgIGNvbnN0IGNvdW50VWludDhBcnJheSA9IG5ldyBVaW50OEFycmF5KGNvdW50QnVmZmVyKTsKICAgIGhlYWRlclVpbnQ4QXJyYXkuc2V0KGNvdW50VWludDhBcnJheS5zdWJhcnJheShVaW50MzJBcnJheS5CWVRFU19QRVJfRUxFTUVOVCAtIGxlbiksIGtsZW4gKyAxKTsKICAgIHJldHVybiBoZWFkZXJVaW50OEFycmF5Owp9CmZ1bmN0aW9uIHNwbGl0SGVhZGVyKHNmcmFtZSkgewogICAgY29uc3Qgc2ZyYW1lRGF0YVZpZXcgPSBuZXcgRGF0YVZpZXcoc2ZyYW1lKTsKICAgIGNvbnN0IGhlYWRlciA9IHNmcmFtZURhdGFWaWV3LmdldFVpbnQ4KDApOwogICAgY29uc3QgbGVuID0gKGhlYWRlciAmIDB4NzApID4+IDQ7CiAgICBjb25zdCBrbGVuID0gaGVhZGVyICYgMHgwNzsKICAgIGNvbnN0IHNmcmFtZUhlYWRlckxlbmd0aCA9IDEgKyBrbGVuICsgbGVuOwogICAgY29uc3Qgc2ZyYW1lSGVhZGVyID0gc2ZyYW1lLnNsaWNlKDAsIHNmcmFtZUhlYWRlckxlbmd0aCk7CiAgICBpZiAoc2ZyYW1lSGVhZGVyLmJ5dGVMZW5ndGggPCBzZnJhbWVIZWFkZXJMZW5ndGgpIHsKICAgICAgICB0aHJvdyBuZXcgRXJyb3IoIlVORVhQRUNURUQtU0ZSQU1FLUxFTkdUSCIpOwogICAgfQogICAgY29uc3QgY29ubmVjdGlvbklkID0gc2ZyYW1lLnNsaWNlKHNmcmFtZUhlYWRlckxlbmd0aCwgc2ZyYW1lSGVhZGVyTGVuZ3RoICsgY29ubmVjdGlvbklkTGVuZ3RoKTsKICAgIGNvbnN0IGVuY3J5cHRlZEZyYW1lID0gc2ZyYW1lLnNsaWNlKHNmcmFtZUhlYWRlckxlbmd0aCArIGNvbm5lY3Rpb25JZExlbmd0aCwgc2ZyYW1lLmJ5dGVMZW5ndGgpOwogICAgcmV0dXJuIFtzZnJhbWVIZWFkZXIsIGNvbm5lY3Rpb25JZCwgZW5jcnlwdGVkRnJhbWVdOwp9CmZ1bmN0aW9uIHBhcnNlU0ZyYW1lSGVhZGVyKHNmcmFtZUhlYWRlcikgewogICAgY29uc3Qgc2ZyYW1lSGVhZGVyRGF0YVZpZXcgPSBuZXcgRGF0YVZpZXcoc2ZyYW1lSGVhZGVyKTsKICAgIGNvbnN0IGhlYWRlciA9IHNmcmFtZUhlYWRlckRhdGFWaWV3LmdldFVpbnQ4KDApOwogICAgY29uc3QgcyA9IChoZWFkZXIgJiAweDgwKSA+PiA3OwogICAgY29uc3QgbGVuID0gKGhlYWRlciAmIDB4NzApID4+IDQ7CiAgICBjb25zdCB4ID0gKGhlYWRlciAmIDB4MDgpID4+IDM7CiAgICBjb25zdCBrbGVuID0gaGVhZGVyICYgMHgwNzsKICAgIC8vIHggZmxhZwogICAgaWYgKHggIT09IDEpIHsKICAgICAgICB0aHJvdyBuZXcgRXJyb3IoIlVORVhQRUNURUQtWC1GTEFHIik7CiAgICB9CiAgICBjb25zdCBoZWFkZXJMZW5ndGggPSAxICsga2xlbiArIGxlbjsKICAgIGlmIChzZnJhbWVIZWFkZXJEYXRhVmlldy5ieXRlTGVuZ3RoIDwgaGVhZGVyTGVuZ3RoKSB7CiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCJVTkVYUEVDVEVELVNGUkFNRS1IRUFERVItTEVOR1RIIik7CiAgICB9CiAgICBjb25zdCBrZXlJZEJ1ZmZlciA9IHNmcmFtZUhlYWRlci5zbGljZSgxLCAxICsga2xlbik7CiAgICBjb25zdCBrZXlJZCA9IGFycmF5QnVmZmVyVG9OdW1iZXIoa2V5SWRCdWZmZXIpOwogICAgY29uc3QgY291bnRCdWZmZXIgPSBzZnJhbWVIZWFkZXIuc2xpY2UoMSArIGtsZW4sIGhlYWRlckxlbmd0aCk7CiAgICBjb25zdCBjb3VudCA9IGFycmF5QnVmZmVyVG9OdW1iZXIoY291bnRCdWZmZXIpOwogICAgcmV0dXJuIFtzLCBjb3VudCwga2V5SWRdOwp9Ci8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC90cmlwbGUtc2xhc2gtcmVmZXJlbmNlLCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnMgKi8KLy8vIDxyZWZlcmVuY2UgcGF0aD0iLi9zZnJhbWUudHMiLz4KLy8gVE9ETzog5omx44GG5pWw5YCk44GM5aSn44GN44GE566H5omA44Gn44GvIE51bWJlciDjgYvjgokgQmlnSW50IOOBq+e9ruOBjeaPm+OBiOOCiwovLyBUT0RPOiBCaWdJbnQg44Gr572u44GN5o+b44GI44KL6Zqb44Gr5aSJ5pu044GZ44KLCmNvbnN0IG1heEtleUlkID0gMiAqKiAzMjsKY29uc3QgbWF4Q291bnQgPSAyICoqIDMyOwpjb25zdCBzZWxmRGVyaXZlS2V5TWFwID0gbmV3IE1hcCgpOwpjb25zdCBjb3VudE1hcCA9IG5ldyBNYXAoKTsKY29uc3Qgd3JpdGVJVk1hcCA9IG5ldyBNYXAoKTsKY29uc3QgcmVtb3RlRGVyaXZlS2V5TWFwID0gbmV3IE1hcCgpOwpjb25zdCBsYXRlc3RSZW1vdGVLZXlJZE1hcCA9IG5ldyBNYXAoKTsKY29uc3QgbGl0dGxlRW5kaWFuID0gdHJ1ZTsKY29uc3QgYmlnRW5kaWFuID0gIWxpdHRsZUVuZGlhbjsKY29uc3QgdGV4dEVuY29kZXIgPSBuZXcgVGV4dEVuY29kZXIoKTsKY29uc3QgdGV4dERlY29kZXIgPSBuZXcgVGV4dERlY29kZXIoKTsKLy8gVlA4IOOBruOBvwovLyBUT0RPKG5ha2FpKTogVlA5IC8gQVYxIOOCguWwhuadpeeahOOBq+WvvuW/nOOCguiAg+OBiOOCiwpjb25zdCB1bmVuY3J5cHRlZEJ5dGVzID0gewogICAgLy8gSSDjg5Xjg6zjg7zjg6AKICAgIGtleTogMTAsCiAgICAvLyDpnZ4gSSDjg5Xjg6zjg7zjg6AKICAgIGRlbHRhOiAzLAogICAgLy8g44Kq44O844OH44Kj44KqCiAgICB1bmRlZmluZWQ6IDEsCn07CmZ1bmN0aW9uIGdldENvdW50KGNvbm5lY3Rpb25JZCkgewogICAgcmV0dXJuIGNvdW50TWFwLmdldChjb25uZWN0aW9uSWQpIHx8IDA7Cn0KZnVuY3Rpb24gc2V0Q291bnQoY29ubmVjdGlvbklkLCBjb3VudCkgewogICAgcmV0dXJuIGNvdW50TWFwLnNldChjb25uZWN0aW9uSWQsIGNvdW50KTsKfQpmdW5jdGlvbiBnZXRSZW1vdGVEZXJpdmVLZXkoY29ubmVjdGlvbklkLCBrZXlJZCkgewogICAgaWYgKCFyZW1vdGVEZXJpdmVLZXlNYXAuaGFzKGNvbm5lY3Rpb25JZCkpIHsKICAgICAgICB0aHJvdyBuZXcgRXJyb3IoIlJFTU9URS1ERVJJVkVLRVktTUFQLU5PVC1GT1VORCIpOwogICAgfQogICAgY29uc3QgZGVyaXZlS2V5TWFwID0gcmVtb3RlRGVyaXZlS2V5TWFwLmdldChjb25uZWN0aW9uSWQpOwogICAgaWYgKCFkZXJpdmVLZXlNYXApIHsKICAgICAgICByZXR1cm47CiAgICB9CiAgICByZXR1cm4gZGVyaXZlS2V5TWFwLmdldChrZXlJZCk7Cn0KZnVuY3Rpb24gc2V0UmVtb3RlRGVyaXZlS2V5KGNvbm5lY3Rpb25JZCwga2V5SWQsIGRlcml2ZUtleSkgewogICAgbGV0IGRlcml2ZUtleU1hcCA9IHJlbW90ZURlcml2ZUtleU1hcC5nZXQoY29ubmVjdGlvbklkKTsKICAgIGlmICghZGVyaXZlS2V5TWFwKSB7CiAgICAgICAgZGVyaXZlS2V5TWFwID0gbmV3IE1hcCgpOwogICAgfQogICAgZGVyaXZlS2V5TWFwLnNldChrZXlJZCwgZGVyaXZlS2V5KTsKICAgIHJlbW90ZURlcml2ZUtleU1hcC5zZXQoY29ubmVjdGlvbklkLCBkZXJpdmVLZXlNYXApOwp9CmZ1bmN0aW9uIHNldExhdGVzdFJlbW90ZUtleUlkKGNvbm5lY3Rpb25JZCwga2V5SWQpIHsKICAgIGNvbnN0IGxhdGVzdFJlbW90ZUtleUlkID0gbGF0ZXN0UmVtb3RlS2V5SWRNYXAuZ2V0KGNvbm5lY3Rpb25JZCk7CiAgICBpZiAobGF0ZXN0UmVtb3RlS2V5SWQpIHsKICAgICAgICBpZiAobGF0ZXN0UmVtb3RlS2V5SWQgPCBrZXlJZCkgewogICAgICAgICAgICBsYXRlc3RSZW1vdGVLZXlJZE1hcC5zZXQoY29ubmVjdGlvbklkLCBrZXlJZCk7CiAgICAgICAgfQogICAgfQogICAgZWxzZSB7CiAgICAgICAgbGF0ZXN0UmVtb3RlS2V5SWRNYXAuc2V0KGNvbm5lY3Rpb25JZCwga2V5SWQpOwogICAgfQp9CmZ1bmN0aW9uIHJlbW92ZU9sZFJlbW90ZURlcml2ZUtleXMoKSB7CiAgICBsYXRlc3RSZW1vdGVLZXlJZE1hcC5mb3JFYWNoKChsYXRlc3RLZXlJZCwgY29ubmVjdGlvbklkKSA9PiB7CiAgICAgICAgY29uc3QgZGVyaXZlS2V5TWFwID0gcmVtb3RlRGVyaXZlS2V5TWFwLmdldChjb25uZWN0aW9uSWQpOwogICAgICAgIGlmIChkZXJpdmVLZXlNYXApIHsKICAgICAgICAgICAgZGVyaXZlS2V5TWFwLmZvckVhY2goKF8sIGtleUlkKSA9PiB7CiAgICAgICAgICAgICAgICBpZiAobGF0ZXN0S2V5SWQgIT09IGtleUlkKSB7CiAgICAgICAgICAgICAgICAgICAgZGVyaXZlS2V5TWFwLmRlbGV0ZShrZXlJZCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0pOwogICAgICAgIH0KICAgIH0pOwp9CmZ1bmN0aW9uIHJlbW92ZURlcml2ZUtleShjb25uZWN0aW9uSWQpIHsKICAgIGxhdGVzdFJlbW90ZUtleUlkTWFwLmRlbGV0ZShjb25uZWN0aW9uSWQpOwogICAgcmVtb3RlRGVyaXZlS2V5TWFwLmRlbGV0ZShjb25uZWN0aW9uSWQpOwp9CmZ1bmN0aW9uIGdldExhdGVzdFNlbGZEZXJpdmVLZXkoKSB7CiAgICBjb25zdCBkZXJpdmVLZXkgPSBzZWxmRGVyaXZlS2V5TWFwLmdldCgibGF0ZXN0Iik7CiAgICBpZiAoIWRlcml2ZUtleSkgewogICAgICAgIHRocm93IG5ldyBFcnJvcigiTEFURVNULVNFTEYtREVSSVZFS0VZLU5PVF9GT1VORCIpOwogICAgfQogICAgcmV0dXJuIGRlcml2ZUtleTsKfQpmdW5jdGlvbiBzZXRTZWxmRGVyaXZlS2V5KGNvbm5lY3Rpb25JZCwga2V5SWQsIGRlcml2ZUtleSkgewogICAgY29uc3QgY3VycmVudFNlbGZEZXJpdmVLZXkgPSBzZWxmRGVyaXZlS2V5TWFwLmdldCgibGF0ZXN0Iik7CiAgICBpZiAoY3VycmVudFNlbGZEZXJpdmVLZXkpIHsKICAgICAgICBpZiAoY3VycmVudFNlbGZEZXJpdmVLZXlbImtleUlkIl0gPCBrZXlJZCkgewogICAgICAgICAgICBjb25zdCBuZXh0U2VsZkRlcml2ZUtleSA9IHsgY29ubmVjdGlvbklkLCBrZXlJZCwgZGVyaXZlS2V5IH07CiAgICAgICAgICAgIHNlbGZEZXJpdmVLZXlNYXAuc2V0KCJsYXRlc3QiLCBuZXh0U2VsZkRlcml2ZUtleSk7CiAgICAgICAgfQogICAgfQogICAgZWxzZSB7CiAgICAgICAgY29uc3QgbmV4dFNlbGZEZXJpdmVLZXkgPSB7IGNvbm5lY3Rpb25JZCwga2V5SWQsIGRlcml2ZUtleSB9OwogICAgICAgIHNlbGZEZXJpdmVLZXlNYXAuc2V0KCJsYXRlc3QiLCBuZXh0U2VsZkRlcml2ZUtleSk7CiAgICB9Cn0KZnVuY3Rpb24gc2lsZW5jZUZyYW1lKGVuY29kZWRGcmFtZSkgewogICAgLy8gY29ubmVjdGlvbi5jcmVhdGVkLCByZWNlaXZlTWVzc2FnZSDlj5fkv6HliY3jga7loLTlkIgKICAgIGlmIChlbmNvZGVkRnJhbWUudHlwZSA9PT0gdW5kZWZpbmVkKSB7CiAgICAgICAgLy8g6Z+z5aOw44Gv5pqX5Y+35YyW44Gv44GE44KL44Go6IGe44GR44Gf44KC44Gu44GY44KD44Gq44GE44Gu44Gn572u44GN5o+b44GI44KLCiAgICAgICAgY29uc3QgbmV3RGF0YSA9IG5ldyBBcnJheUJ1ZmZlcigzKTsKICAgICAgICBjb25zdCBuZXdVaW50OCA9IG5ldyBVaW50OEFycmF5KG5ld0RhdGEpOwogICAgICAgIC8vIE9wdXMg44K144Kk44Os44Oz44K544OV44Os44O844OgCiAgICAgICAgbmV3VWludDguc2V0KFsweGQ4LCAweGZmLCAweGZlXSk7CiAgICAgICAgZW5jb2RlZEZyYW1lLmRhdGEgPSBuZXdEYXRhOwogICAgfQogICAgZWxzZSB7CiAgICAgICAgLy8g5pig5YOP44GM5q2j5bi444GY44KD44Gq44GE44Gf44KBIFBMSSDjgrnjg4jjg7zjg6DjgYznmbrnlJ/jgZfjgabjgZfjgb7jgYYKICAgICAgICAvLyDjgZ3jga7jgZ/jgoEgMzIweDI0MCDjga7nnJ/jgaPpu5LjgarnlLvpnaLjgavnva7jgY3mj5vjgYjjgosKICAgICAgICBjb25zdCBuZXdEYXRhID0gbmV3IEFycmF5QnVmZmVyKDYwKTsKICAgICAgICBjb25zdCBuZXdVaW50OCA9IG5ldyBVaW50OEFycmF5KG5ld0RhdGEpOwogICAgICAgIC8vIHByZXR0aWVyLWlnbm9yZQogICAgICAgIG5ld1VpbnQ4LnNldChbMHhiMCwgMHgwNSwgMHgwMCwgMHg5ZCwgMHgwMSwgMHgyYSwgMHhhMCwgMHgwMCwgMHg1YSwgMHgwMCwKICAgICAgICAgICAgMHgzOSwgMHgwMywgMHgwMCwgMHgwMCwgMHgxYywgMHgyMiwgMHgxNiwgMHgxNiwgMHgyMiwgMHg2NiwKICAgICAgICAgICAgMHgxMiwgMHgyMCwgMHgwNCwgMHg5MCwgMHg0MCwgMHgwMCwgMHhjNSwgMHgwMSwgMHhlMCwgMHg3YywKICAgICAgICAgICAgMHg0ZCwgMHgyZiwgMHhmYSwgMHhkZCwgMHg0ZCwgMHhhNSwgMHg3ZiwgMHg4OSwgMHhhNSwgMHhmZiwKICAgICAgICAgICAgMHg1YiwgMHhhOSwgMHhiNCwgMHhhZiwgMHhmMSwgMHgzNCwgMHhiZiwgMHhlYiwgMHg3NSwgMHgzNiwKICAgICAgICAgICAgMHg5NSwgMHhmZSwgMHgyNiwgMHg5NiwgMHg2MCwgMHhmZSwgMHhmZiwgMHhiYSwgMHhmZiwgMHg0MCwKICAgICAgICBdKTsKICAgICAgICBlbmNvZGVkRnJhbWUuZGF0YSA9IG5ld0RhdGE7CiAgICB9CiAgICByZXR1cm4gZW5jb2RlZEZyYW1lOwp9CmZ1bmN0aW9uIHNldFdyaXRlSVYoY29ubmVjdGlvbklkLCBrZXlJZCwgd3JpdGVJVikgewogICAgY29uc3Qga2V5ID0gW2Nvbm5lY3Rpb25JZCwga2V5SWQudG9TdHJpbmcoKV0uam9pbigiOiIpOwogICAgd3JpdGVJVk1hcC5zZXQoa2V5LCB3cml0ZUlWKTsKfQpmdW5jdGlvbiBnZXRXcml0ZUlWKGNvbm5lY3Rpb25JZCwga2V5SWQpIHsKICAgIGNvbnN0IGtleSA9IFtjb25uZWN0aW9uSWQsIGtleUlkLnRvU3RyaW5nKCldLmpvaW4oIjoiKTsKICAgIHJldHVybiB3cml0ZUlWTWFwLmdldChrZXkpOwp9CmZ1bmN0aW9uIGdlbmVyYXRlSVYoY291bnQsIGNvbm5lY3Rpb25JZCwga2V5SWQpIHsKICAgIC8vIFRPRE86IGtleUlkIOOBjCBOdW1iZXIuTUFYX1NBRkVfSU5URUdFUiwgNyBieXRlIOOCkui2heOBiOOBpuOBhOOBn+WgtOWQiOOBr+OCqOODqeODvOOBi+S+i+WklgogICAgLy8gVE9ETzogY291bnQg44GMIE51bWJlci5NQVhfU0FGRV9JTlRFR0VSLCA3IGJ5dGUg44KS6LaF44GI44Gm44GE44Gf5aC05ZCI44Gv44Ko44Op44O844GL5L6L5aSWCiAgICAvLyAzMiBiaXQg44G+44GnCiAgICBpZiAobWF4S2V5SWQgPCBrZXlJZCB8fCBtYXhDb3VudCA8IGNvdW50KSB7CiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCJFWENFRURFRC1NQVhJTVVNLUJST0FEQ0FTVElORy1USU1FIik7CiAgICB9CiAgICBjb25zdCB3cml0ZUlWID0gZ2V0V3JpdGVJVihjb25uZWN0aW9uSWQsIGtleUlkKTsKICAgIGlmICghd3JpdGVJVikgewogICAgICAgIHRocm93IG5ldyBFcnJvcigiV1JJVEVJVi1OT1QtRk9VTkQiKTsKICAgIH0KICAgIGNvbnN0IHBhZGRpbmdMZW5ndGggPSBObiAtIFVpbnQzMkFycmF5LkJZVEVTX1BFUl9FTEVNRU5UOwogICAgY29uc3QgY291bnRXaXRoUGFkZGluZ0J1ZmZlciA9IG5ldyBBcnJheUJ1ZmZlcihObik7CiAgICBjb25zdCBjb3VudFdpdGhQYWRkaW5nRGF0YVZpZXcgPSBuZXcgRGF0YVZpZXcoY291bnRXaXRoUGFkZGluZ0J1ZmZlcik7CiAgICBjb3VudFdpdGhQYWRkaW5nRGF0YVZpZXcuc2V0VWludDMyKHBhZGRpbmdMZW5ndGgsIGNvdW50LCBiaWdFbmRpYW4pOwogICAgY29uc3QgaXYgPSBuZXcgVWludDhBcnJheShObik7CiAgICBjb25zdCBjb3VudFdpdGhQYWRkaW5nID0gbmV3IFVpbnQ4QXJyYXkoY291bnRXaXRoUGFkZGluZ0J1ZmZlcik7CiAgICBmb3IgKGxldCBpID0gMDsgaSA8IE5uOyBpKyspIHsKICAgICAgICBpdltpXSA9IHdyaXRlSVZbaV0gXiBjb3VudFdpdGhQYWRkaW5nW2ldOwogICAgfQogICAgcmV0dXJuIGl2Owp9CmZ1bmN0aW9uIHBhcnNlUGF5bG9hZChwYXlsb2FkVHlwZSwgcGF5bG9hZCkgewogICAgcmV0dXJuIFsKICAgICAgICBuZXcgVWludDhBcnJheShwYXlsb2FkLCAwLCB1bmVuY3J5cHRlZEJ5dGVzW3BheWxvYWRUeXBlXSksCiAgICAgICAgbmV3IFVpbnQ4QXJyYXkocGF5bG9hZCwgdW5lbmNyeXB0ZWRCeXRlc1twYXlsb2FkVHlwZV0pLAogICAgXTsKfQpmdW5jdGlvbiBlbmNvZGVGcmFtZUFkZChoZWFkZXIsIHNmcmFtZUhlYWRlciwgY29ubmVjdGlvbklkKSB7CiAgICBjb25zdCBjb25uZWN0aW9uSWREYXRhID0gdGV4dEVuY29kZXIuZW5jb2RlKGNvbm5lY3Rpb25JZCk7CiAgICBjb25zdCBmcmFtZUFkZCA9IG5ldyBVaW50OEFycmF5KGhlYWRlci5ieXRlTGVuZ3RoICsgc2ZyYW1lSGVhZGVyLmJ5dGVMZW5ndGggKyBjb25uZWN0aW9uSWREYXRhLmJ5dGVMZW5ndGgpOwogICAgZnJhbWVBZGQuc2V0KGhlYWRlciwgMCk7CiAgICBmcmFtZUFkZC5zZXQoc2ZyYW1lSGVhZGVyLCBoZWFkZXIuYnl0ZUxlbmd0aCk7CiAgICBmcmFtZUFkZC5zZXQoY29ubmVjdGlvbklkRGF0YSwgaGVhZGVyLmJ5dGVMZW5ndGggKyBzZnJhbWVIZWFkZXIuYnl0ZUxlbmd0aCk7CiAgICByZXR1cm4gZnJhbWVBZGQ7Cn0KYXN5bmMgZnVuY3Rpb24gZW5jcnlwdEZ1bmN0aW9uKGVuY29kZWRGcmFtZSwgY29udHJvbGxlcikgewogICAgY29uc3QgeyBjb25uZWN0aW9uSWQsIGtleUlkLCBkZXJpdmVLZXkgfSA9IGdldExhdGVzdFNlbGZEZXJpdmVLZXkoKTsKICAgIGlmICghZGVyaXZlS2V5KSB7CiAgICAgICAgcmV0dXJuOwogICAgfQogICAgY29uc3QgY3VycmVudENvdW50ID0gZ2V0Q291bnQoY29ubmVjdGlvbklkKTsKICAgIC8vIGNvdW50IOOBjCAzMiBiaXQg5Lul5LiK44Gu5aC05ZCI44Gv5YGc5q2i44GZ44KLCiAgICBpZiAoY3VycmVudENvdW50ID4gbWF4Q291bnQpIHsKICAgICAgICBwb3N0TWVzc2FnZSh7IHR5cGU6ICJkaXNjb25uZWN0IiB9KTsKICAgIH0KICAgIGNvbnN0IGl2ID0gZ2VuZXJhdGVJVihjdXJyZW50Q291bnQsIGNvbm5lY3Rpb25JZCwga2V5SWQpOwogICAgaWYgKCFpdikgewogICAgICAgIHJldHVybjsKICAgIH0KICAgIGNvbnN0IFtoZWFkZXIsIHBheWxvYWRdID0gcGFyc2VQYXlsb2FkKGVuY29kZWRGcmFtZS50eXBlLCBlbmNvZGVkRnJhbWUuZGF0YSk7CiAgICBjb25zdCBzZnJhbWVIZWFkZXIgPSBlbmNvZGVTRnJhbWVIZWFkZXIoMCwgY3VycmVudENvdW50LCBrZXlJZCk7CiAgICBjb25zdCBmcmFtZUFkZCA9IGVuY29kZUZyYW1lQWRkKGhlYWRlciwgc2ZyYW1lSGVhZGVyLCBjb25uZWN0aW9uSWQpOwogICAgY3J5cHRvLnN1YnRsZQogICAgICAgIC5lbmNyeXB0KHsKICAgICAgICBuYW1lOiAiQUVTLUdDTSIsCiAgICAgICAgaXY6IGl2LAogICAgICAgIC8vIOaal+WPt+WMluOBleOCjOOBpuOBhOOBquOBhOmDqOWIhgogICAgICAgIGFkZGl0aW9uYWxEYXRhOiBmcmFtZUFkZCwKICAgIH0sIGRlcml2ZUtleSwgcGF5bG9hZCkKICAgICAgICAudGhlbigoY2lwaGVyVGV4dCkgPT4gewogICAgICAgIGNvbnN0IG5ld0RhdGEgPSBuZXcgQXJyYXlCdWZmZXIoZnJhbWVBZGQuYnl0ZUxlbmd0aCArIGNpcGhlclRleHQuYnl0ZUxlbmd0aCk7CiAgICAgICAgY29uc3QgbmV3RGF0YVVpbnQ4ID0gbmV3IFVpbnQ4QXJyYXkobmV3RGF0YSk7CiAgICAgICAgbmV3RGF0YVVpbnQ4LnNldChmcmFtZUFkZCwgMCk7CiAgICAgICAgbmV3RGF0YVVpbnQ4LnNldChuZXcgVWludDhBcnJheShjaXBoZXJUZXh0KSwgZnJhbWVBZGQuYnl0ZUxlbmd0aCk7CiAgICAgICAgZW5jb2RlZEZyYW1lLmRhdGEgPSBuZXdEYXRhOwogICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZShlbmNvZGVkRnJhbWUpOwogICAgfSk7CiAgICBzZXRDb3VudChjb25uZWN0aW9uSWQsIGN1cnJlbnRDb3VudCArIDEpOwp9CmFzeW5jIGZ1bmN0aW9uIGRlY3J5cHRGdW5jdGlvbihlbmNvZGVkRnJhbWUsIGNvbnRyb2xsZXIpIHsKICAgIC8vIOepuuODleODrOODvOODoOWvvuW/nAogICAgaWYgKGVuY29kZWRGcmFtZS5kYXRhLmJ5dGVMZW5ndGggPCAxKSB7CiAgICAgICAgcmV0dXJuOwogICAgfQogICAgdHJ5IHsKICAgICAgICBjb25zdCBmcmFtZU1ldGFkYXRhQnVmZmVyID0gZW5jb2RlZEZyYW1lLmRhdGEuc2xpY2UoMCwgdW5lbmNyeXB0ZWRCeXRlc1tlbmNvZGVkRnJhbWUudHlwZV0pOwogICAgICAgIGNvbnN0IGZyYW1lTWV0YWRhdGEgPSBuZXcgVWludDhBcnJheShmcmFtZU1ldGFkYXRhQnVmZmVyKTsKICAgICAgICBjb25zdCBbc2ZyYW1lSGVhZGVyQnVmZmVyLCBjb25uZWN0aW9uSWRCdWZmZXIsIGVuY3J5cHRlZEZyYW1lQnVmZmVyXSA9IHNwbGl0SGVhZGVyKGVuY29kZWRGcmFtZS5kYXRhLnNsaWNlKHVuZW5jcnlwdGVkQnl0ZXNbZW5jb2RlZEZyYW1lLnR5cGVdKSk7CiAgICAgICAgY29uc3Qgc2ZyYW1lSGVhZGVyID0gbmV3IFVpbnQ4QXJyYXkoc2ZyYW1lSGVhZGVyQnVmZmVyKTsKICAgICAgICBjb25zdCBjb25uZWN0aW9uSWQgPSB0ZXh0RGVjb2Rlci5kZWNvZGUoY29ubmVjdGlvbklkQnVmZmVyKTsKICAgICAgICBjb25zdCBbcywgY291bnQsIGtleUlkXSA9IHBhcnNlU0ZyYW1lSGVhZGVyKHNmcmFtZUhlYWRlckJ1ZmZlcik7CiAgICAgICAgLy8g5LuK5Zue44GvIHMgZmxhZyDjga8gMCDjga7jgb8KICAgICAgICBpZiAocyAhPT0gMCkgewogICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoIlVORVhQRUNURUQtUy1GTEFHIik7CiAgICAgICAgfQogICAgICAgIGNvbnN0IGRlcml2ZUtleSA9IGdldFJlbW90ZURlcml2ZUtleShjb25uZWN0aW9uSWQsIGtleUlkKTsKICAgICAgICBpZiAoIWRlcml2ZUtleSkgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgIGNvbnN0IGl2ID0gZ2VuZXJhdGVJVihjb3VudCwgY29ubmVjdGlvbklkLCBrZXlJZCk7CiAgICAgICAgaWYgKCFpdikgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgIGNvbnN0IGZyYW1lQWRkID0gZW5jb2RlRnJhbWVBZGQoZnJhbWVNZXRhZGF0YSwgc2ZyYW1lSGVhZGVyLCBjb25uZWN0aW9uSWQpOwogICAgICAgIGNyeXB0by5zdWJ0bGUKICAgICAgICAgICAgLmRlY3J5cHQoewogICAgICAgICAgICBuYW1lOiAiQUVTLUdDTSIsCiAgICAgICAgICAgIGl2OiBpdiwKICAgICAgICAgICAgYWRkaXRpb25hbERhdGE6IGZyYW1lQWRkLAogICAgICAgIH0sIGRlcml2ZUtleSwgbmV3IFVpbnQ4QXJyYXkoZW5jcnlwdGVkRnJhbWVCdWZmZXIpKQogICAgICAgICAgICAudGhlbigocGxhaW5UZXh0KSA9PiB7CiAgICAgICAgICAgIGNvbnN0IG5ld0RhdGEgPSBuZXcgQXJyYXlCdWZmZXIoZnJhbWVNZXRhZGF0YUJ1ZmZlci5ieXRlTGVuZ3RoICsgcGxhaW5UZXh0LmJ5dGVMZW5ndGgpOwogICAgICAgICAgICBjb25zdCBuZXdVaW50OCA9IG5ldyBVaW50OEFycmF5KG5ld0RhdGEpOwogICAgICAgICAgICBuZXdVaW50OC5zZXQobmV3IFVpbnQ4QXJyYXkoZnJhbWVNZXRhZGF0YUJ1ZmZlciwgMCwgdW5lbmNyeXB0ZWRCeXRlc1tlbmNvZGVkRnJhbWUudHlwZV0pKTsKICAgICAgICAgICAgbmV3VWludDguc2V0KG5ldyBVaW50OEFycmF5KHBsYWluVGV4dCksIHVuZW5jcnlwdGVkQnl0ZXNbZW5jb2RlZEZyYW1lLnR5cGVdKTsKICAgICAgICAgICAgZW5jb2RlZEZyYW1lLmRhdGEgPSBuZXdEYXRhOwogICAgICAgICAgICBjb250cm9sbGVyLmVucXVldWUoZW5jb2RlZEZyYW1lKTsKICAgICAgICB9KTsKICAgIH0KICAgIGNhdGNoIChlKSB7CiAgICAgICAgLy8g5oOz5a6a5aSW44Gu44OR44Kx44OD44OI44OV44Kp44O844Oe44OD44OI44KS5Y+X5L+h44GX44Gf5aC05ZCICiAgICAgICAgY29udHJvbGxlci5lbnF1ZXVlKHNpbGVuY2VGcmFtZShlbmNvZGVkRnJhbWUpKTsKICAgIH0KfQovKiBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvdHJpcGxlLXNsYXNoLXJlZmVyZW5jZSAqLwovLy8gPHJlZmVyZW5jZSBwYXRoPSIuL2UyZWUudHMiLz4KLy8gbm9uY2Ug44K144Kk44K6CmNvbnN0IE5uID0gMTI7Ci8vIGtleSDjgrXjgqTjgroKY29uc3QgTmsgPSAxNjsKLy8ga2V5IOOCteOCpOOCuu+8iGJpdO+8iQpjb25zdCBrZXlMZW5ndGggPSBOayAqIDg7CmFzeW5jIGZ1bmN0aW9uIGdlbmVyYXRlRGVyaXZlS2V5KG1hdGVyaWFsKSB7CiAgICBjb25zdCBzYWx0ID0gdGV4dEVuY29kZXIuZW5jb2RlKCJTRnJhbWUxMCIpOwogICAgY29uc3QgaW5mbyA9IHRleHRFbmNvZGVyLmVuY29kZSgia2V5Iik7CiAgICBjb25zdCBkZXJpdmVLZXkgPSBhd2FpdCBjcnlwdG8uc3VidGxlLmRlcml2ZUtleSh7CiAgICAgICAgbmFtZTogIkhLREYiLAogICAgICAgIHNhbHQ6IHNhbHQsCiAgICAgICAgaGFzaDogIlNIQS0yNTYiLAogICAgICAgIGluZm86IGluZm8sCiAgICB9LCBtYXRlcmlhbCwgewogICAgICAgIG5hbWU6ICJBRVMtR0NNIiwKICAgICAgICBsZW5ndGg6IGtleUxlbmd0aCwKICAgIH0sIGZhbHNlLCBbImVuY3J5cHQiLCAiZGVjcnlwdCJdKTsKICAgIHJldHVybiBkZXJpdmVLZXk7Cn0KYXN5bmMgZnVuY3Rpb24gZ2VuZXJhdGVXcml0ZUlWKG1hdGVyaWFsKSB7CiAgICBjb25zdCBzYWx0ID0gdGV4dEVuY29kZXIuZW5jb2RlKCJTRnJhbWUxMCIpOwogICAgY29uc3QgaW5mbyA9IHRleHRFbmNvZGVyLmVuY29kZSgic2FsdCIpOwogICAgY29uc3Qgd3JpdGVJVkJ1ZmZlciA9IGF3YWl0IGNyeXB0by5zdWJ0bGUuZGVyaXZlQml0cyh7CiAgICAgICAgbmFtZTogIkhLREYiLAogICAgICAgIHNhbHQ6IHNhbHQsCiAgICAgICAgaGFzaDogIlNIQS0zODQiLAogICAgICAgIGluZm86IGluZm8sCiAgICB9LCBtYXRlcmlhbCwgCiAgICAvLyBJViDjga8gOTYg44OT44OD44OI44Gq44Gu44GnCiAgICBObiAqIDgpOwogICAgY29uc3Qgd3JpdGVJViA9IG5ldyBVaW50OEFycmF5KHdyaXRlSVZCdWZmZXIpOwogICAgcmV0dXJuIHdyaXRlSVY7Cn0KbGV0IHJlbW92YWxUaW1lb3V0SWQgPSAwOwpvbm1lc3NhZ2UgPSAoZXZlbnQpID0+IHsKICAgIGNvbnN0IHsgdHlwZSB9ID0gZXZlbnQuZGF0YTsKICAgIGlmICh0eXBlID09PSAic2VsZlNlY3JldEtleU1hdGVyaWFsIikgewogICAgICAgIGNvbnN0IHsgc2VsZlNlY3JldEtleU1hdGVyaWFsLCBzZWxmQ29ubmVjdGlvbklkLCBzZWxmS2V5SWQsIHdhaXRpbmdUaW1lIH0gPSBldmVudC5kYXRhOwogICAgICAgIGNvbnN0IHRpbWVvdXRJZCA9IHNldFRpbWVvdXQoKCkgPT4gewogICAgICAgICAgICBjcnlwdG8uc3VidGxlCiAgICAgICAgICAgICAgICAuaW1wb3J0S2V5KCJyYXciLCBzZWxmU2VjcmV0S2V5TWF0ZXJpYWwuYnVmZmVyLCAiSEtERiIsIGZhbHNlLCBbImRlcml2ZUJpdHMiLCAiZGVyaXZlS2V5Il0pCiAgICAgICAgICAgICAgICAudGhlbigobWF0ZXJpYWwpID0+IHsKICAgICAgICAgICAgICAgIGdlbmVyYXRlRGVyaXZlS2V5KG1hdGVyaWFsKS50aGVuKChkZXJpdmVLZXkpID0+IHsKICAgICAgICAgICAgICAgICAgICBzZXRTZWxmRGVyaXZlS2V5KHNlbGZDb25uZWN0aW9uSWQsIHNlbGZLZXlJZCwgZGVyaXZlS2V5KTsKICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgZ2VuZXJhdGVXcml0ZUlWKG1hdGVyaWFsKS50aGVuKCh3cml0ZUlWKSA9PiB7CiAgICAgICAgICAgICAgICAgICAgc2V0V3JpdGVJVihzZWxmQ29ubmVjdGlvbklkLCBzZWxmS2V5SWQsIHdyaXRlSVYpOwogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICBjbGVhclRpbWVvdXQodGltZW91dElkKTsKICAgICAgICAgICAgfSk7CiAgICAgICAgfSwgd2FpdGluZ1RpbWUgfHwgMCk7CiAgICAgICAgLy8gVE9ETzogKzEwMDAg44Gn6Y2155Sf5oiQ5b6M44Gr5a6f6KGM44GV44KM44KL44KI44GG44Gr44GX44Gm44GE44KL44GM55+t44GE5aC05ZCI44Gv5Ly444Gw44GZCiAgICAgICAgY29uc3QgcmVtb3ZhbFdhaXRpbmdUaW1lID0gKHdhaXRpbmdUaW1lIHx8IDApICsgMTAwMDsKICAgICAgICBpZiAocmVtb3ZhbFRpbWVvdXRJZCkgewogICAgICAgICAgICAvLyDli5XkvZzmuIjjgb/jgr/jgqTjg57jg7zmnInjgooKICAgICAgICAgICAgaWYgKHdhaXRpbmdUaW1lKSB7CiAgICAgICAgICAgICAgICAvLyBjb25uZWN0aW9uLmRlc3Ryb3llZAogICAgICAgICAgICAgICAgY2xlYXJUaW1lb3V0KHJlbW92YWxUaW1lb3V0SWQpOwogICAgICAgICAgICAgICAgcmVtb3ZhbFRpbWVvdXRJZCA9IHNldFRpbWVvdXQoKCkgPT4gewogICAgICAgICAgICAgICAgICAgIHJlbW92ZU9sZFJlbW90ZURlcml2ZUtleXMoKTsKICAgICAgICAgICAgICAgICAgICBjbGVhclRpbWVvdXQocmVtb3ZhbFRpbWVvdXRJZCk7CiAgICAgICAgICAgICAgICAgICAgcmVtb3ZhbFRpbWVvdXRJZCA9IDA7CiAgICAgICAgICAgICAgICB9LCByZW1vdmFsV2FpdGluZ1RpbWUpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGVsc2UgewogICAgICAgICAgICAvLyDli5XkvZzmuIjjgb/jgr/jgqTjg57jg7zjgarjgZcKICAgICAgICAgICAgLy8gY29ubmVjdGlvbi5jcmVhdGVkIOOBruWgtOWQiOOCguWwkeOBl+Wun+ihjOOCkumBheOCieOBm+OCiwogICAgICAgICAgICByZW1vdmFsVGltZW91dElkID0gc2V0VGltZW91dCgoKSA9PiB7CiAgICAgICAgICAgICAgICByZW1vdmVPbGRSZW1vdGVEZXJpdmVLZXlzKCk7CiAgICAgICAgICAgICAgICBjbGVhclRpbWVvdXQocmVtb3ZhbFRpbWVvdXRJZCk7CiAgICAgICAgICAgICAgICByZW1vdmFsVGltZW91dElkID0gMDsKICAgICAgICAgICAgfSwgcmVtb3ZhbFdhaXRpbmdUaW1lKTsKICAgICAgICB9CiAgICB9CiAgICBlbHNlIGlmICh0eXBlID09PSAicmVtb3RlU2VjcmV0S2V5TWF0ZXJpYWxzIikgewogICAgICAgIGNvbnN0IHsgcmVtb3RlU2VjcmV0S2V5TWF0ZXJpYWxzIH0gPSBldmVudC5kYXRhOwogICAgICAgIGZvciAoY29uc3QgW2Nvbm5lY3Rpb25JZCwgcmVtb3RlU2VjcmV0S2V5TWF0ZXJpYWxdIG9mIE9iamVjdC5lbnRyaWVzKHJlbW90ZVNlY3JldEtleU1hdGVyaWFscykpIHsKICAgICAgICAgICAgY29uc3QgeyBrZXlJZCwgc2VjcmV0S2V5TWF0ZXJpYWwgfSA9IHJlbW90ZVNlY3JldEtleU1hdGVyaWFsOwogICAgICAgICAgICBjcnlwdG8uc3VidGxlCiAgICAgICAgICAgICAgICAuaW1wb3J0S2V5KCJyYXciLCBzZWNyZXRLZXlNYXRlcmlhbC5idWZmZXIsICJIS0RGIiwgZmFsc2UsIFsiZGVyaXZlQml0cyIsICJkZXJpdmVLZXkiXSkKICAgICAgICAgICAgICAgIC50aGVuKChtYXRlcmlhbCkgPT4gewogICAgICAgICAgICAgICAgZ2VuZXJhdGVEZXJpdmVLZXkobWF0ZXJpYWwpLnRoZW4oKGRlcml2ZUtleSkgPT4gewogICAgICAgICAgICAgICAgICAgIHNldFJlbW90ZURlcml2ZUtleShjb25uZWN0aW9uSWQsIGtleUlkLCBkZXJpdmVLZXkpOwogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICBnZW5lcmF0ZVdyaXRlSVYobWF0ZXJpYWwpLnRoZW4oKHdyaXRlSVYpID0+IHsKICAgICAgICAgICAgICAgICAgICBzZXRXcml0ZUlWKGNvbm5lY3Rpb25JZCwga2V5SWQsIHdyaXRlSVYpOwogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICBzZXRMYXRlc3RSZW1vdGVLZXlJZChjb25uZWN0aW9uSWQsIGtleUlkKTsKICAgICAgICAgICAgfSk7CiAgICAgICAgfQogICAgfQogICAgZWxzZSBpZiAodHlwZSA9PT0gInJlbW92ZVJlbW90ZURlcml2ZUtleSIpIHsKICAgICAgICBjb25zdCB7IGNvbm5lY3Rpb25JZCB9ID0gZXZlbnQuZGF0YTsKICAgICAgICByZW1vdmVEZXJpdmVLZXkoY29ubmVjdGlvbklkKTsKICAgIH0KICAgIGVsc2UgaWYgKHR5cGUgPT09ICJlbmNyeXB0IikgewogICAgICAgIGNvbnN0IHsgcmVhZGFibGVTdHJlYW0sIHdyaXRhYmxlU3RyZWFtIH0gPSBldmVudC5kYXRhOwogICAgICAgIGNvbnN0IHRyYW5zZm9ybVN0cmVhbSA9IG5ldyBUcmFuc2Zvcm1TdHJlYW0oewogICAgICAgICAgICB0cmFuc2Zvcm06IGVuY3J5cHRGdW5jdGlvbiwKICAgICAgICB9KTsKICAgICAgICByZWFkYWJsZVN0cmVhbS5waXBlVGhyb3VnaCh0cmFuc2Zvcm1TdHJlYW0pLnBpcGVUbyh3cml0YWJsZVN0cmVhbSk7CiAgICB9CiAgICBlbHNlIGlmICh0eXBlID09PSAiZGVjcnlwdCIpIHsKICAgICAgICBjb25zdCB7IHJlYWRhYmxlU3RyZWFtLCB3cml0YWJsZVN0cmVhbSB9ID0gZXZlbnQuZGF0YTsKICAgICAgICBjb25zdCB0cmFuc2Zvcm1TdHJlYW0gPSBuZXcgVHJhbnNmb3JtU3RyZWFtKHsKICAgICAgICAgICAgdHJhbnNmb3JtOiBkZWNyeXB0RnVuY3Rpb24sCiAgICAgICAgfSk7CiAgICAgICAgcmVhZGFibGVTdHJlYW0ucGlwZVRocm91Z2godHJhbnNmb3JtU3RyZWFtKS5waXBlVG8od3JpdGFibGVTdHJlYW0pOwogICAgfQogICAgZWxzZSBpZiAodHlwZSA9PT0gImNsZWFyIikgewogICAgICAgIGNvdW50TWFwLmNsZWFyKCk7CiAgICAgICAgd3JpdGVJVk1hcC5jbGVhcigpOwogICAgICAgIHJlbW90ZURlcml2ZUtleU1hcC5jbGVhcigpOwogICAgICAgIGxhdGVzdFJlbW90ZUtleUlkTWFwLmNsZWFyKCk7CiAgICAgICAgc2VsZkRlcml2ZUtleU1hcC5jbGVhcigpOwogICAgfQp9Owo=");this.worker=new Worker(URL.createObjectURL(new Blob([e],{type:"application/javascript"}))),this.worker.onmessage=e=>{const{operation:n}=e.data;"disconnect"===n&&"function"==typeof this.onWorkerDisconnect&&this.onWorkerDisconnect()}}clearWorker(){this.worker&&this.worker.postMessage({type:"clear"})}terminateWorker(){this.worker&&this.worker.terminate()}async init(){const{preKeyBundle:e}=await window.e2ee.init();return e}setupSenderTransform(e){if(!e.track)return;const n=e.createEncodedStreams(),i=n.readableStream||n.readable,t=n.writableStream||n.writable;if(!this.worker)throw new Error("Worker is null. Call startWorker in advance.");this.worker.postMessage({type:"encrypt",readableStream:i,writableStream:t},[i,t])}setupReceiverTransform(e){const n=e.createEncodedStreams(),i=n.readableStream||n.readable,t=n.writableStream||n.writable;if(!this.worker)throw new Error("Worker is null. Call startWorker in advance.");this.worker.postMessage({type:"decrypt",readableStream:i,writableStream:t},[i,t])}postRemoteSecretKeyMaterials(e){if(!this.worker)throw new Error("Worker is null. Call startWorker in advance.");this.worker.postMessage({type:"remoteSecretKeyMaterials",remoteSecretKeyMaterials:e.remoteSecretKeyMaterials})}postRemoveRemoteDeriveKey(e){if(!this.worker)throw new Error("Worker is null. Call startWorker in advance.");this.worker.postMessage({type:"removeRemoteDeriveKey",connectionId:e})}postSelfSecretKeyMaterial(e,n,i,t=0){if(!this.worker)throw new Error("Worker is null. Call startWorker in advance.");this.worker.postMessage({type:"selfSecretKeyMaterial",selfConnectionId:e,selfKeyId:n,selfSecretKeyMaterial:i,waitingTime:t})}startSession(e,n){const[i,t]=window.e2ee.startSession(e,n.identityKey,n.signedPreKey,n.preKeySignature);if(t)throw t;return i}stopSession(e){const[n,i]=window.e2ee.stopSession(e);if(i)throw i;return n}receiveMessage(e){const[n,i]=window.e2ee.receiveMessage(e);if(i)throw i;return n}start(e){const[n,i]=window.e2ee.start(e);if(i)throw i;return n}addPreKeyBundle(e,n){const i=window.e2ee.addPreKeyBundle(e,n.identityKey,n.signedPreKey,n.preKeySignature);if(i)throw i}selfFingerprint(){return window.e2ee.selfFingerprint()}remoteFingerprints(){return window.e2ee.remoteFingerprints()}static async loadWasm(e){if(void 0===!window.e2ee)return void console.warn("E2ee wasm is already loaded. Will not be reload.");if(g(),!window.Go)throw new Error(`Failed to load module Go. window.Go is ${window.Go}.`);const n=new Go,{instance:i}=await WebAssembly.instantiateStreaming(fetch(e),n.importObject);if(n.run(i),!window.e2ee)throw new Error(`Failed to load module e2ee. window.e2ee is ${window.e2ee}.`)}static version(){return"2021.1.0"}static wasmVersion(){return window.e2ee.version()}}var V=Uint8Array,S=Uint16Array,G=Uint32Array,W=new V([0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0,0]),h=new V([0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,0,0]),y=new V([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]),k=function(e,n){for(var t=new S(31),a=0;31>a;++a)t[a]=n+=1<a;++a)for(var o=t[a];oN;++N)X=(43690&N)>>>1|(21845&N)<<1,X=(52428&X)>>>2|(13107&X)<<2,X=(61680&X)>>>4|(3855&X)<<4,Y[N]=((65280&X)>>>8|(255&X)<<8)>>>1;for(var E=function(e,n,t){for(var a=e.length,g=0,o=new S(n);g>>15-n]=c}else for(d=new S(a),g=0;g>>15-e[g]);return d},v=new V(288),N=0;144>N;++N)v[N]=8;for(var N=144;256>N;++N)v[N]=9;for(var N=256;280>N;++N)v[N]=7;for(var N=280;288>N;++N)v[N]=8;for(var O=new V(32),N=0;32>N;++N)O[N]=5;var K=E(v,9,0),L=E(v,9,1),F=E(O,5,0),J=E(O,5,1),U=function(e){for(var n=e[0],t=1;tn&&(n=e[t]);return n},Q=function(e,n,i){var t=0|n/8;return(e[t]|e[t+1]<<8)>>(7&n)&i},D=function(e,n){var i=0|n/8;return(e[i]|e[i+1]<<8|e[i+2]<<16)>>(7&n)},H=function(e){return(0|e/8)+(7&e&&1)},M=function(i,t,a){(null==t||0>t)&&(t=0),(null==a||a>i.length)&&(a=i.length);var g=new(i instanceof S?S:i instanceof G?G:V)(a-t);return g.set(i.subarray(t,a)),g},P=["unexpected EOF","invalid block type","invalid length/literal","invalid distance","stream finished","no stream handler",,"no callback","invalid UTF-8 data","extra field too long","date not in range 1980-2099","filename too long","stream finishing","invalid zip data"],j=function(n,i,t){var a=new Error(i||P[n]);if(a.code=n,Error.captureStackTrace&&Error.captureStackTrace(a,j),!t)throw a;return a},z=function(g,o,C){var I=g.length;if(!I||C&&!C.l&&5>I)return o||new V(0);var m=!o||C,A=!C||C.i;C||(C={}),o||(o=new V(3*I));var Z=function(e){var n=o.length;if(e>n){var i=new V(a(2*n,e));i.set(o),o=i}},u=C.f||0,p=C.p||0,S=C.b||0,G=C.l,k=C.d,w=C.m,R=C.n,X=8*I;do{if(!G){C.f=u=Q(g,p,1);var f=Q(g,p+1,3);if(p+=3,!f){var T=H(p)+4,Y=g[T-4]|g[T-3]<<8,l=T+Y;if(l>I){A&&j(0);break}m&&Z(S+Y),o.set(g.subarray(T,l),S),C.b=S+=Y,C.p=p=8*l;continue}else if(1==f)G=L,k=J,w=9,R=5;else if(2==f){var t=Q(g,p,31)+257,N=Q(g,p+10,15)+4,v=t+Q(g,p+5,31)+1;p+=14;for(var O=new V(v),K=new V(19),F=0;F>>4;if(16>T)O[F++]=T;else{var _=0,q=0;for(16==T?(q=3+Q(g,p,3),p+=2,_=O[F-1]):17==T?(q=3+Q(g,p,7),p+=3):18==T&&(q=11+Q(g,p,127),p+=7);q--;)O[F++]=_}}var $=O.subarray(0,t),ee=O.subarray(t);w=U($),R=U(ee),G=E($,w,1),k=E(ee,R,1)}else j(1);if(p>X){A&&j(0);break}}m&&Z(S+131072);for(var ne=(1<>>4;if(p+=15&_,p>X){A&&j(0);break}if(_||j(2),256>ae)o[S++]=ae;else if(256==ae){te=p,G=null;break}else{var ge=ae-254;if(264>>4;le||j(3),p+=15≤var ee=B[d];if(3X){A&&j(0);break}m&&Z(S+131072);for(var de=S+ge;S>>8},q=function(e,n,i){i<<=7&n;var t=0|n/8;e[t]|=i,e[t+1]|=i>>>8,e[t+2]|=i>>>16},$=function(e,n){for(var a=[],t=0;tA&&(A=o[t].s);var Z=new S(A+1),u=ee(a[I-1],Z,0);if(u>n){var t=0,b=0,p=u-n;for(o.sort(function(e,n){return Z[n.s]-Z[e.s]||e.f-n.f});tn)b+=(1<>>=p;0>>8,e[g+2]=255^e[g],e[g+3]=255^e[g+1];for(var o=0;oz;++z){x=P[z];for(var ee,f=0;f>>5),C+=x[f]>>>12)}}else Q=K,D=v,j=F,H=O;for(var f=0;f>>18;q(n,C,Q[ee+257]),C+=D[ee+257],7>>23),C+=W[ee]);var ae=31&a[f];q(n,C,j[ae]),C+=H[ae],3>>5),C+=h[ae])}else q(n,C,Q[a[f]]),C+=D[a[f]];return q(n,C,Q[256]),C+D[256]},ge=new G([65540,131080,131088,131104,262176,1048704,1048832,2114560,2117632]),oe=new V(0),le=function(a,g,c,C,I,r){var m=a.length,s=new V(C+m+5*(1+t(m/7e3))+I),o=s.subarray(C,s.length-I),A=0;if(!g||8>m)for(var Z,u=0;u<=m;u+=65535)Z=u+65535,ZQ;++Q)B[Q]=0;for(var Q=0;30>Q;++Q)Y[Q]=0}var D=2,x=0,P=8191&b,z=32767&F-J;if(2>>13,U)-1,q=n(32767,u),$=n(258,U);z<=q&&--P&&F!=J;){if(a[u+D]==a[u+D-z]){for(var ee=0;ee<$&&a[u+ee]==a[u+ee-z];++ee);if(ee>D){if(D=ee,x=z,ee>_)break;for(var ne=n(z,ee-2),ie=0,Q=0;Qie&&(ie=ce,J=le)}}}F=J,J=y[F],z+=32767&F-J+32768}if(x){f[v++]=268435456|R[D]<<18|T[x];var se=31&R[D],Ce=31&T[x];E+=W[se]+h[Ce],++B[257+se],++Y[Ce],O=u+D,++N}else f[v++]=a[u],++B[a[u]]}}A=ae(a,o,r,f,B,Y,E,v,K,u-K,A),!r&&7&A&&(A=te(o,A+1,oe))}return M(s,0,C+H(A)+I)},de=function(){var t=1,g=0;return{p:function(a){for(var o,d=t,c=g,s=a.length,l=0;l!=s;){for(o=n(l+2655,s);l>16),c=(65535&c)+15*(c>>16)}t=d,g=c},d:function(){return t%=65521,g%=65521,(255&t)<<24|t>>>8<<16|(255&g)<<8|g>>>8}}},ce=function(e,i,g,o,l){return le(e,null==i.level?6:i.level,null==i.mem?t(1.5*a(8,n(13,Math.log(e.length)))):12+i.mem,g,o,!l)},se=function(e,n,i){for(;i;++n)e[n]=i,i>>>=8},Ce=function(e,n){var i=n.level,t=0==i?0:6>i?1:9==i?3:2;e[0]=120,e[1]=t<<6|(t?32-2*t:1)},Ie=function(e){(8!=(15&e[0])||7>>4||(e[0]<<8|e[1])%31)&&j(6,"invalid zlib data"),32&e[1]&&j(6,"invalid zlib data: preset dictionaries not supported")},re="undefined"!=typeof TextDecoder&&new TextDecoder,me=0;try{re.decode(oe,{stream:!0}),me=1}catch(n){}class Ae extends Error{}class Ze{constructor(e,n,i,t,a,g){this.role=n,this.channelId=i,this.metadata=t,this.signalingUrl=e,this.options=a,this.connectionTimeout=6e4,"number"==typeof this.options.timeout&&(console.warn("@deprecated timeout option will be removed in a future version. Use connectionTimeout."),this.connectionTimeout=this.options.timeout),"number"==typeof this.options.connectionTimeout&&(this.connectionTimeout=this.options.connectionTimeout),this.disconnectWaitTimeout=3e3,"number"==typeof this.options.disconnectWaitTimeout&&(this.disconnectWaitTimeout=this.options.disconnectWaitTimeout),this.constraints=null,this.debug=g,this.clientId=null,this.connectionId=null,this.remoteConnectionIds=[],this.stream=null,this.ws=null,this.pc=null,this.encodings=[],this.callbacks={disconnect:()=>{},push:()=>{},addstream:()=>{},track:()=>{},removestream:()=>{},removetrack:()=>{},notify:()=>{},log:()=>{},timeout:()=>{},timeline:()=>{},signaling:()=>{}},this.authMetadata=null,this.e2ee=null,this.connectionTimeoutTimerId=0,this.monitorSignalingWebSocketEventTimerId=0,this.monitorIceConnectionStateChangeTimerId=0,this.dataChannels={},this.mids={audio:"",video:""},this.signalingSwitched=!1,this.dataChannelsCompress={}}on(e,n){"addstream"===e?console.warn("@deprecated addstream callback will be removed in a future version. Use track callback."):"removestream"==e&&console.warn("@deprecated removestream callback will be removed in a future version. Use removetrack callback."),e in this.callbacks&&(this.callbacks[e]=n)}stopAudioTrack(e){for(const n of e.getAudioTracks())n.enabled=!1;return new Promise(n=>{setTimeout(async()=>{for(const n of e.getAudioTracks())if(n.stop(),e.removeTrack(n),null!==this.pc){const e=this.pc.getSenders().find(e=>e.track&&e.track.id===n.id);e&&(await e.replaceTrack(null))}n()},100)})}stopVideoTrack(e){for(const n of e.getVideoTracks())n.enabled=!1;return new Promise(n=>{setTimeout(async()=>{for(const n of e.getVideoTracks())if(n.stop(),e.removeTrack(n),null!==this.pc){const e=this.pc.getSenders().find(e=>e.track&&e.track.id===n.id);e&&(await e.replaceTrack(null))}n()},100)})}async replaceAudioTrack(e,n){await this.stopAudioTrack(e);const i=this.getAudioTransceiver();if(null===i)throw new Error("Unable to set an audio track. Audio track sender is undefined");e.addTrack(n),await i.sender.replaceTrack(n)}async replaceVideoTrack(e,n){await this.stopVideoTrack(e);const i=this.getVideoTransceiver();if(null===i)throw new Error("Unable to set video track. Video track sender is undefined");e.addTrack(n),await i.sender.replaceTrack(n)}stopStream(){return new Promise(e=>(this.debug&&console.warn("@deprecated closing MediaStream in disconnect will be removed in a future version. Close every track in the MediaStream by yourself."),!this.stream)?e():(this.stream.getTracks().forEach(e=>{e.stop()}),this.stream=null,e()))}async signalingTerminate(){await this.stopStream();for(const e of Object.keys(this.dataChannels)){const n=this.dataChannels[e];n&&n.close(),delete this.dataChannels[e]}this.ws&&(this.ws.close(),this.ws=null),this.pc&&this.pc.close(),this.e2ee&&this.e2ee.terminateWorker(),this.initializeConnection()}async abendPeerConnectionState(e){this.clearMonitorIceConnectionStateChange(),await this.stopStream(),this.pc&&(this.pc.ondatachannel=null,this.pc.oniceconnectionstatechange=null,this.pc.onicegatheringstatechange=null,this.pc.onconnectionstatechange=null),this.ws&&(this.ws.onclose=e=>{this.writeWebSocketTimelineLog("onclose",{code:e.code,reason:e.reason})},this.ws.onmessage=null,this.ws.onerror=null);for(const n of Object.keys(this.dataChannels)){const e=this.dataChannels[n];e&&(e.onclose=e=>{const n=e.currentTarget;this.writeDataChannelTimelineLog("onclose",n),this.trace("CLOSE DATA CHANNEL",n.label)},e.onmessage=null,e.onerror=null)}for(const n of Object.keys(this.dataChannels)){const e=this.dataChannels[n];e&&e.close(),delete this.dataChannels[n]}this.ws&&(this.ws.close(),this.ws=null),this.pc&&this.pc.close(),this.e2ee&&this.e2ee.terminateWorker(),this.initializeConnection();const n=this.soraCloseEvent("abend",e);this.callbacks.disconnect(n),this.writeSoraTimelineLog("disconnect-abend",n)}async abend(e,n){this.clearMonitorIceConnectionStateChange(),await this.stopStream(),this.pc&&(this.pc.ondatachannel=null,this.pc.oniceconnectionstatechange=null,this.pc.onicegatheringstatechange=null,this.pc.onconnectionstatechange=null),this.ws&&(this.ws.onclose=e=>{this.writeWebSocketTimelineLog("onclose",{code:e.code,reason:e.reason})},this.ws.onmessage=null,this.ws.onerror=null);for(const i of Object.keys(this.dataChannels)){const e=this.dataChannels[i];e&&(e.onclose=e=>{const n=e.currentTarget;this.writeDataChannelTimelineLog("onclose",n),this.trace("CLOSE DATA CHANNEL",n.label)},e.onmessage=null,e.onerror=null)}if(this.dataChannels.signaling){const n={type:"disconnect",reason:e};if(!0===this.dataChannelsCompress.signaling){const e=new TextEncoder().encode(JSON.stringify(n)),i=o(e,{});if("open"===this.dataChannels.signaling.readyState)try{this.dataChannels.signaling.send(i),this.writeDataChannelSignalingLog("send-disconnect",this.dataChannels.signaling,n)}catch(n){const e=n.message;this.writeDataChannelSignalingLog("failed-to-send-disconnect",this.dataChannels.signaling,e)}}else if("open"===this.dataChannels.signaling.readyState)try{this.dataChannels.signaling.send(JSON.stringify(n)),this.writeDataChannelSignalingLog("send-disconnect",this.dataChannels.signaling,n)}catch(n){const e=n.message;this.writeDataChannelSignalingLog("failed-to-send-disconnect",this.dataChannels.signaling,e)}}for(const i of Object.keys(this.dataChannels)){const e=this.dataChannels[i];e&&(e.onerror=null,e.close()),delete this.dataChannels[i]}if(await this.disconnectWebSocket(e),await this.disconnectPeerConnection(),this.e2ee&&this.e2ee.terminateWorker(),this.initializeConnection(),"WEBSOCKET-ONCLOSE"===e&&n&&(1e3===n.code||1005===n.code)){const e=this.soraCloseEvent("normal","DISCONNECT",n);return this.writeSoraTimelineLog("disconnect-normal",e),void this.callbacks.disconnect(e)}const i=this.soraCloseEvent("abend",e,n);this.writeSoraTimelineLog("disconnect-abend",i),this.callbacks.disconnect(this.soraCloseEvent("abend",e,n))}initializeConnection(){this.clientId=null,this.connectionId=null,this.remoteConnectionIds=[],this.stream=null,this.ws=null,this.pc=null,this.encodings=[],this.authMetadata=null,this.e2ee=null,this.dataChannels={},this.mids={audio:"",video:""},this.signalingSwitched=!1,this.clearConnectionTimeout()}disconnectWebSocket(e){let n=0;return this.signalingSwitched?(this.ws&&(this.ws.close(),this.ws=null),Promise.resolve(null)):new Promise(i=>{if(!this.ws)return i(null);if(this.ws.onclose=e=>(this.ws&&(this.ws.close(),this.ws=null),clearTimeout(n),this.writeWebSocketTimelineLog("onclose",{code:e.code,reason:e.reason}),i({code:e.code,reason:e.reason})),1===this.ws.readyState){const t={type:"disconnect",reason:e};this.ws.send(JSON.stringify(t)),this.writeWebSocketSignalingLog("send-disconnect",t),n=setTimeout(()=>{this.ws&&(this.ws.close(),this.ws=null),i(null)},this.disconnectWaitTimeout)}else return this.ws.close(),this.ws=null,i(null)})}disconnectDataChannel(){const e=()=>{for(const e of Object.keys(this.dataChannels)){const n=this.dataChannels[e];n&&(n.onerror=null,n.close()),delete this.dataChannels[e]}};return new Promise((n,i)=>{if(!this.dataChannels.signaling)return e(),n({code:4999,reason:""});const t=setTimeout(()=>(e(),i()),this.disconnectWaitTimeout),a=[];for(const g of Object.keys(this.dataChannels)){const i=this.dataChannels[g];if(i){i.onerror=()=>(clearTimeout(t),e(),n({code:4999,reason:""}));a.push((()=>new Promise(e=>{let n=0;const t=setInterval(()=>{n++,"closed"===i.readyState&&(clearInterval(t),e()),this.disconnectWaitTimeout<100*n&&(e(),clearInterval(t))},100)}))())}}Promise.all(a).then(()=>{0===Object.keys(this.dataChannels).length?n(null):n({code:4999,reason:""})}).finally(()=>{e(),clearTimeout(t)});const g={type:"disconnect",reason:"NO-ERROR"};if(!0===this.dataChannelsCompress.signaling){const e=new TextEncoder().encode(JSON.stringify(g)),n=o(e,{});if("open"===this.dataChannels.signaling.readyState)try{this.dataChannels.signaling.send(n),this.writeDataChannelSignalingLog("send-disconnect",this.dataChannels.signaling,g)}catch(n){const e=n.message;this.writeDataChannelSignalingLog("failed-to-send-disconnect",this.dataChannels.signaling,e)}}else if("open"===this.dataChannels.signaling.readyState)try{this.dataChannels.signaling.send(JSON.stringify(g)),this.writeDataChannelSignalingLog("send-disconnect",this.dataChannels.signaling,g)}catch(n){const e=n.message;this.writeDataChannelSignalingLog("failed-to-send-disconnect",this.dataChannels.signaling,e)}})}disconnectPeerConnection(){return new Promise(e=>(this.pc&&"closed"!==this.pc.connectionState&&this.pc.close(),e()))}async disconnect(){this.clearMonitorIceConnectionStateChange(),await this.stopStream(),this.pc&&(this.pc.ondatachannel=null,this.pc.oniceconnectionstatechange=null,this.pc.onicegatheringstatechange=null,this.pc.onconnectionstatechange=null),this.ws&&(this.ws.onclose=e=>{this.writeWebSocketTimelineLog("onclose",{code:e.code,reason:e.reason})},this.ws.onmessage=null,this.ws.onerror=null);for(const e of Object.keys(this.dataChannels)){const n=this.dataChannels[e];n&&(n.onmessage=null)}let e=null;if(this.signalingSwitched){try{const n=await this.disconnectDataChannel();null!==n&&(e=this.soraCloseEvent("normal","DISCONNECT",n))}catch(n){e=this.soraCloseEvent("abend","DISCONNECT-TIMEOUT")}await this.disconnectWebSocket("NO-ERROR"),await this.disconnectPeerConnection()}else{const n=await this.disconnectWebSocket("NO-ERROR");await this.disconnectPeerConnection(),null!==n&&(e=this.soraCloseEvent("normal","DISCONNECT",n))}this.e2ee&&this.e2ee.terminateWorker(),this.initializeConnection(),e&&("abend"===e.type?this.writeSoraTimelineLog("disconnect-abend",e):"normal"===e.type&&this.writeSoraTimelineLog("disconnect-normal",e),this.callbacks.disconnect(e))}setupE2EE(){!0===this.options.e2ee&&(this.e2ee=new p,this.e2ee.onWorkerDisconnect=async()=>{await this.abend("INTERNAL-ERROR",{reason:"CRASH-E2EE-WORKER"})},this.e2ee.startWorker())}startE2EE(){if(!0===this.options.e2ee&&this.e2ee){if(!this.connectionId){const e=new Error;throw e.message=`E2EE failed. Self connectionId is null`,e}this.e2ee.clearWorker();const e=this.e2ee.start(this.connectionId);this.e2ee.postSelfSecretKeyMaterial(this.connectionId,e.selfKeyId,e.selfSecretKeyMaterial)}}signaling(e){return this.trace("CREATE OFFER",e),new Promise((n,i)=>{null===this.ws&&(this.ws=new WebSocket(this.signalingUrl),this.writeWebSocketSignalingLog("new-websocket",this.signalingUrl)),this.ws.binaryType="arraybuffer",this.ws.onclose=async e=>{const n=new Ae(`Signaling failed. CloseEventCode:${e.code} CloseEventReason:'${e.reason}'`);n.code=e.code,n.reason=e.reason,this.writeWebSocketTimelineLog("onclose",n),await this.signalingTerminate(),i(n)},this.ws.onopen=async()=>{this.writeWebSocketSignalingLog("onopen");let n;try{n=C(e.sdp||"",this.role,this.channelId,this.metadata,this.options)}catch(e){return void i(e)}if(n.e2ee&&this.e2ee){const e=await this.e2ee.init();n.signaling_notify_metadata.pre_key_bundle=e}this.trace("SIGNALING CONNECT MESSAGE",n),this.ws&&(this.ws.send(JSON.stringify(n)),this.writeWebSocketSignalingLog(`send-${n.type}`,n))},this.ws.onmessage=async e=>{if(e.data instanceof ArrayBuffer)return this.writeWebSocketSignalingLog("onmessage-e2ee",e.data),void this.signalingOnMessageE2EE(e.data);const i=JSON.parse(e.data);"offer"==i.type?(this.writeWebSocketSignalingLog("onmessage-offer",i),this.signalingOnMessageTypeOffer(i),n(i)):"update"==i.type?(this.writeWebSocketSignalingLog("onmessage-update",i),await this.signalingOnMessageTypeUpdate(i)):"re-offer"==i.type?(this.writeWebSocketSignalingLog("onmessage-re-offer",i),await this.signalingOnMessageTypeReOffer(i)):"ping"==i.type?await this.signalingOnMessageTypePing(i):"push"==i.type?this.callbacks.push(i,"websocket"):"notify"==i.type?("connection.created"===i.event_type?this.writeWebSocketTimelineLog("notify-connection.created",i):"connection.destroyed"===i.event_type&&this.writeWebSocketTimelineLog("notify-connection.destroyed",i),this.signalingOnMessageTypeNotify(i,"websocket")):"switched"==i.type&&(this.writeWebSocketSignalingLog("onmessage-switched",i),this.signalingOnMessageTypeSwitched(i))}})}async createOffer(){const e=new window.RTCPeerConnection({iceServers:[]});if(s()){e.addTransceiver("video",{direction:"recvonly"}),e.addTransceiver("audio",{direction:"recvonly"});const n=await e.createOffer();return e.close(),this.writePeerConnectionTimelineLog("create-offer",n),n}const n=await e.createOffer({offerToReceiveAudio:!0,offerToReceiveVideo:!0});return e.close(),this.writePeerConnectionTimelineLog("create-offer",n),n}async connectPeerConnection(e){let n=Object.assign({},e.config);if(this.e2ee&&(n=Object.assign({encodedInsertableStreams:!0},n)),void 0!==window.RTCPeerConnection.generateCertificate){const e=await window.RTCPeerConnection.generateCertificate({name:"ECDSA",namedCurve:"P-256"});n=Object.assign({certificates:[e]},n)}return this.trace("PEER CONNECTION CONFIG",n),this.writePeerConnectionTimelineLog("new-peerconnection",n),this.pc=new window.RTCPeerConnection(n,this.constraints),this.pc.oniceconnectionstatechange=()=>{this.pc&&(this.writePeerConnectionTimelineLog("oniceconnectionstatechange",{connectionState:this.pc.connectionState,iceConnectionState:this.pc.iceConnectionState,iceGatheringState:this.pc.iceGatheringState}),this.trace("ONICECONNECTIONSTATECHANGE ICECONNECTIONSTATE",this.pc.iceConnectionState))},this.pc.onicegatheringstatechange=()=>{this.pc&&this.writePeerConnectionTimelineLog("onicegatheringstatechange",{connectionState:this.pc.connectionState,iceConnectionState:this.pc.iceConnectionState,iceGatheringState:this.pc.iceGatheringState})},this.pc.onconnectionstatechange=()=>{this.pc&&this.writePeerConnectionTimelineLog("onconnectionstatechange",{connectionState:this.pc.connectionState,iceConnectionState:this.pc.iceConnectionState,iceGatheringState:this.pc.iceGatheringState})},void(this.pc.ondatachannel=e=>{this.onDataChannel(e)})}async setRemoteDescription(e){if(this.pc){const n=new RTCSessionDescription({type:"offer",sdp:e.sdp});return await this.pc.setRemoteDescription(n),void this.writePeerConnectionTimelineLog("set-remote-description",n)}}async createAnswer(e){if(this.pc){for(const e of Object.values(this.mids)){const n=this.pc.getTransceivers().find(n=>n.mid===e);n&&"recvonly"===n.direction&&(n.direction="sendrecv")}if(this.options.simulcast&&("sendrecv"===this.role||"sendonly"===this.role)){const n=this.pc.getTransceivers().find(e=>{if(e.mid&&0<=e.mid.indexOf("video")&&null!==e.sender.track&&(null===e.currentDirection||"sendonly"===e.currentDirection))return e});if(n){await this.setSenderParameters(n,this.encodings),await this.setRemoteDescription(e),this.trace("TRANSCEIVER SENDER GET_PARAMETERS",n.sender.getParameters()),await this.setSenderParameters(n,this.encodings);const i=await this.pc.createAnswer();return await this.pc.setLocalDescription(i),void this.trace("TRANSCEIVER SENDER GET_PARAMETERS",n.sender.getParameters())}}const n=await this.pc.createAnswer();return this.writePeerConnectionTimelineLog("create-answer",n),await this.pc.setLocalDescription(n),void this.writePeerConnectionTimelineLog("set-local-description",n)}}sendAnswer(){if(this.pc&&this.ws&&this.pc.localDescription){this.trace("ANSWER SDP",this.pc.localDescription.sdp);const e={type:"answer",sdp:this.pc.localDescription.sdp};this.ws.send(JSON.stringify(e)),this.writeWebSocketSignalingLog("send-answer",e)}}onIceCandidate(){return new Promise(e=>{this.pc&&(this.pc.oniceconnectionstatechange=()=>{this.pc&&(this.writePeerConnectionTimelineLog("oniceconnectionstatechange",{connectionState:this.pc.connectionState,iceConnectionState:this.pc.iceConnectionState,iceGatheringState:this.pc.iceGatheringState}),this.trace("ONICECONNECTIONSTATECHANGE ICECONNECTIONSTATE",this.pc.iceConnectionState),"connected"===this.pc.iceConnectionState&&e())},this.pc.onicecandidate=n=>{if(this.writePeerConnectionTimelineLog("onicecandidate",n.candidate),this.pc&&this.trace("ONICECANDIDATE ICEGATHERINGSTATE",this.pc.iceGatheringState),null===n.candidate)e();else{const e=n.candidate.toJSON(),i=Object.assign(e,{type:"candidate"});this.trace("ONICECANDIDATE CANDIDATE MESSAGE",i),this.sendMessage(i)}})})}waitChangeConnectionStateConnected(){return new Promise((e,n)=>{if(this.pc&&void 0===this.pc.connectionState)return void e();const i=setInterval(()=>{if(!this.pc){const e=new Error;e.message="PeerConnection connectionState did not change to 'connected'",clearInterval(i),n(e)}else this.pc&&"connected"===this.pc.connectionState&&(clearInterval(i),e())},10)})}monitorSignalingWebSocketEvent(){return new Promise((e,n)=>{this.monitorSignalingWebSocketEventTimerId=setInterval(()=>{this.ws&&(this.clearMonitorSignalingWebSocketEvent(),this.ws.onclose=async e=>{const i=new Ae(`Signaling failed. CloseEventCode:${e.code} CloseEventReason:'${e.reason}'`);i.code=e.code,i.reason=e.reason,this.writeWebSocketTimelineLog("onclose",i),await this.signalingTerminate(),n(i)},this.ws.onerror=async()=>{const e=new Ae(`Signaling failed. WebSocket onerror was called`);this.writeWebSocketSignalingLog("onerror",e),await this.signalingTerminate(),n(e)})},100)})}monitorWebSocketEvent(){this.ws&&(this.ws.onclose=async e=>{this.writeWebSocketTimelineLog("onclose",{code:e.code,reason:e.reason}),await this.abend("WEBSOCKET-ONCLOSE",{code:e.code,reason:e.reason})},this.ws.onerror=async()=>{this.writeWebSocketSignalingLog("onerror"),await this.abend("WEBSOCKET-ONERROR")})}monitorPeerConnectionState(){this.pc&&(this.pc.oniceconnectionstatechange=async()=>{this.pc&&this.pc.connectionState===void 0&&(this.writePeerConnectionTimelineLog("oniceconnectionstatechange",{connectionState:this.pc.connectionState,iceConnectionState:this.pc.iceConnectionState,iceGatheringState:this.pc.iceGatheringState}),this.trace("ONICECONNECTIONSTATECHANGE ICECONNECTIONSTATE",this.pc.iceConnectionState),clearTimeout(this.monitorIceConnectionStateChangeTimerId),"failed"===this.pc.iceConnectionState?await this.abendPeerConnectionState("ICE-CONNECTION-STATE-FAILED"):"disconnected"===this.pc.iceConnectionState&&(this.monitorIceConnectionStateChangeTimerId=setTimeout(async()=>{this.pc&&"disconnected"===this.pc.iceConnectionState&&(await this.abendPeerConnectionState("ICE-CONNECTION-STATE-DISCONNECTED-TIMEOUT"))},1e4)))},this.pc.onconnectionstatechange=async()=>{this.pc&&(this.writePeerConnectionTimelineLog("onconnectionstatechange",{connectionState:this.pc.connectionState,iceConnectionState:this.pc.iceConnectionState,iceGatheringState:this.pc.iceGatheringState}),"failed"===this.pc.connectionState&&(await this.abendPeerConnectionState("CONNECTION-STATE-FAILED")))})}setConnectionTimeout(){return new Promise((e,n)=>{0{if(!this.pc||this.pc&&this.pc.connectionState!==void 0&&"connected"!==this.pc.connectionState){const e=new Error;e.message="Signaling connection timeout",this.callbacks.timeout(),this.trace("DISCONNECT","Signaling connection timeout"),this.writePeerConnectionTimelineLog("signaling-connection-timeout",{connectionTimeout:this.connectionTimeout}),await this.signalingTerminate(),n(e)}},this.connectionTimeout))})}clearConnectionTimeout(){clearTimeout(this.connectionTimeoutTimerId)}clearMonitorSignalingWebSocketEvent(){clearInterval(this.monitorSignalingWebSocketEventTimerId)}clearMonitorIceConnectionStateChange(){clearInterval(this.monitorIceConnectionStateChangeTimerId)}trace(e,n){this.callbacks.log(e,n);this.debug&&A(this.clientId,e,n)}writeWebSocketSignalingLog(e,n){this.callbacks.signaling(Z(e,n,"websocket")),this.writeWebSocketTimelineLog(e,n)}writeDataChannelSignalingLog(e,n,i){this.callbacks.signaling(Z(e,i,"datachannel")),this.writeDataChannelTimelineLog(e,n,i)}writeWebSocketTimelineLog(e,n){const i=b(e,n,"websocket");this.callbacks.timeline(i)}writeDataChannelTimelineLog(e,n,i){const t=b(e,i,"datachannel",n.id,n.label);this.callbacks.timeline(t)}writePeerConnectionTimelineLog(e,n){const i=b(e,n,"peerconnection");this.callbacks.timeline(i)}writeSoraTimelineLog(e,n){const i=b(e,n,"sora");this.callbacks.timeline(i)}signalingOnMessageE2EE(e){if(this.e2ee){const n=new Uint8Array(e),i=this.e2ee.receiveMessage(n);this.e2ee.postRemoteSecretKeyMaterials(i),i.messages.forEach(e=>{this.sendE2EEMessage(e.buffer)})}}signalingOnMessageTypeOffer(e){if(this.clientId=e.client_id,this.connectionId=e.connection_id,void 0!==e.metadata&&(this.authMetadata=e.metadata),Array.isArray(e.encodings)&&(this.encodings=e.encodings),void 0!==e.mid&&void 0!==e.mid.audio&&(this.mids.audio=e.mid.audio),void 0!==e.mid&&void 0!==e.mid.video&&(this.mids.video=e.mid.video),e.data_channels)for(const n of e.data_channels)this.dataChannelsCompress[n.label]=n.compress;this.trace("SIGNALING OFFER MESSAGE",e),this.trace("OFFER SDP",e.sdp)}sendUpdateAnswer(){this.pc&&this.ws&&this.pc.localDescription&&(this.trace("ANSWER SDP",this.pc.localDescription.sdp),this.sendMessage({type:"update",sdp:this.pc.localDescription.sdp}))}sendReAnswer(){this.pc&&this.pc.localDescription&&(this.trace("RE ANSWER SDP",this.pc.localDescription.sdp),this.sendMessage({type:"re-answer",sdp:this.pc.localDescription.sdp}))}async signalingOnMessageTypeUpdate(e){this.trace("SIGNALING UPDATE MESSGE",e),this.trace("UPDATE SDP",e.sdp),await this.setRemoteDescription(e),await this.createAnswer(e),this.sendUpdateAnswer()}async signalingOnMessageTypeReOffer(e){this.trace("SIGNALING RE OFFER MESSGE",e),this.trace("RE OFFER SDP",e.sdp),await this.setRemoteDescription(e),await this.createAnswer(e),this.sendReAnswer()}async signalingOnMessageTypePing(e){const n={type:"pong"};if(e.stats){const e=await this.getStats();n.stats=e}this.ws&&this.ws.send(JSON.stringify(n))}signalingOnMessageTypeNotify(e,n){if("connection.created"===e.event_type){const n=e.connection_id;if(this.connectionId!==n){const i=I(e),t=m(i);if(t&&this.e2ee&&n){const e=this.e2ee.startSession(n,t);this.e2ee.postRemoteSecretKeyMaterials(e),e.messages.forEach(e=>{this.sendE2EEMessage(e.buffer)}),this.e2ee.postSelfSecretKeyMaterial(e.selfConnectionId,e.selfKeyId,e.selfSecretKeyMaterial)}}const i=r(e);i.forEach(e=>{const n=I(e),i=m(n),t=e.connection_id;t&&this.e2ee&&i&&this.e2ee.addPreKeyBundle(t,i)})}else if("connection.destroyed"===e.event_type){const n=I(e),i=m(n),t=e.connection_id;if(i&&this.e2ee&&t){const e=this.e2ee.stopSession(t);this.e2ee.postSelfSecretKeyMaterial(e.selfConnectionId,e.selfKeyId,e.selfSecretKeyMaterial,5e3),e.messages.forEach(e=>{this.sendE2EEMessage(e.buffer)}),this.e2ee.postRemoveRemoteDeriveKey(t)}}this.callbacks.notify(e,n)}signalingOnMessageTypeSwitched(e){this.signalingSwitched=!0;!this.ws||e.ignore_disconnect_websocket&&(this.ws&&(this.ws.onclose=null,this.ws.close(),this.ws=null),this.writeWebSocketSignalingLog("close"))}async setSenderParameters(e,n){const i=e.sender.getParameters();return i.encodings=n,await e.sender.setParameters(i),this.trace("TRANSCEIVER SENDER SET_PARAMETERS",i),void this.writePeerConnectionTimelineLog("transceiver-sender-set-parameters",i)}async getStats(){const e=[];if(!this.pc)return e;const n=await this.pc.getStats();return n.forEach(n=>{e.push(n)}),e}onDataChannel(e){const n=e.channel;this.writeDataChannelTimelineLog("ondatachannel",n,u(n)),e.channel.onbufferedamountlow=e=>{const n=e.currentTarget;this.writeDataChannelTimelineLog("onbufferedamountlow",n)},e.channel.onopen=e=>{const n=e.currentTarget;n.bufferedAmountLowThreshold=65536,n.binaryType="arraybuffer",this.dataChannels[n.label]=n,this.trace("OPEN DATA CHANNEL",n.label),"signaling"===n.label&&this.ws?this.writeDataChannelSignalingLog("onopen",n):this.writeDataChannelTimelineLog("onopen",n)},e.channel.onclose=async e=>{const n=e.currentTarget;this.writeDataChannelTimelineLog("onclose",n),this.trace("CLOSE DATA CHANNEL",n.label),await this.disconnect()},e.channel.onerror=async e=>{const n=e.currentTarget;this.writeDataChannelTimelineLog("onerror",n),this.trace("ERROR DATA CHANNEL",n.label),await this.abend("DATA-CHANNEL-ONERROR",{params:{label:n.label}})},"signaling"===e.channel.label?e.channel.onmessage=async e=>{const n=e.currentTarget;let i=e.data;if(!0===this.dataChannelsCompress.signaling){const n=l(new Uint8Array(e.data));i=new TextDecoder().decode(n)}const t=JSON.parse(i);this.writeDataChannelSignalingLog(`onmessage-${t.type}`,n,t),"re-offer"===t.type&&(await this.signalingOnMessageTypeReOffer(t))}:"notify"===e.channel.label?e.channel.onmessage=e=>{const n=e.currentTarget;let i=e.data;if(!0===this.dataChannelsCompress.notify){const n=l(new Uint8Array(e.data));i=new TextDecoder().decode(n)}const t=JSON.parse(i);"connection.created"===t.event_type?this.writeDataChannelTimelineLog("notify-connection.created",n,t):"connection.destroyed"===t.event_type&&this.writeDataChannelTimelineLog("notify-connection.destroyed",n,t),this.signalingOnMessageTypeNotify(t,"datachannel")}:"push"===e.channel.label?e.channel.onmessage=e=>{let n=e.data;if(!0===this.dataChannelsCompress.push){const i=l(new Uint8Array(e.data));n=new TextDecoder().decode(i)}const i=JSON.parse(n);this.callbacks.push(i,"datachannel")}:"e2ee"===e.channel.label?e.channel.onmessage=e=>{const n=e.currentTarget,i=e.data;this.signalingOnMessageE2EE(i),this.writeDataChannelSignalingLog("onmessage-e2ee",n,i)}:"stats"===e.channel.label&&(e.channel.onmessage=async e=>{let n=e.data;if(!0===this.dataChannelsCompress.stats){const i=l(new Uint8Array(e.data));n=new TextDecoder().decode(i)}const i=JSON.parse(n);if("req-stats"===i.type){const e=await this.getStats();this.sendStatsMessage(e)}})}sendMessage(e){if(this.dataChannels.signaling){if(!0===this.dataChannelsCompress.signaling){const n=new TextEncoder().encode(JSON.stringify(e)),i=o(n,{});this.dataChannels.signaling.send(i)}else this.dataChannels.signaling.send(JSON.stringify(e));this.writeDataChannelSignalingLog(`send-${e.type}`,this.dataChannels.signaling,e)}else null!==this.ws&&(this.ws.send(JSON.stringify(e)),this.writeWebSocketSignalingLog(`send-${e.type}`,e))}sendE2EEMessage(e){this.dataChannels.e2ee?(this.dataChannels.e2ee.send(e),this.writeDataChannelSignalingLog("send-e2ee",this.dataChannels.e2ee,e)):null!==this.ws&&(this.ws.send(e),this.writeWebSocketSignalingLog("send-e2ee",e))}sendStatsMessage(e){if(this.dataChannels.stats){const n={type:"stats",reports:e};if(!0===this.dataChannelsCompress.stats){const e=new TextEncoder().encode(JSON.stringify(n)),i=o(e,{});this.dataChannels.stats.send(i)}else this.dataChannels.stats.send(JSON.stringify(n))}}getAudioTransceiver(){if(this.pc&&this.mids.audio){const e=this.pc.getTransceivers().find(e=>e.mid===this.mids.audio);return e||null}return null}getVideoTransceiver(){if(this.pc&&this.mids.video){const e=this.pc.getTransceivers().find(e=>e.mid===this.mids.video);return e||null}return null}soraCloseEvent(e,n,i){const t=class extends Event{constructor(e,n,i){super(e),i&&(i.code&&(this.code=i.code),i.reason&&(this.reason=i.reason),i.params&&(this.params=i.params)),this.title=n}};return new t(e,n,i)}get e2eeSelfFingerprint(){return this.options.e2ee&&this.e2ee?this.e2ee.selfFingerprint():void 0}get e2eeRemoteFingerprints(){return this.options.e2ee&&this.e2ee?this.e2ee.remoteFingerprints():void 0}get audio(){return null!==this.getAudioTransceiver()}get video(){return null!==this.getVideoTransceiver()}}class ue extends Ze{async connect(e){return this.options.multistream?await Promise.race([this.multiStream(e).finally(()=>{this.clearConnectionTimeout(),this.clearMonitorSignalingWebSocketEvent()}),this.setConnectionTimeout(),this.monitorSignalingWebSocketEvent()]):await Promise.race([this.singleStream(e).finally(()=>{this.clearConnectionTimeout(),this.clearMonitorSignalingWebSocketEvent()}),this.setConnectionTimeout(),this.monitorSignalingWebSocketEvent()]),this.monitorWebSocketEvent(),this.monitorPeerConnectionState(),e}async singleStream(e){await this.disconnect(),this.setupE2EE();const n=await this.createOffer(),i=await this.signaling(n);return this.startE2EE(),await this.connectPeerConnection(i),await this.setRemoteDescription(i),e.getTracks().forEach(n=>{this.pc&&this.pc.addTrack(n,e)}),this.stream=e,await this.createAnswer(i),this.sendAnswer(),this.pc&&this.e2ee&&this.pc.getSenders().forEach(e=>{this.e2ee&&this.e2ee.setupSenderTransform(e)}),await this.onIceCandidate(),await this.waitChangeConnectionStateConnected(),e}async multiStream(e){await this.disconnect(),this.setupE2EE();const n=await this.createOffer(),i=await this.signaling(n);return this.startE2EE(),await this.connectPeerConnection(i),this.pc&&(this.pc.ontrack=e=>{const n=e.streams[0];if(n){const i={"stream.id":n.id,id:e.track.id,label:e.track.label,enabled:e.track.enabled,kind:e.track.kind,muted:e.track.muted,readyState:e.track.readyState};(this.writePeerConnectionTimelineLog("ontrack",i),"default"!==n.id)&&n.id!==this.connectionId&&(this.e2ee&&this.e2ee.setupReceiverTransform(e.receiver),this.callbacks.track(e),n.onremovetrack=e=>{if(this.callbacks.removetrack(e),e.target){const n=this.remoteConnectionIds.indexOf(e.target.id);-1{this.pc&&this.pc.addTrack(n,e)}),this.stream=e,await this.createAnswer(i),this.sendAnswer(),this.pc&&this.e2ee&&this.pc.getSenders().forEach(e=>{this.e2ee&&this.e2ee.setupSenderTransform(e)}),await this.onIceCandidate(),await this.waitChangeConnectionStateConnected(),e}}class be extends Ze{async connect(){if(this.options.multistream)return await Promise.race([this.multiStream().finally(()=>{this.clearConnectionTimeout(),this.clearMonitorSignalingWebSocketEvent()}),this.setConnectionTimeout(),this.monitorSignalingWebSocketEvent()]),this.monitorWebSocketEvent(),void this.monitorPeerConnectionState();else{const e=await Promise.race([this.singleStream().finally(()=>{this.clearConnectionTimeout(),this.clearMonitorSignalingWebSocketEvent()}),this.setConnectionTimeout(),this.monitorSignalingWebSocketEvent()]);return this.monitorWebSocketEvent(),this.monitorPeerConnectionState(),e}}async singleStream(){await this.disconnect(),this.setupE2EE();const e=await this.createOffer(),n=await this.signaling(e);return this.startE2EE(),await this.connectPeerConnection(n),this.pc&&(this.pc.ontrack=e=>{this.stream=e.streams[0];const n=this.stream.id;if("default"!==n){const i={"stream.id":n,id:e.track.id,label:e.track.label,enabled:e.track.enabled,kind:e.track.kind,muted:e.track.muted,readyState:e.track.readyState};this.writePeerConnectionTimelineLog("ontrack",i),this.e2ee&&this.e2ee.setupReceiverTransform(e.receiver),this.callbacks.track(e),this.stream.onremovetrack=e=>{if(this.callbacks.removetrack(e),e.target){const n=this.remoteConnectionIds.indexOf(e.target.id);-1{const n=e.streams[0];if("default"!==n.id&&n.id!==this.connectionId){const i={"stream.id":n.id,id:e.track.id,label:e.track.label,enabled:e.track.enabled,kind:e.track.kind,muted:e.track.muted,readyState:e.track.readyState};this.writePeerConnectionTimelineLog("ontrack",i),this.e2ee&&this.e2ee.setupReceiverTransform(e.receiver),this.callbacks.track(e),n.onremovetrack=e=>{if(this.callbacks.removetrack(e),e.target){const n=this.remoteConnectionIds.indexOf(e.target.id);-1{if("undefined"!=typeof global);else if("undefined"!=typeof window)window.global=window;else if("undefined"!=typeof self)self.global=self;else throw new Error("cannot export Go (neither global, window nor self is defined)");if(global.require||"undefined"==typeof require||(global.require=require),!global.fs&&global.require){const e=require("fs");0!==Object.keys(e)&&(global.fs=e)}const e=()=>{const e=new Error("not implemented");return e.code="ENOSYS",e};if(!global.fs){let n="";global.fs={constants:{O_WRONLY:-1,O_RDWR:-1,O_CREAT:-1,O_TRUNC:-1,O_APPEND:-1,O_EXCL:-1},writeSync(e,t){n+=i.decode(t);const a=n.lastIndexOf("\n");return-1!=a&&(console.log(n.substr(0,a)),n=n.substr(a+1)),t.length},write(i,t,a,g,o,l){if(0!==a||g!==t.length||null!==o)return void l(e());const d=this.writeSync(i,t);l(null,d)},chmod(n,i,t){t(e())},chown(n,i,t,a){a(e())},close(n,i){i(e())},fchmod(n,i,t){t(e())},fchown(n,i,t,a){a(e())},fstat(n,i){i(e())},fsync(e,n){n(null)},ftruncate(n,i,t){t(e())},lchown(n,i,t,a){a(e())},link(n,i,t){t(e())},lstat(n,i){i(e())},mkdir(n,i,t){t(e())},open(n,i,t,a){a(e())},read(n,i,t,a,g,o){o(e())},readdir(n,i){i(e())},readlink(n,i){i(e())},rename(n,i,t){t(e())},rmdir(n,i){i(e())},stat(n,i){i(e())},symlink(n,i,t){t(e())},truncate(n,i,t){t(e())},unlink(n,i){i(e())},utimes(n,i,t,a){a(e())}}}if(global.process||(global.process={getuid(){return-1},getgid(){return-1},geteuid(){return-1},getegid(){return-1},getgroups(){throw e()},pid:-1,ppid:-1,umask(){throw e()},cwd(){throw e()},chdir(){throw e()}}),!global.crypto){const e=require("crypto");global.crypto={getRandomValues(n){e.randomFillSync(n)}}}global.performance||(global.performance={now(){const[e,n]=process.hrtime();return 1e3*e+n/1e6}}),global.TextEncoder||(global.TextEncoder=require("util").TextEncoder),global.TextDecoder||(global.TextDecoder=require("util").TextDecoder);const n=new TextEncoder("utf-8"),i=new TextDecoder("utf-8");if(global.Go=class{constructor(){this.argv=["js"],this.env={},this.exit=e=>{0!==e&&console.warn("exit code:",e)},this._exitPromise=new Promise(e=>{this._resolveExitPromise=e}),this._pendingEvent=null,this._scheduledTimeouts=new Map,this._nextCallbackTimeoutID=1;const e=(e,n)=>{var i=Math.floor;this.mem.setUint32(e+0,n,!0),this.mem.setUint32(e+4,i(n/4294967296),!0)},t=e=>{const n=this.mem.getUint32(e+0,!0),i=this.mem.getInt32(e+4,!0);return n+4294967296*i},g=e=>{const n=this.mem.getFloat64(e,!0);if(0!==n){if(!isNaN(n))return n;const i=this.mem.getUint32(e,!0);return this._values[i]}},o=(e,n)=>{if("number"==typeof n&&0!==n)return isNaN(n)?(this.mem.setUint32(e+4,2146959360,!0),void this.mem.setUint32(e,0,!0)):void this.mem.setFloat64(e,n,!0);if(void 0===n)return void this.mem.setFloat64(e,0,!0);let i=this._ids.get(n);void 0===i&&(i=this._idPool.pop(),void 0===i&&(i=this._values.length),this._values[i]=n,this._goRefCounts[i]=0,this._ids.set(n,i)),this._goRefCounts[i]++;let t=0;switch(typeof n){case"object":null!==n&&(t=1);break;case"string":t=2;break;case"symbol":t=3;break;case"function":t=4;}this.mem.setUint32(e+4,2146959360|t,!0),this.mem.setUint32(e,i,!0)},l=e=>{const n=t(e+0),i=t(e+8);return new Uint8Array(this._inst.exports.mem.buffer,n,i)},d=e=>{const n=t(e+0),o=t(e+8),l=Array(o);for(let t=0;t{const n=t(e+0),a=t(e+8);return i.decode(new DataView(this._inst.exports.mem.buffer,n,a))},s=Date.now()-performance.now();this.importObject={go:{"runtime.wasmExit":e=>{const n=this.mem.getInt32(e+8,!0);this.exited=!0,delete this._inst,delete this._values,delete this._goRefCounts,delete this._ids,delete this._idPool,this.exit(n)},"runtime.wasmWrite":e=>{const i=t(e+8),a=t(e+16),g=this.mem.getInt32(e+24,!0);fs.writeSync(i,new Uint8Array(this._inst.exports.mem.buffer,a,g))},"runtime.resetMemoryDataView":()=>{this.mem=new DataView(this._inst.exports.mem.buffer)},"runtime.nanotime1":n=>{e(n+8,1e6*(s+performance.now()))},"runtime.walltime1":n=>{const i=new Date().getTime();e(n+8,i/1e3),this.mem.setInt32(n+16,1e6*(i%1e3),!0)},"runtime.scheduleTimeoutEvent":e=>{const n=this._nextCallbackTimeoutID;this._nextCallbackTimeoutID++,this._scheduledTimeouts.set(n,setTimeout(()=>{for(this._resume();this._scheduledTimeouts.has(n);)console.warn("scheduleTimeoutEvent: missed timeout event"),this._resume()},t(e+8)+1)),this.mem.setInt32(e+16,n,!0)},"runtime.clearTimeoutEvent":e=>{const n=this.mem.getInt32(e+8,!0);clearTimeout(this._scheduledTimeouts.get(n)),this._scheduledTimeouts.delete(n)},"runtime.getRandomData":e=>{crypto.getRandomValues(l(e+8))},"syscall/js.finalizeRef":e=>{const n=this.mem.getUint32(e+8,!0);if(this._goRefCounts[n]--,0===this._goRefCounts[n]){const e=this._values[n];this._values[n]=null,this._ids.delete(e),this._idPool.push(n)}},"syscall/js.stringVal":e=>{o(e+24,c(e+8))},"syscall/js.valueGet":e=>{const n=Reflect.get(g(e+8),c(e+16));e=this._inst.exports.getsp(),o(e+32,n)},"syscall/js.valueSet":e=>{Reflect.set(g(e+8),c(e+16),g(e+32))},"syscall/js.valueDelete":e=>{Reflect.deleteProperty(g(e+8),c(e+16))},"syscall/js.valueIndex":e=>{o(e+24,Reflect.get(g(e+8),t(e+16)))},"syscall/js.valueSetIndex":e=>{Reflect.set(g(e+8),t(e+16),g(e+24))},"syscall/js.valueCall":e=>{try{const n=g(e+8),i=Reflect.get(n,c(e+16)),t=d(e+32),a=Reflect.apply(i,n,t);e=this._inst.exports.getsp(),o(e+56,a),this.mem.setUint8(e+64,1)}catch(n){o(e+56,n),this.mem.setUint8(e+64,0)}},"syscall/js.valueInvoke":e=>{try{const n=g(e+8),i=d(e+16),t=Reflect.apply(n,void 0,i);e=this._inst.exports.getsp(),o(e+40,t),this.mem.setUint8(e+48,1)}catch(n){o(e+40,n),this.mem.setUint8(e+48,0)}},"syscall/js.valueNew":e=>{try{const n=g(e+8),i=d(e+16),t=Reflect.construct(n,i);e=this._inst.exports.getsp(),o(e+40,t),this.mem.setUint8(e+48,1)}catch(n){o(e+40,n),this.mem.setUint8(e+48,0)}},"syscall/js.valueLength":n=>{e(n+16,parseInt(g(n+8).length))},"syscall/js.valuePrepareString":i=>{const t=n.encode(g(i+8)+"");o(i+16,t),e(i+24,t.length)},"syscall/js.valueLoadString":e=>{const n=g(e+8);l(e+16).set(n)},"syscall/js.valueInstanceOf":e=>{this.mem.setUint8(e+24,g(e+8)instanceof g(e+16)?1:0)},"syscall/js.copyBytesToGo":n=>{const i=l(n+8),t=g(n+32);if(!(t instanceof Uint8Array||t instanceof Uint8ClampedArray))return void this.mem.setUint8(n+48,0);const a=t.subarray(0,i.length);i.set(a),e(n+40,a.length),this.mem.setUint8(n+48,1)},"syscall/js.copyBytesToJS":n=>{const i=g(n+8),t=l(n+16);if(!(i instanceof Uint8Array||i instanceof Uint8ClampedArray))return void this.mem.setUint8(n+48,0);const a=t.subarray(0,i.length);i.set(a),e(n+40,a.length),this.mem.setUint8(n+48,1)},debug:e=>{console.log(e)}}}}async run(e){this._inst=e,this.mem=new DataView(this._inst.exports.mem.buffer),this._values=[NaN,0,null,!0,!1,global,this],this._goRefCounts=Array(this._values.length).fill(1/0),this._ids=new Map([[0,1],[null,2],[!0,3],[!1,4],[global,5],[this,6]]),this._idPool=[],this.exited=!1;let i=4096;const t=e=>{const t=i,a=n.encode(e+"\0");return new Uint8Array(this.mem.buffer,i,a.length).set(a),i+=a.length,0!=i%8&&(i+=8-i%8),t},a=this.argv.length,g=[];this.argv.forEach(e=>{g.push(t(e))}),g.push(0);const o=Object.keys(this.env).sort();o.forEach(e=>{g.push(t(`${e}=${this.env[e]}`))}),g.push(0);const l=i;g.forEach(e=>{this.mem.setUint32(i,e,!0),this.mem.setUint32(i+4,0,!0),i+=8}),this._inst.exports.run(a,l),this.exited&&this._resolveExitPromise(),await this._exitPromise}_resume(){if(this.exited)throw new Error("Go program has already exited");this._inst.exports.resume(),this.exited&&this._resolveExitPromise()}_makeFuncWrapper(e){const n=this;return function(){const i={id:e,this:this,args:arguments};return n._pendingEvent=i,n._resume(),i.result}}},global.require&&global.require.main===module&&global.process&&global.process.versions&&!global.process.versions.electron){3>process.argv.length&&(console.error("usage: go_js_wasm_exec [wasm binary] [arguments]"),process.exit(1));const e=new Go;e.argv=process.argv.slice(2),e.env=Object.assign({TMPDIR:require("os").tmpdir()},process.env),e.exit=process.exit,WebAssembly.instantiate(fs.readFileSync(process.argv[2]),e.importObject).then(n=>(process.on("exit",n=>{0!==n||e.exited||(e._pendingEvent={id:0},e._resume())}),e.run(n.instance))).catch(e=>{console.error(e),process.exit(1)})}})()}function o(e,n){n||(n={});var i=de();i.p(e);var t=ce(e,n,2,4);return Ce(t,n),se(t,t.length-4,i.d()),t}function l(e,n){return z((Ie(e),e.subarray(2,-4)),n)}function d(){const e=window.navigator.userAgent.toLocaleLowerCase();if(-1!==e.indexOf("edge"))return"edge";return-1!==e.indexOf("chrome")&&-1===e.indexOf("edge")?"chrome":-1!==e.indexOf("safari")&&-1===e.indexOf("chrome")?"safari":-1===e.indexOf("opera")?-1===e.indexOf("firefox")?null:"firefox":"opera"}function c(){if(!window.RTCRtpSender)return!1;if(!RTCRtpSender.getCapabilities)return!1;const e=RTCRtpSender.getCapabilities("video");if(!e)return!1;const n=e.headerExtensions.map(e=>e.uri),i=["urn:ietf:params:rtp-hdrext:sdes:mid","urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id","urn:ietf:params:rtp-hdrext:sdes:repaired-rtp-stream-id"].every(e=>n.includes(e));return i}function s(){return"safari"===d()}function C(e,n,i,t,a){if("sendrecv"!==n&&"sendonly"!==n&&"recvonly"!==n)throw new Error("Unknown role type");if(null===i||void 0===i)throw new Error("channelId can not be null or undefined");const g={type:"connect",sora_client:"Sora JavaScript SDK 2021.1.7",environment:window.navigator.userAgent,role:n,channel_id:i,sdp:e,audio:!0,video:!0};if(void 0!==t&&(g.metadata=t),"signalingNotifyMetadata"in a&&(g.signaling_notify_metadata=a.signalingNotifyMetadata),"multistream"in a&&!0===a.multistream&&(g.multistream=!0,"spotlight"in a&&(g.spotlight=a.spotlight,"spotlightNumber"in a&&(g.spotlight_number=a.spotlightNumber)),!0===g.spotlight)){const e=["none","r0","r1","r2"];void 0!==a.spotlightFocusRid&&0<=e.indexOf(a.spotlightFocusRid)&&(g.spotlight_focus_rid=a.spotlightFocusRid),void 0!==a.spotlightUnfocusRid&&0<=e.indexOf(a.spotlightUnfocusRid)&&(g.spotlight_unfocus_rid=a.spotlightUnfocusRid)}if("simulcast"in a||"simulcastRid"in a){"simulcast"in a&&!0===a.simulcast&&(g.simulcast=!0);void 0!==a.simulcastRid&&0<=["r0","r1","r2"].indexOf(a.simulcastRid)&&(g.simulcast_rid=a.simulcastRid)}"clientId"in a&&void 0!==a.clientId&&(g.client_id=a.clientId),"dataChannelSignaling"in a&&"boolean"==typeof a.dataChannelSignaling&&(g.data_channel_signaling=a.dataChannelSignaling),"ignoreDisconnectWebSocket"in a&&"boolean"==typeof a.ignoreDisconnectWebSocket&&(g.ignore_disconnect_websocket=a.ignoreDisconnectWebSocket);const o=["audioCodecType","audioBitRate"],l=["audioOpusParamsChannels","audioOpusParamsClockRate","audioOpusParamsMaxplaybackrate","audioOpusParamsStereo","audioOpusParamsSpropStereo","audioOpusParamsMinptime","audioOpusParamsPtime","audioOpusParamsUseinbandfec","audioOpusParamsUsedtx"],d=["videoCodecType","videoBitRate"],s=Object.assign({},a);Object.keys(s).forEach(e=>{"audio"===e&&"boolean"==typeof s[e]||"video"===e&&"boolean"==typeof s[e]||0<=o.indexOf(e)&&null!==s[e]||0<=l.indexOf(e)&&null!==s[e]||0<=d.indexOf(e)&&null!==s[e]||delete s[e]}),void 0!==s.audio&&(g.audio=s.audio);const C=Object.keys(s).some(e=>0<=o.indexOf(e));g.audio&&C&&(g.audio={},"audioCodecType"in s&&(g.audio.codec_type=s.audioCodecType),"audioBitRate"in s&&(g.audio.bit_rate=s.audioBitRate));const I=Object.keys(s).some(e=>0<=l.indexOf(e));g.audio&&I&&("object"!=typeof g.audio&&(g.audio={}),g.audio.opus_params={},"audioOpusParamsChannels"in s&&(g.audio.opus_params.channels=s.audioOpusParamsChannels),"audioOpusParamsClockRate"in s&&(g.audio.opus_params.clock_rate=s.audioOpusParamsClockRate),"audioOpusParamsMaxplaybackrate"in s&&(g.audio.opus_params.maxplaybackrate=s.audioOpusParamsMaxplaybackrate),"audioOpusParamsStereo"in s&&(g.audio.opus_params.stereo=s.audioOpusParamsStereo),"audioOpusParamsSpropStereo"in s&&(g.audio.opus_params.sprop_stereo=s.audioOpusParamsSpropStereo),"audioOpusParamsMinptime"in s&&(g.audio.opus_params.minptime=s.audioOpusParamsMinptime),"audioOpusParamsPtime"in s&&(g.audio.opus_params.ptime=s.audioOpusParamsPtime),"audioOpusParamsUseinbandfec"in s&&(g.audio.opus_params.useinbandfec=s.audioOpusParamsUseinbandfec),"audioOpusParamsUsedtx"in s&&(g.audio.opus_params.usedtx=s.audioOpusParamsUsedtx)),void 0!==s.video&&(g.video=s.video);const r=Object.keys(s).some(e=>0<=d.indexOf(e));if(g.video&&r&&(g.video={},"videoCodecType"in s&&(g.video.codec_type=s.videoCodecType),"videoBitRate"in s&&(g.video.bit_rate=s.videoBitRate)),g.simulcast&&!c()&&"recvonly"!==n)throw new Error("Simulcast can not be used with this browser");if(!0===a.e2ee){if(void 0===g.signaling_notify_metadata&&(g.signaling_notify_metadata={}),null===g.signaling_notify_metadata||"object"!=typeof g.signaling_notify_metadata)throw new Error("E2EE failed. Options signalingNotifyMetadata must be type 'object'");!0===g.video&&(g.video={}),g.video&&(g.video.codec_type="VP8"),g.e2ee=!0}return g}function I(e){if(e.authn_metadata!==void 0)return e.authn_metadata;return void 0===e.metadata?null:e.metadata}function r(e){if(e.data&&Array.isArray(e.data))return e.data;return e.metadata_list&&Array.isArray(e.metadata_list)?e.metadata_list:[]}function m(e){return"object"==typeof e&&null!==e&&"pre_key_bundle"in e?e.pre_key_bundle:null}function A(e,n,i){const t=e=>{if(e&&"object"==typeof e){let n=null;try{n=Object.keys(JSON.parse(JSON.stringify(e)))}catch(e){}n&&Array.isArray(n)?n.forEach(n=>{console.group(n),t(e[n]),console.groupEnd()}):console.info(e)}else console.info(e)};let a="";window.performance&&(a="["+(window.performance.now()/1e3).toFixed(3)+"]"),e&&(a=a+"["+e+"]"),console.info!==void 0&&console.group!==void 0?(console.group(a+" "+n),t(i),console.groupEnd()):console.log(a+" "+n+"\n",i)}function Z(e,n,i){const t=new Event(e);try{t.data=JSON.parse(JSON.stringify(n))}catch(e){t.data=n}return t.transportType=i,t}function u(e){return{binaryType:e.binaryType,bufferedAmount:e.bufferedAmount,bufferedAmountLowThreshold:e.bufferedAmountLowThreshold,id:e.id,label:e.label,maxPacketLifeTime:e.maxPacketLifeTime,maxRetransmits:e.maxRetransmits,negotiated:e.negotiated,ordered:e.ordered,protocol:e.protocol,readyState:e.readyState,reliable:e.reliable}}function b(e,n,i,t,a){const g=new Event(e);try{g.data=JSON.parse(JSON.stringify(n))}catch(e){g.data=n}return g.logType=i,g.dataChannelId=t,g.dataChannelLabel=a,g}class p{constructor(){const e=!!RTCRtpSender.prototype.createEncodedStreams;if(!e)throw new Error("E2EE is not supported in this browser.");this.worker=null,this.onWorkerDisconnect=null}startWorker(){const e=atob("InVzZSBzdHJpY3QiOwovKiBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnMgKi8KY29uc3QgY29ubmVjdGlvbklkTGVuZ3RoID0gMjY7CmZ1bmN0aW9uIGJ5dGVDb3VudChuKSB7CiAgICBpZiAobiA9PSAwKSB7CiAgICAgICAgcmV0dXJuIDE7CiAgICB9CiAgICAvLyBsb2cyNTYoeCkgPSBsb2coeCkgLyBsb2coMjU2KQogICAgcmV0dXJuIE1hdGguZmxvb3IoTWF0aC5sb2cobikgLyBNYXRoLmxvZygyICoqIDgpICsgMSk7Cn0KZnVuY3Rpb24gYXJyYXlCdWZmZXJUb051bWJlcihhcnJheUJ1ZmZlcikgewogICAgLy8gMzJiaXQg44G+44Gn44KS5oOz5a6aIChCaWdJbnQg44G444Gu5pu444GN5o+b44GI5pmC44Gr6KaB5L+u5q2jKQogICAgY29uc3QgbmV3QXJyYXlCdWZmZXIgPSBuZXcgQXJyYXlCdWZmZXIoVWludDMyQXJyYXkuQllURVNfUEVSX0VMRU1FTlQpOwogICAgY29uc3QgbmV3RGF0YVZpZXcgPSBuZXcgRGF0YVZpZXcobmV3QXJyYXlCdWZmZXIpOwogICAgY29uc3QgZGF0YVZpZXcgPSBuZXcgRGF0YVZpZXcoYXJyYXlCdWZmZXIpOwogICAgY29uc3QgcGFkZGluZ0xlbmd0aCA9IFVpbnQzMkFycmF5LkJZVEVTX1BFUl9FTEVNRU5UIC0gZGF0YVZpZXcuYnl0ZUxlbmd0aDsKICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcGFkZGluZ0xlbmd0aDsgaSArPSAxKSB7CiAgICAgICAgbmV3RGF0YVZpZXcuc2V0VWludDgoaSwgMCk7CiAgICB9CiAgICBmb3IgKGxldCBpID0gcGFkZGluZ0xlbmd0aCwgaiA9IDA7IGkgPCBVaW50MzJBcnJheS5CWVRFU19QRVJfRUxFTUVOVDsgaSArPSAxLCBqICs9IDEpIHsKICAgICAgICBuZXdEYXRhVmlldy5zZXRVaW50OChpLCBkYXRhVmlldy5nZXRVaW50OChqKSk7CiAgICB9CiAgICByZXR1cm4gbmV3RGF0YVZpZXcuZ2V0VWludDMyKDApOwp9CmZ1bmN0aW9uIGVuY29kZVNGcmFtZUhlYWRlcihzLCBjb3VudCwga2V5SWQpIHsKICAgIC8vICAwIDEgMiAzIDQgNSA2IDcKICAgIC8vICstKy0rLSstKy0rLSstKy0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSsKICAgIC8vIHxTfExFTiAgfDF8S0xFTiB8ICAgS0lELi4uIChsZW5ndGg9S0xFTikgICAgfCAgICBDVFIuLi4gKGxlbmd0aD1MRU4pICAgIHwKICAgIC8vICstKy0rLSstKy0rLSstKy0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSsKICAgIC8vIFM6IDEgYml0CiAgICAvLyBMRU46IDMgYml0CiAgICAvLyBYOiAxIGJpdAogICAgLy8gS0xFTjogMyBiaXQKICAgIC8vIEtJRDogS0xFTiBieXRlCiAgICAvLyBDVFI6IExFTiBieXRlCiAgICAvLyBUT0RPOiBrZXlJZCAoS0lEKSDjgYwgTnVtYmVyLk1BWF9TQUZFX0lOVEVHRVIsIDcgYnl0ZSDjgpLotoXjgYjjgabjgYTjgZ/loLTlkIjjga/jgqjjg6njg7zjgYvkvovlpJYKICAgIC8vIFRPRE86IGNvdW50IChDVFIpIOOBjCBOdW1iZXIuTUFYX1NBRkVfSU5URUdFUiwgNyBieXRlIOOCkui2heOBiOOBpuOBhOOBn+WgtOWQiOOBr+OCqOODqeODvOOBi+S+i+WklgogICAgaWYgKG1heEtleUlkIDwga2V5SWQgfHwgbWF4Q291bnQgPCBjb3VudCkgewogICAgICAgIHRocm93IG5ldyBFcnJvcigiRVhDRUVERUQtTUFYSU1VTS1CUk9BRENBU1RJTkctVElNRSIpOwogICAgfQogICAgY29uc3Qga2xlbiA9IGJ5dGVDb3VudChrZXlJZCk7CiAgICBjb25zdCBsZW4gPSBieXRlQ291bnQoY291bnQpOwogICAgY29uc3QgaGVhZGVyQnVmZmVyID0gbmV3IEFycmF5QnVmZmVyKDEgKyBrbGVuICsgbGVuKTsKICAgIGNvbnN0IGhlYWRlckRhdGFWaWV3ID0gbmV3IERhdGFWaWV3KGhlYWRlckJ1ZmZlcik7CiAgICAvLyBTLCBMRU4sIDEsIEtMRU4g44GnIDEgYnl0ZQogICAgaGVhZGVyRGF0YVZpZXcuc2V0VWludDgoMCwgKHMgPDwgNykgKyAobGVuIDw8IDQpICsgKDEgPDwgMykgKyBrbGVuKTsKICAgIGNvbnN0IGhlYWRlclVpbnQ4QXJyYXkgPSBuZXcgVWludDhBcnJheShoZWFkZXJCdWZmZXIpOwogICAgY29uc3Qga2V5SWRCdWZmZXIgPSBuZXcgQXJyYXlCdWZmZXIoVWludDMyQXJyYXkuQllURVNfUEVSX0VMRU1FTlQpOwogICAgY29uc3Qga2V5SWREYXRhVmlldyA9IG5ldyBEYXRhVmlldyhrZXlJZEJ1ZmZlcik7CiAgICBrZXlJZERhdGFWaWV3LnNldFVpbnQzMigwLCBrZXlJZCk7CiAgICBjb25zdCBrZXlJZFVpbnQ4QXJyYXkgPSBuZXcgVWludDhBcnJheShrZXlJZEJ1ZmZlcik7CiAgICBoZWFkZXJVaW50OEFycmF5LnNldChrZXlJZFVpbnQ4QXJyYXkuc3ViYXJyYXkoVWludDMyQXJyYXkuQllURVNfUEVSX0VMRU1FTlQgLSBrbGVuKSwgMSk7CiAgICBjb25zdCBjb3VudEJ1ZmZlciA9IG5ldyBBcnJheUJ1ZmZlcihVaW50MzJBcnJheS5CWVRFU19QRVJfRUxFTUVOVCk7CiAgICBjb25zdCBjb3VudERhdGFWaWV3ID0gbmV3IERhdGFWaWV3KGNvdW50QnVmZmVyKTsKICAgIGNvdW50RGF0YVZpZXcuc2V0VWludDMyKDAsIGNvdW50KTsKICAgIGNvbnN0IGNvdW50VWludDhBcnJheSA9IG5ldyBVaW50OEFycmF5KGNvdW50QnVmZmVyKTsKICAgIGhlYWRlclVpbnQ4QXJyYXkuc2V0KGNvdW50VWludDhBcnJheS5zdWJhcnJheShVaW50MzJBcnJheS5CWVRFU19QRVJfRUxFTUVOVCAtIGxlbiksIGtsZW4gKyAxKTsKICAgIHJldHVybiBoZWFkZXJVaW50OEFycmF5Owp9CmZ1bmN0aW9uIHNwbGl0SGVhZGVyKHNmcmFtZSkgewogICAgY29uc3Qgc2ZyYW1lRGF0YVZpZXcgPSBuZXcgRGF0YVZpZXcoc2ZyYW1lKTsKICAgIGNvbnN0IGhlYWRlciA9IHNmcmFtZURhdGFWaWV3LmdldFVpbnQ4KDApOwogICAgY29uc3QgbGVuID0gKGhlYWRlciAmIDB4NzApID4+IDQ7CiAgICBjb25zdCBrbGVuID0gaGVhZGVyICYgMHgwNzsKICAgIGNvbnN0IHNmcmFtZUhlYWRlckxlbmd0aCA9IDEgKyBrbGVuICsgbGVuOwogICAgY29uc3Qgc2ZyYW1lSGVhZGVyID0gc2ZyYW1lLnNsaWNlKDAsIHNmcmFtZUhlYWRlckxlbmd0aCk7CiAgICBpZiAoc2ZyYW1lSGVhZGVyLmJ5dGVMZW5ndGggPCBzZnJhbWVIZWFkZXJMZW5ndGgpIHsKICAgICAgICB0aHJvdyBuZXcgRXJyb3IoIlVORVhQRUNURUQtU0ZSQU1FLUxFTkdUSCIpOwogICAgfQogICAgY29uc3QgY29ubmVjdGlvbklkID0gc2ZyYW1lLnNsaWNlKHNmcmFtZUhlYWRlckxlbmd0aCwgc2ZyYW1lSGVhZGVyTGVuZ3RoICsgY29ubmVjdGlvbklkTGVuZ3RoKTsKICAgIGNvbnN0IGVuY3J5cHRlZEZyYW1lID0gc2ZyYW1lLnNsaWNlKHNmcmFtZUhlYWRlckxlbmd0aCArIGNvbm5lY3Rpb25JZExlbmd0aCwgc2ZyYW1lLmJ5dGVMZW5ndGgpOwogICAgcmV0dXJuIFtzZnJhbWVIZWFkZXIsIGNvbm5lY3Rpb25JZCwgZW5jcnlwdGVkRnJhbWVdOwp9CmZ1bmN0aW9uIHBhcnNlU0ZyYW1lSGVhZGVyKHNmcmFtZUhlYWRlcikgewogICAgY29uc3Qgc2ZyYW1lSGVhZGVyRGF0YVZpZXcgPSBuZXcgRGF0YVZpZXcoc2ZyYW1lSGVhZGVyKTsKICAgIGNvbnN0IGhlYWRlciA9IHNmcmFtZUhlYWRlckRhdGFWaWV3LmdldFVpbnQ4KDApOwogICAgY29uc3QgcyA9IChoZWFkZXIgJiAweDgwKSA+PiA3OwogICAgY29uc3QgbGVuID0gKGhlYWRlciAmIDB4NzApID4+IDQ7CiAgICBjb25zdCB4ID0gKGhlYWRlciAmIDB4MDgpID4+IDM7CiAgICBjb25zdCBrbGVuID0gaGVhZGVyICYgMHgwNzsKICAgIC8vIHggZmxhZwogICAgaWYgKHggIT09IDEpIHsKICAgICAgICB0aHJvdyBuZXcgRXJyb3IoIlVORVhQRUNURUQtWC1GTEFHIik7CiAgICB9CiAgICBjb25zdCBoZWFkZXJMZW5ndGggPSAxICsga2xlbiArIGxlbjsKICAgIGlmIChzZnJhbWVIZWFkZXJEYXRhVmlldy5ieXRlTGVuZ3RoIDwgaGVhZGVyTGVuZ3RoKSB7CiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCJVTkVYUEVDVEVELVNGUkFNRS1IRUFERVItTEVOR1RIIik7CiAgICB9CiAgICBjb25zdCBrZXlJZEJ1ZmZlciA9IHNmcmFtZUhlYWRlci5zbGljZSgxLCAxICsga2xlbik7CiAgICBjb25zdCBrZXlJZCA9IGFycmF5QnVmZmVyVG9OdW1iZXIoa2V5SWRCdWZmZXIpOwogICAgY29uc3QgY291bnRCdWZmZXIgPSBzZnJhbWVIZWFkZXIuc2xpY2UoMSArIGtsZW4sIGhlYWRlckxlbmd0aCk7CiAgICBjb25zdCBjb3VudCA9IGFycmF5QnVmZmVyVG9OdW1iZXIoY291bnRCdWZmZXIpOwogICAgcmV0dXJuIFtzLCBjb3VudCwga2V5SWRdOwp9Ci8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC90cmlwbGUtc2xhc2gtcmVmZXJlbmNlLCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnMgKi8KLy8vIDxyZWZlcmVuY2UgcGF0aD0iLi9zZnJhbWUudHMiLz4KLy8gVE9ETzog5omx44GG5pWw5YCk44GM5aSn44GN44GE566H5omA44Gn44GvIE51bWJlciDjgYvjgokgQmlnSW50IOOBq+e9ruOBjeaPm+OBiOOCiwovLyBUT0RPOiBCaWdJbnQg44Gr572u44GN5o+b44GI44KL6Zqb44Gr5aSJ5pu044GZ44KLCmNvbnN0IG1heEtleUlkID0gMiAqKiAzMjsKY29uc3QgbWF4Q291bnQgPSAyICoqIDMyOwpjb25zdCBzZWxmRGVyaXZlS2V5TWFwID0gbmV3IE1hcCgpOwpjb25zdCBjb3VudE1hcCA9IG5ldyBNYXAoKTsKY29uc3Qgd3JpdGVJVk1hcCA9IG5ldyBNYXAoKTsKY29uc3QgcmVtb3RlRGVyaXZlS2V5TWFwID0gbmV3IE1hcCgpOwpjb25zdCBsYXRlc3RSZW1vdGVLZXlJZE1hcCA9IG5ldyBNYXAoKTsKY29uc3QgbGl0dGxlRW5kaWFuID0gdHJ1ZTsKY29uc3QgYmlnRW5kaWFuID0gIWxpdHRsZUVuZGlhbjsKY29uc3QgdGV4dEVuY29kZXIgPSBuZXcgVGV4dEVuY29kZXIoKTsKY29uc3QgdGV4dERlY29kZXIgPSBuZXcgVGV4dERlY29kZXIoKTsKLy8gVlA4IOOBruOBvwovLyBUT0RPKG5ha2FpKTogVlA5IC8gQVYxIOOCguWwhuadpeeahOOBq+WvvuW/nOOCguiAg+OBiOOCiwpjb25zdCB1bmVuY3J5cHRlZEJ5dGVzID0gewogICAgLy8gSSDjg5Xjg6zjg7zjg6AKICAgIGtleTogMTAsCiAgICAvLyDpnZ4gSSDjg5Xjg6zjg7zjg6AKICAgIGRlbHRhOiAzLAogICAgLy8g44Kq44O844OH44Kj44KqCiAgICB1bmRlZmluZWQ6IDEsCn07CmZ1bmN0aW9uIGdldENvdW50KGNvbm5lY3Rpb25JZCkgewogICAgcmV0dXJuIGNvdW50TWFwLmdldChjb25uZWN0aW9uSWQpIHx8IDA7Cn0KZnVuY3Rpb24gc2V0Q291bnQoY29ubmVjdGlvbklkLCBjb3VudCkgewogICAgcmV0dXJuIGNvdW50TWFwLnNldChjb25uZWN0aW9uSWQsIGNvdW50KTsKfQpmdW5jdGlvbiBnZXRSZW1vdGVEZXJpdmVLZXkoY29ubmVjdGlvbklkLCBrZXlJZCkgewogICAgaWYgKCFyZW1vdGVEZXJpdmVLZXlNYXAuaGFzKGNvbm5lY3Rpb25JZCkpIHsKICAgICAgICB0aHJvdyBuZXcgRXJyb3IoIlJFTU9URS1ERVJJVkVLRVktTUFQLU5PVC1GT1VORCIpOwogICAgfQogICAgY29uc3QgZGVyaXZlS2V5TWFwID0gcmVtb3RlRGVyaXZlS2V5TWFwLmdldChjb25uZWN0aW9uSWQpOwogICAgaWYgKCFkZXJpdmVLZXlNYXApIHsKICAgICAgICByZXR1cm47CiAgICB9CiAgICByZXR1cm4gZGVyaXZlS2V5TWFwLmdldChrZXlJZCk7Cn0KZnVuY3Rpb24gc2V0UmVtb3RlRGVyaXZlS2V5KGNvbm5lY3Rpb25JZCwga2V5SWQsIGRlcml2ZUtleSkgewogICAgbGV0IGRlcml2ZUtleU1hcCA9IHJlbW90ZURlcml2ZUtleU1hcC5nZXQoY29ubmVjdGlvbklkKTsKICAgIGlmICghZGVyaXZlS2V5TWFwKSB7CiAgICAgICAgZGVyaXZlS2V5TWFwID0gbmV3IE1hcCgpOwogICAgfQogICAgZGVyaXZlS2V5TWFwLnNldChrZXlJZCwgZGVyaXZlS2V5KTsKICAgIHJlbW90ZURlcml2ZUtleU1hcC5zZXQoY29ubmVjdGlvbklkLCBkZXJpdmVLZXlNYXApOwp9CmZ1bmN0aW9uIHNldExhdGVzdFJlbW90ZUtleUlkKGNvbm5lY3Rpb25JZCwga2V5SWQpIHsKICAgIGNvbnN0IGxhdGVzdFJlbW90ZUtleUlkID0gbGF0ZXN0UmVtb3RlS2V5SWRNYXAuZ2V0KGNvbm5lY3Rpb25JZCk7CiAgICBpZiAobGF0ZXN0UmVtb3RlS2V5SWQpIHsKICAgICAgICBpZiAobGF0ZXN0UmVtb3RlS2V5SWQgPCBrZXlJZCkgewogICAgICAgICAgICBsYXRlc3RSZW1vdGVLZXlJZE1hcC5zZXQoY29ubmVjdGlvbklkLCBrZXlJZCk7CiAgICAgICAgfQogICAgfQogICAgZWxzZSB7CiAgICAgICAgbGF0ZXN0UmVtb3RlS2V5SWRNYXAuc2V0KGNvbm5lY3Rpb25JZCwga2V5SWQpOwogICAgfQp9CmZ1bmN0aW9uIHJlbW92ZU9sZFJlbW90ZURlcml2ZUtleXMoKSB7CiAgICBsYXRlc3RSZW1vdGVLZXlJZE1hcC5mb3JFYWNoKChsYXRlc3RLZXlJZCwgY29ubmVjdGlvbklkKSA9PiB7CiAgICAgICAgY29uc3QgZGVyaXZlS2V5TWFwID0gcmVtb3RlRGVyaXZlS2V5TWFwLmdldChjb25uZWN0aW9uSWQpOwogICAgICAgIGlmIChkZXJpdmVLZXlNYXApIHsKICAgICAgICAgICAgZGVyaXZlS2V5TWFwLmZvckVhY2goKF8sIGtleUlkKSA9PiB7CiAgICAgICAgICAgICAgICBpZiAobGF0ZXN0S2V5SWQgIT09IGtleUlkKSB7CiAgICAgICAgICAgICAgICAgICAgZGVyaXZlS2V5TWFwLmRlbGV0ZShrZXlJZCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0pOwogICAgICAgIH0KICAgIH0pOwp9CmZ1bmN0aW9uIHJlbW92ZURlcml2ZUtleShjb25uZWN0aW9uSWQpIHsKICAgIGxhdGVzdFJlbW90ZUtleUlkTWFwLmRlbGV0ZShjb25uZWN0aW9uSWQpOwogICAgcmVtb3RlRGVyaXZlS2V5TWFwLmRlbGV0ZShjb25uZWN0aW9uSWQpOwp9CmZ1bmN0aW9uIGdldExhdGVzdFNlbGZEZXJpdmVLZXkoKSB7CiAgICBjb25zdCBkZXJpdmVLZXkgPSBzZWxmRGVyaXZlS2V5TWFwLmdldCgibGF0ZXN0Iik7CiAgICBpZiAoIWRlcml2ZUtleSkgewogICAgICAgIHRocm93IG5ldyBFcnJvcigiTEFURVNULVNFTEYtREVSSVZFS0VZLU5PVF9GT1VORCIpOwogICAgfQogICAgcmV0dXJuIGRlcml2ZUtleTsKfQpmdW5jdGlvbiBzZXRTZWxmRGVyaXZlS2V5KGNvbm5lY3Rpb25JZCwga2V5SWQsIGRlcml2ZUtleSkgewogICAgY29uc3QgY3VycmVudFNlbGZEZXJpdmVLZXkgPSBzZWxmRGVyaXZlS2V5TWFwLmdldCgibGF0ZXN0Iik7CiAgICBpZiAoY3VycmVudFNlbGZEZXJpdmVLZXkpIHsKICAgICAgICBpZiAoY3VycmVudFNlbGZEZXJpdmVLZXlbImtleUlkIl0gPCBrZXlJZCkgewogICAgICAgICAgICBjb25zdCBuZXh0U2VsZkRlcml2ZUtleSA9IHsgY29ubmVjdGlvbklkLCBrZXlJZCwgZGVyaXZlS2V5IH07CiAgICAgICAgICAgIHNlbGZEZXJpdmVLZXlNYXAuc2V0KCJsYXRlc3QiLCBuZXh0U2VsZkRlcml2ZUtleSk7CiAgICAgICAgfQogICAgfQogICAgZWxzZSB7CiAgICAgICAgY29uc3QgbmV4dFNlbGZEZXJpdmVLZXkgPSB7IGNvbm5lY3Rpb25JZCwga2V5SWQsIGRlcml2ZUtleSB9OwogICAgICAgIHNlbGZEZXJpdmVLZXlNYXAuc2V0KCJsYXRlc3QiLCBuZXh0U2VsZkRlcml2ZUtleSk7CiAgICB9Cn0KZnVuY3Rpb24gc2lsZW5jZUZyYW1lKGVuY29kZWRGcmFtZSkgewogICAgLy8gY29ubmVjdGlvbi5jcmVhdGVkLCByZWNlaXZlTWVzc2FnZSDlj5fkv6HliY3jga7loLTlkIgKICAgIGlmIChlbmNvZGVkRnJhbWUudHlwZSA9PT0gdW5kZWZpbmVkKSB7CiAgICAgICAgLy8g6Z+z5aOw44Gv5pqX5Y+35YyW44Gv44GE44KL44Go6IGe44GR44Gf44KC44Gu44GY44KD44Gq44GE44Gu44Gn572u44GN5o+b44GI44KLCiAgICAgICAgY29uc3QgbmV3RGF0YSA9IG5ldyBBcnJheUJ1ZmZlcigzKTsKICAgICAgICBjb25zdCBuZXdVaW50OCA9IG5ldyBVaW50OEFycmF5KG5ld0RhdGEpOwogICAgICAgIC8vIE9wdXMg44K144Kk44Os44Oz44K544OV44Os44O844OgCiAgICAgICAgbmV3VWludDguc2V0KFsweGQ4LCAweGZmLCAweGZlXSk7CiAgICAgICAgZW5jb2RlZEZyYW1lLmRhdGEgPSBuZXdEYXRhOwogICAgfQogICAgZWxzZSB7CiAgICAgICAgLy8g5pig5YOP44GM5q2j5bi444GY44KD44Gq44GE44Gf44KBIFBMSSDjgrnjg4jjg7zjg6DjgYznmbrnlJ/jgZfjgabjgZfjgb7jgYYKICAgICAgICAvLyDjgZ3jga7jgZ/jgoEgMzIweDI0MCDjga7nnJ/jgaPpu5LjgarnlLvpnaLjgavnva7jgY3mj5vjgYjjgosKICAgICAgICBjb25zdCBuZXdEYXRhID0gbmV3IEFycmF5QnVmZmVyKDYwKTsKICAgICAgICBjb25zdCBuZXdVaW50OCA9IG5ldyBVaW50OEFycmF5KG5ld0RhdGEpOwogICAgICAgIC8vIHByZXR0aWVyLWlnbm9yZQogICAgICAgIG5ld1VpbnQ4LnNldChbMHhiMCwgMHgwNSwgMHgwMCwgMHg5ZCwgMHgwMSwgMHgyYSwgMHhhMCwgMHgwMCwgMHg1YSwgMHgwMCwKICAgICAgICAgICAgMHgzOSwgMHgwMywgMHgwMCwgMHgwMCwgMHgxYywgMHgyMiwgMHgxNiwgMHgxNiwgMHgyMiwgMHg2NiwKICAgICAgICAgICAgMHgxMiwgMHgyMCwgMHgwNCwgMHg5MCwgMHg0MCwgMHgwMCwgMHhjNSwgMHgwMSwgMHhlMCwgMHg3YywKICAgICAgICAgICAgMHg0ZCwgMHgyZiwgMHhmYSwgMHhkZCwgMHg0ZCwgMHhhNSwgMHg3ZiwgMHg4OSwgMHhhNSwgMHhmZiwKICAgICAgICAgICAgMHg1YiwgMHhhOSwgMHhiNCwgMHhhZiwgMHhmMSwgMHgzNCwgMHhiZiwgMHhlYiwgMHg3NSwgMHgzNiwKICAgICAgICAgICAgMHg5NSwgMHhmZSwgMHgyNiwgMHg5NiwgMHg2MCwgMHhmZSwgMHhmZiwgMHhiYSwgMHhmZiwgMHg0MCwKICAgICAgICBdKTsKICAgICAgICBlbmNvZGVkRnJhbWUuZGF0YSA9IG5ld0RhdGE7CiAgICB9CiAgICByZXR1cm4gZW5jb2RlZEZyYW1lOwp9CmZ1bmN0aW9uIHNldFdyaXRlSVYoY29ubmVjdGlvbklkLCBrZXlJZCwgd3JpdGVJVikgewogICAgY29uc3Qga2V5ID0gW2Nvbm5lY3Rpb25JZCwga2V5SWQudG9TdHJpbmcoKV0uam9pbigiOiIpOwogICAgd3JpdGVJVk1hcC5zZXQoa2V5LCB3cml0ZUlWKTsKfQpmdW5jdGlvbiBnZXRXcml0ZUlWKGNvbm5lY3Rpb25JZCwga2V5SWQpIHsKICAgIGNvbnN0IGtleSA9IFtjb25uZWN0aW9uSWQsIGtleUlkLnRvU3RyaW5nKCldLmpvaW4oIjoiKTsKICAgIHJldHVybiB3cml0ZUlWTWFwLmdldChrZXkpOwp9CmZ1bmN0aW9uIGdlbmVyYXRlSVYoY291bnQsIGNvbm5lY3Rpb25JZCwga2V5SWQpIHsKICAgIC8vIFRPRE86IGtleUlkIOOBjCBOdW1iZXIuTUFYX1NBRkVfSU5URUdFUiwgNyBieXRlIOOCkui2heOBiOOBpuOBhOOBn+WgtOWQiOOBr+OCqOODqeODvOOBi+S+i+WklgogICAgLy8gVE9ETzogY291bnQg44GMIE51bWJlci5NQVhfU0FGRV9JTlRFR0VSLCA3IGJ5dGUg44KS6LaF44GI44Gm44GE44Gf5aC05ZCI44Gv44Ko44Op44O844GL5L6L5aSWCiAgICAvLyAzMiBiaXQg44G+44GnCiAgICBpZiAobWF4S2V5SWQgPCBrZXlJZCB8fCBtYXhDb3VudCA8IGNvdW50KSB7CiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCJFWENFRURFRC1NQVhJTVVNLUJST0FEQ0FTVElORy1USU1FIik7CiAgICB9CiAgICBjb25zdCB3cml0ZUlWID0gZ2V0V3JpdGVJVihjb25uZWN0aW9uSWQsIGtleUlkKTsKICAgIGlmICghd3JpdGVJVikgewogICAgICAgIHRocm93IG5ldyBFcnJvcigiV1JJVEVJVi1OT1QtRk9VTkQiKTsKICAgIH0KICAgIGNvbnN0IHBhZGRpbmdMZW5ndGggPSBObiAtIFVpbnQzMkFycmF5LkJZVEVTX1BFUl9FTEVNRU5UOwogICAgY29uc3QgY291bnRXaXRoUGFkZGluZ0J1ZmZlciA9IG5ldyBBcnJheUJ1ZmZlcihObik7CiAgICBjb25zdCBjb3VudFdpdGhQYWRkaW5nRGF0YVZpZXcgPSBuZXcgRGF0YVZpZXcoY291bnRXaXRoUGFkZGluZ0J1ZmZlcik7CiAgICBjb3VudFdpdGhQYWRkaW5nRGF0YVZpZXcuc2V0VWludDMyKHBhZGRpbmdMZW5ndGgsIGNvdW50LCBiaWdFbmRpYW4pOwogICAgY29uc3QgaXYgPSBuZXcgVWludDhBcnJheShObik7CiAgICBjb25zdCBjb3VudFdpdGhQYWRkaW5nID0gbmV3IFVpbnQ4QXJyYXkoY291bnRXaXRoUGFkZGluZ0J1ZmZlcik7CiAgICBmb3IgKGxldCBpID0gMDsgaSA8IE5uOyBpKyspIHsKICAgICAgICBpdltpXSA9IHdyaXRlSVZbaV0gXiBjb3VudFdpdGhQYWRkaW5nW2ldOwogICAgfQogICAgcmV0dXJuIGl2Owp9CmZ1bmN0aW9uIHBhcnNlUGF5bG9hZChwYXlsb2FkVHlwZSwgcGF5bG9hZCkgewogICAgcmV0dXJuIFsKICAgICAgICBuZXcgVWludDhBcnJheShwYXlsb2FkLCAwLCB1bmVuY3J5cHRlZEJ5dGVzW3BheWxvYWRUeXBlXSksCiAgICAgICAgbmV3IFVpbnQ4QXJyYXkocGF5bG9hZCwgdW5lbmNyeXB0ZWRCeXRlc1twYXlsb2FkVHlwZV0pLAogICAgXTsKfQpmdW5jdGlvbiBlbmNvZGVGcmFtZUFkZChoZWFkZXIsIHNmcmFtZUhlYWRlciwgY29ubmVjdGlvbklkKSB7CiAgICBjb25zdCBjb25uZWN0aW9uSWREYXRhID0gdGV4dEVuY29kZXIuZW5jb2RlKGNvbm5lY3Rpb25JZCk7CiAgICBjb25zdCBmcmFtZUFkZCA9IG5ldyBVaW50OEFycmF5KGhlYWRlci5ieXRlTGVuZ3RoICsgc2ZyYW1lSGVhZGVyLmJ5dGVMZW5ndGggKyBjb25uZWN0aW9uSWREYXRhLmJ5dGVMZW5ndGgpOwogICAgZnJhbWVBZGQuc2V0KGhlYWRlciwgMCk7CiAgICBmcmFtZUFkZC5zZXQoc2ZyYW1lSGVhZGVyLCBoZWFkZXIuYnl0ZUxlbmd0aCk7CiAgICBmcmFtZUFkZC5zZXQoY29ubmVjdGlvbklkRGF0YSwgaGVhZGVyLmJ5dGVMZW5ndGggKyBzZnJhbWVIZWFkZXIuYnl0ZUxlbmd0aCk7CiAgICByZXR1cm4gZnJhbWVBZGQ7Cn0KYXN5bmMgZnVuY3Rpb24gZW5jcnlwdEZ1bmN0aW9uKGVuY29kZWRGcmFtZSwgY29udHJvbGxlcikgewogICAgY29uc3QgeyBjb25uZWN0aW9uSWQsIGtleUlkLCBkZXJpdmVLZXkgfSA9IGdldExhdGVzdFNlbGZEZXJpdmVLZXkoKTsKICAgIGlmICghZGVyaXZlS2V5KSB7CiAgICAgICAgcmV0dXJuOwogICAgfQogICAgY29uc3QgY3VycmVudENvdW50ID0gZ2V0Q291bnQoY29ubmVjdGlvbklkKTsKICAgIC8vIGNvdW50IOOBjCAzMiBiaXQg5Lul5LiK44Gu5aC05ZCI44Gv5YGc5q2i44GZ44KLCiAgICBpZiAoY3VycmVudENvdW50ID4gbWF4Q291bnQpIHsKICAgICAgICBwb3N0TWVzc2FnZSh7IHR5cGU6ICJkaXNjb25uZWN0IiB9KTsKICAgIH0KICAgIGNvbnN0IGl2ID0gZ2VuZXJhdGVJVihjdXJyZW50Q291bnQsIGNvbm5lY3Rpb25JZCwga2V5SWQpOwogICAgaWYgKCFpdikgewogICAgICAgIHJldHVybjsKICAgIH0KICAgIGNvbnN0IFtoZWFkZXIsIHBheWxvYWRdID0gcGFyc2VQYXlsb2FkKGVuY29kZWRGcmFtZS50eXBlLCBlbmNvZGVkRnJhbWUuZGF0YSk7CiAgICBjb25zdCBzZnJhbWVIZWFkZXIgPSBlbmNvZGVTRnJhbWVIZWFkZXIoMCwgY3VycmVudENvdW50LCBrZXlJZCk7CiAgICBjb25zdCBmcmFtZUFkZCA9IGVuY29kZUZyYW1lQWRkKGhlYWRlciwgc2ZyYW1lSGVhZGVyLCBjb25uZWN0aW9uSWQpOwogICAgY3J5cHRvLnN1YnRsZQogICAgICAgIC5lbmNyeXB0KHsKICAgICAgICBuYW1lOiAiQUVTLUdDTSIsCiAgICAgICAgaXY6IGl2LAogICAgICAgIC8vIOaal+WPt+WMluOBleOCjOOBpuOBhOOBquOBhOmDqOWIhgogICAgICAgIGFkZGl0aW9uYWxEYXRhOiBmcmFtZUFkZCwKICAgIH0sIGRlcml2ZUtleSwgcGF5bG9hZCkKICAgICAgICAudGhlbigoY2lwaGVyVGV4dCkgPT4gewogICAgICAgIGNvbnN0IG5ld0RhdGEgPSBuZXcgQXJyYXlCdWZmZXIoZnJhbWVBZGQuYnl0ZUxlbmd0aCArIGNpcGhlclRleHQuYnl0ZUxlbmd0aCk7CiAgICAgICAgY29uc3QgbmV3RGF0YVVpbnQ4ID0gbmV3IFVpbnQ4QXJyYXkobmV3RGF0YSk7CiAgICAgICAgbmV3RGF0YVVpbnQ4LnNldChmcmFtZUFkZCwgMCk7CiAgICAgICAgbmV3RGF0YVVpbnQ4LnNldChuZXcgVWludDhBcnJheShjaXBoZXJUZXh0KSwgZnJhbWVBZGQuYnl0ZUxlbmd0aCk7CiAgICAgICAgZW5jb2RlZEZyYW1lLmRhdGEgPSBuZXdEYXRhOwogICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZShlbmNvZGVkRnJhbWUpOwogICAgfSk7CiAgICBzZXRDb3VudChjb25uZWN0aW9uSWQsIGN1cnJlbnRDb3VudCArIDEpOwp9CmFzeW5jIGZ1bmN0aW9uIGRlY3J5cHRGdW5jdGlvbihlbmNvZGVkRnJhbWUsIGNvbnRyb2xsZXIpIHsKICAgIC8vIOepuuODleODrOODvOODoOWvvuW/nAogICAgaWYgKGVuY29kZWRGcmFtZS5kYXRhLmJ5dGVMZW5ndGggPCAxKSB7CiAgICAgICAgcmV0dXJuOwogICAgfQogICAgdHJ5IHsKICAgICAgICBjb25zdCBmcmFtZU1ldGFkYXRhQnVmZmVyID0gZW5jb2RlZEZyYW1lLmRhdGEuc2xpY2UoMCwgdW5lbmNyeXB0ZWRCeXRlc1tlbmNvZGVkRnJhbWUudHlwZV0pOwogICAgICAgIGNvbnN0IGZyYW1lTWV0YWRhdGEgPSBuZXcgVWludDhBcnJheShmcmFtZU1ldGFkYXRhQnVmZmVyKTsKICAgICAgICBjb25zdCBbc2ZyYW1lSGVhZGVyQnVmZmVyLCBjb25uZWN0aW9uSWRCdWZmZXIsIGVuY3J5cHRlZEZyYW1lQnVmZmVyXSA9IHNwbGl0SGVhZGVyKGVuY29kZWRGcmFtZS5kYXRhLnNsaWNlKHVuZW5jcnlwdGVkQnl0ZXNbZW5jb2RlZEZyYW1lLnR5cGVdKSk7CiAgICAgICAgY29uc3Qgc2ZyYW1lSGVhZGVyID0gbmV3IFVpbnQ4QXJyYXkoc2ZyYW1lSGVhZGVyQnVmZmVyKTsKICAgICAgICBjb25zdCBjb25uZWN0aW9uSWQgPSB0ZXh0RGVjb2Rlci5kZWNvZGUoY29ubmVjdGlvbklkQnVmZmVyKTsKICAgICAgICBjb25zdCBbcywgY291bnQsIGtleUlkXSA9IHBhcnNlU0ZyYW1lSGVhZGVyKHNmcmFtZUhlYWRlckJ1ZmZlcik7CiAgICAgICAgLy8g5LuK5Zue44GvIHMgZmxhZyDjga8gMCDjga7jgb8KICAgICAgICBpZiAocyAhPT0gMCkgewogICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoIlVORVhQRUNURUQtUy1GTEFHIik7CiAgICAgICAgfQogICAgICAgIGNvbnN0IGRlcml2ZUtleSA9IGdldFJlbW90ZURlcml2ZUtleShjb25uZWN0aW9uSWQsIGtleUlkKTsKICAgICAgICBpZiAoIWRlcml2ZUtleSkgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgIGNvbnN0IGl2ID0gZ2VuZXJhdGVJVihjb3VudCwgY29ubmVjdGlvbklkLCBrZXlJZCk7CiAgICAgICAgaWYgKCFpdikgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgIGNvbnN0IGZyYW1lQWRkID0gZW5jb2RlRnJhbWVBZGQoZnJhbWVNZXRhZGF0YSwgc2ZyYW1lSGVhZGVyLCBjb25uZWN0aW9uSWQpOwogICAgICAgIGNyeXB0by5zdWJ0bGUKICAgICAgICAgICAgLmRlY3J5cHQoewogICAgICAgICAgICBuYW1lOiAiQUVTLUdDTSIsCiAgICAgICAgICAgIGl2OiBpdiwKICAgICAgICAgICAgYWRkaXRpb25hbERhdGE6IGZyYW1lQWRkLAogICAgICAgIH0sIGRlcml2ZUtleSwgbmV3IFVpbnQ4QXJyYXkoZW5jcnlwdGVkRnJhbWVCdWZmZXIpKQogICAgICAgICAgICAudGhlbigocGxhaW5UZXh0KSA9PiB7CiAgICAgICAgICAgIGNvbnN0IG5ld0RhdGEgPSBuZXcgQXJyYXlCdWZmZXIoZnJhbWVNZXRhZGF0YUJ1ZmZlci5ieXRlTGVuZ3RoICsgcGxhaW5UZXh0LmJ5dGVMZW5ndGgpOwogICAgICAgICAgICBjb25zdCBuZXdVaW50OCA9IG5ldyBVaW50OEFycmF5KG5ld0RhdGEpOwogICAgICAgICAgICBuZXdVaW50OC5zZXQobmV3IFVpbnQ4QXJyYXkoZnJhbWVNZXRhZGF0YUJ1ZmZlciwgMCwgdW5lbmNyeXB0ZWRCeXRlc1tlbmNvZGVkRnJhbWUudHlwZV0pKTsKICAgICAgICAgICAgbmV3VWludDguc2V0KG5ldyBVaW50OEFycmF5KHBsYWluVGV4dCksIHVuZW5jcnlwdGVkQnl0ZXNbZW5jb2RlZEZyYW1lLnR5cGVdKTsKICAgICAgICAgICAgZW5jb2RlZEZyYW1lLmRhdGEgPSBuZXdEYXRhOwogICAgICAgICAgICBjb250cm9sbGVyLmVucXVldWUoZW5jb2RlZEZyYW1lKTsKICAgICAgICB9KTsKICAgIH0KICAgIGNhdGNoIChlKSB7CiAgICAgICAgLy8g5oOz5a6a5aSW44Gu44OR44Kx44OD44OI44OV44Kp44O844Oe44OD44OI44KS5Y+X5L+h44GX44Gf5aC05ZCICiAgICAgICAgY29udHJvbGxlci5lbnF1ZXVlKHNpbGVuY2VGcmFtZShlbmNvZGVkRnJhbWUpKTsKICAgIH0KfQovKiBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvdHJpcGxlLXNsYXNoLXJlZmVyZW5jZSAqLwovLy8gPHJlZmVyZW5jZSBwYXRoPSIuL2UyZWUudHMiLz4KLy8gbm9uY2Ug44K144Kk44K6CmNvbnN0IE5uID0gMTI7Ci8vIGtleSDjgrXjgqTjgroKY29uc3QgTmsgPSAxNjsKLy8ga2V5IOOCteOCpOOCuu+8iGJpdO+8iQpjb25zdCBrZXlMZW5ndGggPSBOayAqIDg7CmFzeW5jIGZ1bmN0aW9uIGdlbmVyYXRlRGVyaXZlS2V5KG1hdGVyaWFsKSB7CiAgICBjb25zdCBzYWx0ID0gdGV4dEVuY29kZXIuZW5jb2RlKCJTRnJhbWUxMCIpOwogICAgY29uc3QgaW5mbyA9IHRleHRFbmNvZGVyLmVuY29kZSgia2V5Iik7CiAgICBjb25zdCBkZXJpdmVLZXkgPSBhd2FpdCBjcnlwdG8uc3VidGxlLmRlcml2ZUtleSh7CiAgICAgICAgbmFtZTogIkhLREYiLAogICAgICAgIHNhbHQ6IHNhbHQsCiAgICAgICAgaGFzaDogIlNIQS0yNTYiLAogICAgICAgIGluZm86IGluZm8sCiAgICB9LCBtYXRlcmlhbCwgewogICAgICAgIG5hbWU6ICJBRVMtR0NNIiwKICAgICAgICBsZW5ndGg6IGtleUxlbmd0aCwKICAgIH0sIGZhbHNlLCBbImVuY3J5cHQiLCAiZGVjcnlwdCJdKTsKICAgIHJldHVybiBkZXJpdmVLZXk7Cn0KYXN5bmMgZnVuY3Rpb24gZ2VuZXJhdGVXcml0ZUlWKG1hdGVyaWFsKSB7CiAgICBjb25zdCBzYWx0ID0gdGV4dEVuY29kZXIuZW5jb2RlKCJTRnJhbWUxMCIpOwogICAgY29uc3QgaW5mbyA9IHRleHRFbmNvZGVyLmVuY29kZSgic2FsdCIpOwogICAgY29uc3Qgd3JpdGVJVkJ1ZmZlciA9IGF3YWl0IGNyeXB0by5zdWJ0bGUuZGVyaXZlQml0cyh7CiAgICAgICAgbmFtZTogIkhLREYiLAogICAgICAgIHNhbHQ6IHNhbHQsCiAgICAgICAgaGFzaDogIlNIQS0zODQiLAogICAgICAgIGluZm86IGluZm8sCiAgICB9LCBtYXRlcmlhbCwgCiAgICAvLyBJViDjga8gOTYg44OT44OD44OI44Gq44Gu44GnCiAgICBObiAqIDgpOwogICAgY29uc3Qgd3JpdGVJViA9IG5ldyBVaW50OEFycmF5KHdyaXRlSVZCdWZmZXIpOwogICAgcmV0dXJuIHdyaXRlSVY7Cn0KbGV0IHJlbW92YWxUaW1lb3V0SWQgPSAwOwpvbm1lc3NhZ2UgPSAoZXZlbnQpID0+IHsKICAgIGNvbnN0IHsgdHlwZSB9ID0gZXZlbnQuZGF0YTsKICAgIGlmICh0eXBlID09PSAic2VsZlNlY3JldEtleU1hdGVyaWFsIikgewogICAgICAgIGNvbnN0IHsgc2VsZlNlY3JldEtleU1hdGVyaWFsLCBzZWxmQ29ubmVjdGlvbklkLCBzZWxmS2V5SWQsIHdhaXRpbmdUaW1lIH0gPSBldmVudC5kYXRhOwogICAgICAgIGNvbnN0IHRpbWVvdXRJZCA9IHNldFRpbWVvdXQoKCkgPT4gewogICAgICAgICAgICBjcnlwdG8uc3VidGxlCiAgICAgICAgICAgICAgICAuaW1wb3J0S2V5KCJyYXciLCBzZWxmU2VjcmV0S2V5TWF0ZXJpYWwuYnVmZmVyLCAiSEtERiIsIGZhbHNlLCBbImRlcml2ZUJpdHMiLCAiZGVyaXZlS2V5Il0pCiAgICAgICAgICAgICAgICAudGhlbigobWF0ZXJpYWwpID0+IHsKICAgICAgICAgICAgICAgIGdlbmVyYXRlRGVyaXZlS2V5KG1hdGVyaWFsKS50aGVuKChkZXJpdmVLZXkpID0+IHsKICAgICAgICAgICAgICAgICAgICBzZXRTZWxmRGVyaXZlS2V5KHNlbGZDb25uZWN0aW9uSWQsIHNlbGZLZXlJZCwgZGVyaXZlS2V5KTsKICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgZ2VuZXJhdGVXcml0ZUlWKG1hdGVyaWFsKS50aGVuKCh3cml0ZUlWKSA9PiB7CiAgICAgICAgICAgICAgICAgICAgc2V0V3JpdGVJVihzZWxmQ29ubmVjdGlvbklkLCBzZWxmS2V5SWQsIHdyaXRlSVYpOwogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICBjbGVhclRpbWVvdXQodGltZW91dElkKTsKICAgICAgICAgICAgfSk7CiAgICAgICAgfSwgd2FpdGluZ1RpbWUgfHwgMCk7CiAgICAgICAgLy8gVE9ETzogKzEwMDAg44Gn6Y2155Sf5oiQ5b6M44Gr5a6f6KGM44GV44KM44KL44KI44GG44Gr44GX44Gm44GE44KL44GM55+t44GE5aC05ZCI44Gv5Ly444Gw44GZCiAgICAgICAgY29uc3QgcmVtb3ZhbFdhaXRpbmdUaW1lID0gKHdhaXRpbmdUaW1lIHx8IDApICsgMTAwMDsKICAgICAgICBpZiAocmVtb3ZhbFRpbWVvdXRJZCkgewogICAgICAgICAgICAvLyDli5XkvZzmuIjjgb/jgr/jgqTjg57jg7zmnInjgooKICAgICAgICAgICAgaWYgKHdhaXRpbmdUaW1lKSB7CiAgICAgICAgICAgICAgICAvLyBjb25uZWN0aW9uLmRlc3Ryb3llZAogICAgICAgICAgICAgICAgY2xlYXJUaW1lb3V0KHJlbW92YWxUaW1lb3V0SWQpOwogICAgICAgICAgICAgICAgcmVtb3ZhbFRpbWVvdXRJZCA9IHNldFRpbWVvdXQoKCkgPT4gewogICAgICAgICAgICAgICAgICAgIHJlbW92ZU9sZFJlbW90ZURlcml2ZUtleXMoKTsKICAgICAgICAgICAgICAgICAgICBjbGVhclRpbWVvdXQocmVtb3ZhbFRpbWVvdXRJZCk7CiAgICAgICAgICAgICAgICAgICAgcmVtb3ZhbFRpbWVvdXRJZCA9IDA7CiAgICAgICAgICAgICAgICB9LCByZW1vdmFsV2FpdGluZ1RpbWUpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGVsc2UgewogICAgICAgICAgICAvLyDli5XkvZzmuIjjgb/jgr/jgqTjg57jg7zjgarjgZcKICAgICAgICAgICAgLy8gY29ubmVjdGlvbi5jcmVhdGVkIOOBruWgtOWQiOOCguWwkeOBl+Wun+ihjOOCkumBheOCieOBm+OCiwogICAgICAgICAgICByZW1vdmFsVGltZW91dElkID0gc2V0VGltZW91dCgoKSA9PiB7CiAgICAgICAgICAgICAgICByZW1vdmVPbGRSZW1vdGVEZXJpdmVLZXlzKCk7CiAgICAgICAgICAgICAgICBjbGVhclRpbWVvdXQocmVtb3ZhbFRpbWVvdXRJZCk7CiAgICAgICAgICAgICAgICByZW1vdmFsVGltZW91dElkID0gMDsKICAgICAgICAgICAgfSwgcmVtb3ZhbFdhaXRpbmdUaW1lKTsKICAgICAgICB9CiAgICB9CiAgICBlbHNlIGlmICh0eXBlID09PSAicmVtb3RlU2VjcmV0S2V5TWF0ZXJpYWxzIikgewogICAgICAgIGNvbnN0IHsgcmVtb3RlU2VjcmV0S2V5TWF0ZXJpYWxzIH0gPSBldmVudC5kYXRhOwogICAgICAgIGZvciAoY29uc3QgW2Nvbm5lY3Rpb25JZCwgcmVtb3RlU2VjcmV0S2V5TWF0ZXJpYWxdIG9mIE9iamVjdC5lbnRyaWVzKHJlbW90ZVNlY3JldEtleU1hdGVyaWFscykpIHsKICAgICAgICAgICAgY29uc3QgeyBrZXlJZCwgc2VjcmV0S2V5TWF0ZXJpYWwgfSA9IHJlbW90ZVNlY3JldEtleU1hdGVyaWFsOwogICAgICAgICAgICBjcnlwdG8uc3VidGxlCiAgICAgICAgICAgICAgICAuaW1wb3J0S2V5KCJyYXciLCBzZWNyZXRLZXlNYXRlcmlhbC5idWZmZXIsICJIS0RGIiwgZmFsc2UsIFsiZGVyaXZlQml0cyIsICJkZXJpdmVLZXkiXSkKICAgICAgICAgICAgICAgIC50aGVuKChtYXRlcmlhbCkgPT4gewogICAgICAgICAgICAgICAgZ2VuZXJhdGVEZXJpdmVLZXkobWF0ZXJpYWwpLnRoZW4oKGRlcml2ZUtleSkgPT4gewogICAgICAgICAgICAgICAgICAgIHNldFJlbW90ZURlcml2ZUtleShjb25uZWN0aW9uSWQsIGtleUlkLCBkZXJpdmVLZXkpOwogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICBnZW5lcmF0ZVdyaXRlSVYobWF0ZXJpYWwpLnRoZW4oKHdyaXRlSVYpID0+IHsKICAgICAgICAgICAgICAgICAgICBzZXRXcml0ZUlWKGNvbm5lY3Rpb25JZCwga2V5SWQsIHdyaXRlSVYpOwogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICBzZXRMYXRlc3RSZW1vdGVLZXlJZChjb25uZWN0aW9uSWQsIGtleUlkKTsKICAgICAgICAgICAgfSk7CiAgICAgICAgfQogICAgfQogICAgZWxzZSBpZiAodHlwZSA9PT0gInJlbW92ZVJlbW90ZURlcml2ZUtleSIpIHsKICAgICAgICBjb25zdCB7IGNvbm5lY3Rpb25JZCB9ID0gZXZlbnQuZGF0YTsKICAgICAgICByZW1vdmVEZXJpdmVLZXkoY29ubmVjdGlvbklkKTsKICAgIH0KICAgIGVsc2UgaWYgKHR5cGUgPT09ICJlbmNyeXB0IikgewogICAgICAgIGNvbnN0IHsgcmVhZGFibGVTdHJlYW0sIHdyaXRhYmxlU3RyZWFtIH0gPSBldmVudC5kYXRhOwogICAgICAgIGNvbnN0IHRyYW5zZm9ybVN0cmVhbSA9IG5ldyBUcmFuc2Zvcm1TdHJlYW0oewogICAgICAgICAgICB0cmFuc2Zvcm06IGVuY3J5cHRGdW5jdGlvbiwKICAgICAgICB9KTsKICAgICAgICByZWFkYWJsZVN0cmVhbS5waXBlVGhyb3VnaCh0cmFuc2Zvcm1TdHJlYW0pLnBpcGVUbyh3cml0YWJsZVN0cmVhbSk7CiAgICB9CiAgICBlbHNlIGlmICh0eXBlID09PSAiZGVjcnlwdCIpIHsKICAgICAgICBjb25zdCB7IHJlYWRhYmxlU3RyZWFtLCB3cml0YWJsZVN0cmVhbSB9ID0gZXZlbnQuZGF0YTsKICAgICAgICBjb25zdCB0cmFuc2Zvcm1TdHJlYW0gPSBuZXcgVHJhbnNmb3JtU3RyZWFtKHsKICAgICAgICAgICAgdHJhbnNmb3JtOiBkZWNyeXB0RnVuY3Rpb24sCiAgICAgICAgfSk7CiAgICAgICAgcmVhZGFibGVTdHJlYW0ucGlwZVRocm91Z2godHJhbnNmb3JtU3RyZWFtKS5waXBlVG8od3JpdGFibGVTdHJlYW0pOwogICAgfQogICAgZWxzZSBpZiAodHlwZSA9PT0gImNsZWFyIikgewogICAgICAgIGNvdW50TWFwLmNsZWFyKCk7CiAgICAgICAgd3JpdGVJVk1hcC5jbGVhcigpOwogICAgICAgIHJlbW90ZURlcml2ZUtleU1hcC5jbGVhcigpOwogICAgICAgIGxhdGVzdFJlbW90ZUtleUlkTWFwLmNsZWFyKCk7CiAgICAgICAgc2VsZkRlcml2ZUtleU1hcC5jbGVhcigpOwogICAgfQp9Owo=");this.worker=new Worker(URL.createObjectURL(new Blob([e],{type:"application/javascript"}))),this.worker.onmessage=e=>{const{operation:n}=e.data;"disconnect"===n&&"function"==typeof this.onWorkerDisconnect&&this.onWorkerDisconnect()}}clearWorker(){this.worker&&this.worker.postMessage({type:"clear"})}terminateWorker(){this.worker&&this.worker.terminate()}async init(){const{preKeyBundle:e}=await window.e2ee.init();return e}setupSenderTransform(e){if(!e.track)return;const n=e.createEncodedStreams(),i=n.readableStream||n.readable,t=n.writableStream||n.writable;if(!this.worker)throw new Error("Worker is null. Call startWorker in advance.");this.worker.postMessage({type:"encrypt",readableStream:i,writableStream:t},[i,t])}setupReceiverTransform(e){const n=e.createEncodedStreams(),i=n.readableStream||n.readable,t=n.writableStream||n.writable;if(!this.worker)throw new Error("Worker is null. Call startWorker in advance.");this.worker.postMessage({type:"decrypt",readableStream:i,writableStream:t},[i,t])}postRemoteSecretKeyMaterials(e){if(!this.worker)throw new Error("Worker is null. Call startWorker in advance.");this.worker.postMessage({type:"remoteSecretKeyMaterials",remoteSecretKeyMaterials:e.remoteSecretKeyMaterials})}postRemoveRemoteDeriveKey(e){if(!this.worker)throw new Error("Worker is null. Call startWorker in advance.");this.worker.postMessage({type:"removeRemoteDeriveKey",connectionId:e})}postSelfSecretKeyMaterial(e,n,i,t=0){if(!this.worker)throw new Error("Worker is null. Call startWorker in advance.");this.worker.postMessage({type:"selfSecretKeyMaterial",selfConnectionId:e,selfKeyId:n,selfSecretKeyMaterial:i,waitingTime:t})}startSession(e,n){const[i,t]=window.e2ee.startSession(e,n.identityKey,n.signedPreKey,n.preKeySignature);if(t)throw t;return i}stopSession(e){const[n,i]=window.e2ee.stopSession(e);if(i)throw i;return n}receiveMessage(e){const[n,i]=window.e2ee.receiveMessage(e);if(i)throw i;return n}start(e){const[n,i]=window.e2ee.start(e);if(i)throw i;return n}addPreKeyBundle(e,n){const i=window.e2ee.addPreKeyBundle(e,n.identityKey,n.signedPreKey,n.preKeySignature);if(i)throw i}selfFingerprint(){return window.e2ee.selfFingerprint()}remoteFingerprints(){return window.e2ee.remoteFingerprints()}static async loadWasm(e){if(void 0===!window.e2ee)return void console.warn("E2ee wasm is already loaded. Will not be reload.");if(g(),!window.Go)throw new Error(`Failed to load module Go. window.Go is ${window.Go}.`);const n=new Go,{instance:i}=await WebAssembly.instantiateStreaming(fetch(e),n.importObject);if(n.run(i),!window.e2ee)throw new Error(`Failed to load module e2ee. window.e2ee is ${window.e2ee}.`)}static version(){return"2021.1.0"}static wasmVersion(){return window.e2ee.version()}}var V=Uint8Array,S=Uint16Array,G=Uint32Array,W=new V([0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0,0]),h=new V([0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,0,0]),y=new V([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]),k=function(e,n){for(var t=new S(31),a=0;31>a;++a)t[a]=n+=1<a;++a)for(var o=t[a];oN;++N)X=(43690&N)>>>1|(21845&N)<<1,X=(52428&X)>>>2|(13107&X)<<2,X=(61680&X)>>>4|(3855&X)<<4,Y[N]=((65280&X)>>>8|(255&X)<<8)>>>1;for(var E=function(e,n,t){for(var a=e.length,g=0,o=new S(n);g>>15-n]=c}else for(d=new S(a),g=0;g>>15-e[g]);return d},v=new V(288),N=0;144>N;++N)v[N]=8;for(var N=144;256>N;++N)v[N]=9;for(var N=256;280>N;++N)v[N]=7;for(var N=280;288>N;++N)v[N]=8;for(var O=new V(32),N=0;32>N;++N)O[N]=5;var K=E(v,9,0),L=E(v,9,1),F=E(O,5,0),J=E(O,5,1),U=function(e){for(var n=e[0],t=1;tn&&(n=e[t]);return n},Q=function(e,n,i){var t=0|n/8;return(e[t]|e[t+1]<<8)>>(7&n)&i},D=function(e,n){var i=0|n/8;return(e[i]|e[i+1]<<8|e[i+2]<<16)>>(7&n)},H=function(e){return(0|e/8)+(7&e&&1)},M=function(i,t,a){(null==t||0>t)&&(t=0),(null==a||a>i.length)&&(a=i.length);var g=new(i instanceof S?S:i instanceof G?G:V)(a-t);return g.set(i.subarray(t,a)),g},P=["unexpected EOF","invalid block type","invalid length/literal","invalid distance","stream finished","no stream handler",,"no callback","invalid UTF-8 data","extra field too long","date not in range 1980-2099","filename too long","stream finishing","invalid zip data"],j=function(n,i,t){var a=new Error(i||P[n]);if(a.code=n,Error.captureStackTrace&&Error.captureStackTrace(a,j),!t)throw a;return a},z=function(g,o,C){var I=g.length;if(!I||C&&!C.l&&5>I)return o||new V(0);var m=!o||C,A=!C||C.i;C||(C={}),o||(o=new V(3*I));var Z=function(e){var n=o.length;if(e>n){var i=new V(a(2*n,e));i.set(o),o=i}},u=C.f||0,p=C.p||0,S=C.b||0,G=C.l,k=C.d,w=C.m,R=C.n,X=8*I;do{if(!G){C.f=u=Q(g,p,1);var f=Q(g,p+1,3);if(p+=3,!f){var T=H(p)+4,Y=g[T-4]|g[T-3]<<8,l=T+Y;if(l>I){A&&j(0);break}m&&Z(S+Y),o.set(g.subarray(T,l),S),C.b=S+=Y,C.p=p=8*l;continue}else if(1==f)G=L,k=J,w=9,R=5;else if(2==f){var t=Q(g,p,31)+257,N=Q(g,p+10,15)+4,v=t+Q(g,p+5,31)+1;p+=14;for(var O=new V(v),K=new V(19),F=0;F>>4;if(16>T)O[F++]=T;else{var _=0,q=0;for(16==T?(q=3+Q(g,p,3),p+=2,_=O[F-1]):17==T?(q=3+Q(g,p,7),p+=3):18==T&&(q=11+Q(g,p,127),p+=7);q--;)O[F++]=_}}var $=O.subarray(0,t),ee=O.subarray(t);w=U($),R=U(ee),G=E($,w,1),k=E(ee,R,1)}else j(1);if(p>X){A&&j(0);break}}m&&Z(S+131072);for(var ne=(1<>>4;if(p+=15&_,p>X){A&&j(0);break}if(_||j(2),256>ae)o[S++]=ae;else if(256==ae){te=p,G=null;break}else{var ge=ae-254;if(264>>4;le||j(3),p+=15≤var ee=B[d];if(3X){A&&j(0);break}m&&Z(S+131072);for(var de=S+ge;S>>8},q=function(e,n,i){i<<=7&n;var t=0|n/8;e[t]|=i,e[t+1]|=i>>>8,e[t+2]|=i>>>16},$=function(e,n){for(var a=[],t=0;tA&&(A=o[t].s);var Z=new S(A+1),u=ee(a[I-1],Z,0);if(u>n){var t=0,b=0,p=u-n;for(o.sort(function(e,n){return Z[n.s]-Z[e.s]||e.f-n.f});tn)b+=(1<>>=p;0>>8,e[g+2]=255^e[g],e[g+3]=255^e[g+1];for(var o=0;oz;++z){x=P[z];for(var ee,f=0;f>>5),C+=x[f]>>>12)}}else Q=K,D=v,j=F,H=O;for(var f=0;f>>18;q(n,C,Q[ee+257]),C+=D[ee+257],7>>23),C+=W[ee]);var ae=31&a[f];q(n,C,j[ae]),C+=H[ae],3>>5),C+=h[ae])}else q(n,C,Q[a[f]]),C+=D[a[f]];return q(n,C,Q[256]),C+D[256]},ge=new G([65540,131080,131088,131104,262176,1048704,1048832,2114560,2117632]),oe=new V(0),le=function(a,g,c,C,I,r){var m=a.length,s=new V(C+m+5*(1+t(m/7e3))+I),o=s.subarray(C,s.length-I),A=0;if(!g||8>m)for(var Z,u=0;u<=m;u+=65535)Z=u+65535,ZQ;++Q)B[Q]=0;for(var Q=0;30>Q;++Q)Y[Q]=0}var D=2,x=0,P=8191&b,z=32767&F-J;if(2>>13,U)-1,q=n(32767,u),$=n(258,U);z<=q&&--P&&F!=J;){if(a[u+D]==a[u+D-z]){for(var ee=0;ee<$&&a[u+ee]==a[u+ee-z];++ee);if(ee>D){if(D=ee,x=z,ee>_)break;for(var ne=n(z,ee-2),ie=0,Q=0;Qie&&(ie=ce,J=le)}}}F=J,J=y[F],z+=32767&F-J+32768}if(x){f[v++]=268435456|R[D]<<18|T[x];var se=31&R[D],Ce=31&T[x];E+=W[se]+h[Ce],++B[257+se],++Y[Ce],O=u+D,++N}else f[v++]=a[u],++B[a[u]]}}A=ae(a,o,r,f,B,Y,E,v,K,u-K,A),!r&&7&A&&(A=te(o,A+1,oe))}return M(s,0,C+H(A)+I)},de=function(){var t=1,g=0;return{p:function(a){for(var o,d=t,c=g,s=a.length,l=0;l!=s;){for(o=n(l+2655,s);l>16),c=(65535&c)+15*(c>>16)}t=d,g=c},d:function(){return t%=65521,g%=65521,(255&t)<<24|t>>>8<<16|(255&g)<<8|g>>>8}}},ce=function(e,i,g,o,l){return le(e,null==i.level?6:i.level,null==i.mem?t(1.5*a(8,n(13,Math.log(e.length)))):12+i.mem,g,o,!l)},se=function(e,n,i){for(;i;++n)e[n]=i,i>>>=8},Ce=function(e,n){var i=n.level,t=0==i?0:6>i?1:9==i?3:2;e[0]=120,e[1]=t<<6|(t?32-2*t:1)},Ie=function(e){(8!=(15&e[0])||7>>4||(e[0]<<8|e[1])%31)&&j(6,"invalid zlib data"),32&e[1]&&j(6,"invalid zlib data: preset dictionaries not supported")},re="undefined"!=typeof TextDecoder&&new TextDecoder,me=0;try{re.decode(oe,{stream:!0}),me=1}catch(n){}class Ae extends Error{}class Ze{constructor(e,n,i,t,a,g){this.role=n,this.channelId=i,this.metadata=t,this.signalingUrl=e,this.options=a,this.connectionTimeout=6e4,"number"==typeof this.options.timeout&&(console.warn("@deprecated timeout option will be removed in a future version. Use connectionTimeout."),this.connectionTimeout=this.options.timeout),"number"==typeof this.options.connectionTimeout&&(this.connectionTimeout=this.options.connectionTimeout),this.disconnectWaitTimeout=3e3,"number"==typeof this.options.disconnectWaitTimeout&&(this.disconnectWaitTimeout=this.options.disconnectWaitTimeout),this.constraints=null,this.debug=g,this.clientId=null,this.connectionId=null,this.remoteConnectionIds=[],this.stream=null,this.ws=null,this.pc=null,this.encodings=[],this.callbacks={disconnect:()=>{},push:()=>{},addstream:()=>{},track:()=>{},removestream:()=>{},removetrack:()=>{},notify:()=>{},log:()=>{},timeout:()=>{},timeline:()=>{},signaling:()=>{}},this.authMetadata=null,this.e2ee=null,this.connectionTimeoutTimerId=0,this.monitorSignalingWebSocketEventTimerId=0,this.monitorIceConnectionStateChangeTimerId=0,this.dataChannels={},this.mids={audio:"",video:""},this.signalingSwitched=!1,this.dataChannelsCompress={}}on(e,n){"addstream"===e?console.warn("@deprecated addstream callback will be removed in a future version. Use track callback."):"removestream"==e&&console.warn("@deprecated removestream callback will be removed in a future version. Use removetrack callback."),e in this.callbacks&&(this.callbacks[e]=n)}stopAudioTrack(e){for(const n of e.getAudioTracks())n.enabled=!1;return new Promise(n=>{setTimeout(async()=>{for(const n of e.getAudioTracks())if(n.stop(),e.removeTrack(n),null!==this.pc){const e=this.pc.getSenders().find(e=>e.track&&e.track.id===n.id);e&&(await e.replaceTrack(null))}n()},100)})}stopVideoTrack(e){for(const n of e.getVideoTracks())n.enabled=!1;return new Promise(n=>{setTimeout(async()=>{for(const n of e.getVideoTracks())if(n.stop(),e.removeTrack(n),null!==this.pc){const e=this.pc.getSenders().find(e=>e.track&&e.track.id===n.id);e&&(await e.replaceTrack(null))}n()},100)})}async replaceAudioTrack(e,n){await this.stopAudioTrack(e);const i=this.getAudioTransceiver();if(null===i)throw new Error("Unable to set an audio track. Audio track sender is undefined");e.addTrack(n),await i.sender.replaceTrack(n)}async replaceVideoTrack(e,n){await this.stopVideoTrack(e);const i=this.getVideoTransceiver();if(null===i)throw new Error("Unable to set video track. Video track sender is undefined");e.addTrack(n),await i.sender.replaceTrack(n)}stopStream(){return new Promise(e=>(this.debug&&console.warn("@deprecated closing MediaStream in disconnect will be removed in a future version. Close every track in the MediaStream by yourself."),!this.stream)?e():(this.stream.getTracks().forEach(e=>{e.stop()}),this.stream=null,e()))}async signalingTerminate(){await this.stopStream();for(const e of Object.keys(this.dataChannels)){const n=this.dataChannels[e];n&&n.close(),delete this.dataChannels[e]}this.ws&&(this.ws.close(),this.ws=null),this.pc&&this.pc.close(),this.e2ee&&this.e2ee.terminateWorker(),this.initializeConnection()}async abendPeerConnectionState(e){this.clearMonitorIceConnectionStateChange(),await this.stopStream(),this.pc&&(this.pc.ondatachannel=null,this.pc.oniceconnectionstatechange=null,this.pc.onicegatheringstatechange=null,this.pc.onconnectionstatechange=null),this.ws&&(this.ws.onclose=e=>{this.writeWebSocketTimelineLog("onclose",{code:e.code,reason:e.reason})},this.ws.onmessage=null,this.ws.onerror=null);for(const n of Object.keys(this.dataChannels)){const e=this.dataChannels[n];e&&(e.onclose=e=>{const n=e.currentTarget;this.writeDataChannelTimelineLog("onclose",n),this.trace("CLOSE DATA CHANNEL",n.label)},e.onmessage=null,e.onerror=null)}for(const n of Object.keys(this.dataChannels)){const e=this.dataChannels[n];e&&e.close(),delete this.dataChannels[n]}this.ws&&(this.ws.close(),this.ws=null),this.pc&&this.pc.close(),this.e2ee&&this.e2ee.terminateWorker(),this.initializeConnection();const n=this.soraCloseEvent("abend",e);this.callbacks.disconnect(n),this.writeSoraTimelineLog("disconnect-abend",n)}async abend(e,n){this.clearMonitorIceConnectionStateChange(),await this.stopStream(),this.pc&&(this.pc.ondatachannel=null,this.pc.oniceconnectionstatechange=null,this.pc.onicegatheringstatechange=null,this.pc.onconnectionstatechange=null),this.ws&&(this.ws.onclose=e=>{this.writeWebSocketTimelineLog("onclose",{code:e.code,reason:e.reason})},this.ws.onmessage=null,this.ws.onerror=null);for(const i of Object.keys(this.dataChannels)){const e=this.dataChannels[i];e&&(e.onclose=e=>{const n=e.currentTarget;this.writeDataChannelTimelineLog("onclose",n),this.trace("CLOSE DATA CHANNEL",n.label)},e.onmessage=null,e.onerror=null)}if(this.dataChannels.signaling){const n={type:"disconnect",reason:e};if(!0===this.dataChannelsCompress.signaling){const e=new TextEncoder().encode(JSON.stringify(n)),i=o(e,{});if("open"===this.dataChannels.signaling.readyState)try{this.dataChannels.signaling.send(i),this.writeDataChannelSignalingLog("send-disconnect",this.dataChannels.signaling,n)}catch(n){const e=n.message;this.writeDataChannelSignalingLog("failed-to-send-disconnect",this.dataChannels.signaling,e)}}else if("open"===this.dataChannels.signaling.readyState)try{this.dataChannels.signaling.send(JSON.stringify(n)),this.writeDataChannelSignalingLog("send-disconnect",this.dataChannels.signaling,n)}catch(n){const e=n.message;this.writeDataChannelSignalingLog("failed-to-send-disconnect",this.dataChannels.signaling,e)}}for(const i of Object.keys(this.dataChannels)){const e=this.dataChannels[i];e&&(e.onerror=null,e.close()),delete this.dataChannels[i]}if(await this.disconnectWebSocket(e),await this.disconnectPeerConnection(),this.e2ee&&this.e2ee.terminateWorker(),this.initializeConnection(),"WEBSOCKET-ONCLOSE"===e&&n&&(1e3===n.code||1005===n.code)){const e=this.soraCloseEvent("normal","DISCONNECT",n);return this.writeSoraTimelineLog("disconnect-normal",e),void this.callbacks.disconnect(e)}const i=this.soraCloseEvent("abend",e,n);this.writeSoraTimelineLog("disconnect-abend",i),this.callbacks.disconnect(this.soraCloseEvent("abend",e,n))}initializeConnection(){this.clientId=null,this.connectionId=null,this.remoteConnectionIds=[],this.stream=null,this.ws=null,this.pc=null,this.encodings=[],this.authMetadata=null,this.e2ee=null,this.dataChannels={},this.mids={audio:"",video:""},this.signalingSwitched=!1,this.clearConnectionTimeout()}disconnectWebSocket(e){let n=0;return this.signalingSwitched?(this.ws&&(this.ws.close(),this.ws=null),Promise.resolve(null)):new Promise(i=>{if(!this.ws)return i(null);if(this.ws.onclose=e=>(this.ws&&(this.ws.close(),this.ws=null),clearTimeout(n),this.writeWebSocketTimelineLog("onclose",{code:e.code,reason:e.reason}),i({code:e.code,reason:e.reason})),1===this.ws.readyState){const t={type:"disconnect",reason:e};this.ws.send(JSON.stringify(t)),this.writeWebSocketSignalingLog("send-disconnect",t),n=setTimeout(()=>{this.ws&&(this.ws.close(),this.ws=null),i(null)},this.disconnectWaitTimeout)}else return this.ws.close(),this.ws=null,i(null)})}disconnectDataChannel(){const e=()=>{for(const e of Object.keys(this.dataChannels)){const n=this.dataChannels[e];n&&(n.onerror=null,n.close()),delete this.dataChannels[e]}};return new Promise((n,i)=>{if(!this.dataChannels.signaling)return e(),n({code:4999,reason:""});const t=setTimeout(()=>(e(),i()),this.disconnectWaitTimeout),a=[];for(const g of Object.keys(this.dataChannels)){const i=this.dataChannels[g];if(i){i.onerror=()=>(clearTimeout(t),e(),n({code:4999,reason:""}));a.push((()=>new Promise(e=>{let n=0;const t=setInterval(()=>{n++,"closed"===i.readyState&&(clearInterval(t),e()),this.disconnectWaitTimeout<100*n&&(e(),clearInterval(t))},100)}))())}}Promise.all(a).then(()=>{0===Object.keys(this.dataChannels).length?n(null):n({code:4999,reason:""})}).finally(()=>{e(),clearTimeout(t)});const g={type:"disconnect",reason:"NO-ERROR"};if(!0===this.dataChannelsCompress.signaling){const e=new TextEncoder().encode(JSON.stringify(g)),n=o(e,{});if("open"===this.dataChannels.signaling.readyState)try{this.dataChannels.signaling.send(n),this.writeDataChannelSignalingLog("send-disconnect",this.dataChannels.signaling,g)}catch(n){const e=n.message;this.writeDataChannelSignalingLog("failed-to-send-disconnect",this.dataChannels.signaling,e)}}else if("open"===this.dataChannels.signaling.readyState)try{this.dataChannels.signaling.send(JSON.stringify(g)),this.writeDataChannelSignalingLog("send-disconnect",this.dataChannels.signaling,g)}catch(n){const e=n.message;this.writeDataChannelSignalingLog("failed-to-send-disconnect",this.dataChannels.signaling,e)}})}disconnectPeerConnection(){return new Promise(e=>(this.pc&&"closed"!==this.pc.connectionState&&this.pc.close(),e()))}async disconnect(){this.clearMonitorIceConnectionStateChange(),await this.stopStream(),this.pc&&(this.pc.ondatachannel=null,this.pc.oniceconnectionstatechange=null,this.pc.onicegatheringstatechange=null,this.pc.onconnectionstatechange=null),this.ws&&(this.ws.onclose=e=>{this.writeWebSocketTimelineLog("onclose",{code:e.code,reason:e.reason})},this.ws.onmessage=null,this.ws.onerror=null);for(const e of Object.keys(this.dataChannels)){const n=this.dataChannels[e];n&&(n.onmessage=null)}let e=null;if(this.signalingSwitched){try{const n=await this.disconnectDataChannel();null!==n&&(e=this.soraCloseEvent("normal","DISCONNECT",n))}catch(n){e=this.soraCloseEvent("abend","DISCONNECT-TIMEOUT")}await this.disconnectWebSocket("NO-ERROR"),await this.disconnectPeerConnection()}else{const n=await this.disconnectWebSocket("NO-ERROR");await this.disconnectPeerConnection(),null!==n&&(e=this.soraCloseEvent("normal","DISCONNECT",n))}this.e2ee&&this.e2ee.terminateWorker(),this.initializeConnection(),e&&("abend"===e.type?this.writeSoraTimelineLog("disconnect-abend",e):"normal"===e.type&&this.writeSoraTimelineLog("disconnect-normal",e),this.callbacks.disconnect(e))}setupE2EE(){!0===this.options.e2ee&&(this.e2ee=new p,this.e2ee.onWorkerDisconnect=async()=>{await this.abend("INTERNAL-ERROR",{reason:"CRASH-E2EE-WORKER"})},this.e2ee.startWorker())}startE2EE(){if(!0===this.options.e2ee&&this.e2ee){if(!this.connectionId){const e=new Error;throw e.message=`E2EE failed. Self connectionId is null`,e}this.e2ee.clearWorker();const e=this.e2ee.start(this.connectionId);this.e2ee.postSelfSecretKeyMaterial(this.connectionId,e.selfKeyId,e.selfSecretKeyMaterial)}}signaling(e){return this.trace("CREATE OFFER",e),new Promise((n,i)=>{null===this.ws&&(this.ws=new WebSocket(this.signalingUrl),this.writeWebSocketSignalingLog("new-websocket",this.signalingUrl)),this.ws.binaryType="arraybuffer",this.ws.onclose=async e=>{const n=new Ae(`Signaling failed. CloseEventCode:${e.code} CloseEventReason:'${e.reason}'`);n.code=e.code,n.reason=e.reason,this.writeWebSocketTimelineLog("onclose",n),await this.signalingTerminate(),i(n)},this.ws.onopen=async()=>{this.writeWebSocketSignalingLog("onopen");let n;try{n=C(e.sdp||"",this.role,this.channelId,this.metadata,this.options)}catch(e){return void i(e)}if(n.e2ee&&this.e2ee){const e=await this.e2ee.init();n.signaling_notify_metadata.pre_key_bundle=e}this.trace("SIGNALING CONNECT MESSAGE",n),this.ws&&(this.ws.send(JSON.stringify(n)),this.writeWebSocketSignalingLog(`send-${n.type}`,n))},this.ws.onmessage=async e=>{if(e.data instanceof ArrayBuffer)return this.writeWebSocketSignalingLog("onmessage-e2ee",e.data),void this.signalingOnMessageE2EE(e.data);const i=JSON.parse(e.data);"offer"==i.type?(this.writeWebSocketSignalingLog("onmessage-offer",i),this.signalingOnMessageTypeOffer(i),n(i)):"update"==i.type?(this.writeWebSocketSignalingLog("onmessage-update",i),await this.signalingOnMessageTypeUpdate(i)):"re-offer"==i.type?(this.writeWebSocketSignalingLog("onmessage-re-offer",i),await this.signalingOnMessageTypeReOffer(i)):"ping"==i.type?await this.signalingOnMessageTypePing(i):"push"==i.type?this.callbacks.push(i,"websocket"):"notify"==i.type?("connection.created"===i.event_type?this.writeWebSocketTimelineLog("notify-connection.created",i):"connection.destroyed"===i.event_type&&this.writeWebSocketTimelineLog("notify-connection.destroyed",i),this.signalingOnMessageTypeNotify(i,"websocket")):"switched"==i.type&&(this.writeWebSocketSignalingLog("onmessage-switched",i),this.signalingOnMessageTypeSwitched(i))}})}async createOffer(){const e=new window.RTCPeerConnection({iceServers:[]});if(s()){e.addTransceiver("video",{direction:"recvonly"}),e.addTransceiver("audio",{direction:"recvonly"});const n=await e.createOffer();return e.close(),this.writePeerConnectionTimelineLog("create-offer",n),n}const n=await e.createOffer({offerToReceiveAudio:!0,offerToReceiveVideo:!0});return e.close(),this.writePeerConnectionTimelineLog("create-offer",n),n}async connectPeerConnection(e){let n=Object.assign({},e.config);if(this.e2ee&&(n=Object.assign({encodedInsertableStreams:!0},n)),void 0!==window.RTCPeerConnection.generateCertificate){const e=await window.RTCPeerConnection.generateCertificate({name:"ECDSA",namedCurve:"P-256"});n=Object.assign({certificates:[e]},n)}return this.trace("PEER CONNECTION CONFIG",n),this.writePeerConnectionTimelineLog("new-peerconnection",n),this.pc=new window.RTCPeerConnection(n,this.constraints),this.pc.oniceconnectionstatechange=()=>{this.pc&&(this.writePeerConnectionTimelineLog("oniceconnectionstatechange",{connectionState:this.pc.connectionState,iceConnectionState:this.pc.iceConnectionState,iceGatheringState:this.pc.iceGatheringState}),this.trace("ONICECONNECTIONSTATECHANGE ICECONNECTIONSTATE",this.pc.iceConnectionState))},this.pc.onicegatheringstatechange=()=>{this.pc&&this.writePeerConnectionTimelineLog("onicegatheringstatechange",{connectionState:this.pc.connectionState,iceConnectionState:this.pc.iceConnectionState,iceGatheringState:this.pc.iceGatheringState})},this.pc.onconnectionstatechange=()=>{this.pc&&this.writePeerConnectionTimelineLog("onconnectionstatechange",{connectionState:this.pc.connectionState,iceConnectionState:this.pc.iceConnectionState,iceGatheringState:this.pc.iceGatheringState})},void(this.pc.ondatachannel=e=>{this.onDataChannel(e)})}async setRemoteDescription(e){if(this.pc){const n=new RTCSessionDescription({type:"offer",sdp:e.sdp});return await this.pc.setRemoteDescription(n),void this.writePeerConnectionTimelineLog("set-remote-description",n)}}async createAnswer(e){if(this.pc){for(const e of Object.values(this.mids)){const n=this.pc.getTransceivers().find(n=>n.mid===e);n&&"recvonly"===n.direction&&(n.direction="sendrecv")}if(this.options.simulcast&&("sendrecv"===this.role||"sendonly"===this.role)){const n=this.pc.getTransceivers().find(e=>{if(e.mid&&0<=e.mid.indexOf("video")&&null!==e.sender.track&&(null===e.currentDirection||"sendonly"===e.currentDirection))return e});if(n){await this.setSenderParameters(n,this.encodings),await this.setRemoteDescription(e),this.trace("TRANSCEIVER SENDER GET_PARAMETERS",n.sender.getParameters()),await this.setSenderParameters(n,this.encodings);const i=await this.pc.createAnswer();return await this.pc.setLocalDescription(i),void this.trace("TRANSCEIVER SENDER GET_PARAMETERS",n.sender.getParameters())}}const n=await this.pc.createAnswer();return this.writePeerConnectionTimelineLog("create-answer",n),await this.pc.setLocalDescription(n),void this.writePeerConnectionTimelineLog("set-local-description",n)}}sendAnswer(){if(this.pc&&this.ws&&this.pc.localDescription){this.trace("ANSWER SDP",this.pc.localDescription.sdp);const e={type:"answer",sdp:this.pc.localDescription.sdp};this.ws.send(JSON.stringify(e)),this.writeWebSocketSignalingLog("send-answer",e)}}onIceCandidate(){return new Promise(e=>{this.pc&&(this.pc.oniceconnectionstatechange=()=>{this.pc&&(this.writePeerConnectionTimelineLog("oniceconnectionstatechange",{connectionState:this.pc.connectionState,iceConnectionState:this.pc.iceConnectionState,iceGatheringState:this.pc.iceGatheringState}),this.trace("ONICECONNECTIONSTATECHANGE ICECONNECTIONSTATE",this.pc.iceConnectionState),"connected"===this.pc.iceConnectionState&&e())},this.pc.onicecandidate=n=>{if(this.writePeerConnectionTimelineLog("onicecandidate",n.candidate),this.pc&&this.trace("ONICECANDIDATE ICEGATHERINGSTATE",this.pc.iceGatheringState),null===n.candidate)e();else{const e=n.candidate.toJSON(),i=Object.assign(e,{type:"candidate"});this.trace("ONICECANDIDATE CANDIDATE MESSAGE",i),this.sendMessage(i)}})})}waitChangeConnectionStateConnected(){return new Promise((e,n)=>{if(this.pc&&void 0===this.pc.connectionState)return void e();const i=setInterval(()=>{if(!this.pc){const e=new Error;e.message="PeerConnection connectionState did not change to 'connected'",clearInterval(i),n(e)}else this.pc&&"connected"===this.pc.connectionState&&(clearInterval(i),e())},10)})}monitorSignalingWebSocketEvent(){return new Promise((e,n)=>{this.monitorSignalingWebSocketEventTimerId=setInterval(()=>{this.ws&&(this.clearMonitorSignalingWebSocketEvent(),this.ws.onclose=async e=>{const i=new Ae(`Signaling failed. CloseEventCode:${e.code} CloseEventReason:'${e.reason}'`);i.code=e.code,i.reason=e.reason,this.writeWebSocketTimelineLog("onclose",i),await this.signalingTerminate(),n(i)},this.ws.onerror=async()=>{const e=new Ae(`Signaling failed. WebSocket onerror was called`);this.writeWebSocketSignalingLog("onerror",e),await this.signalingTerminate(),n(e)})},100)})}monitorWebSocketEvent(){this.ws&&(this.ws.onclose=async e=>{this.writeWebSocketTimelineLog("onclose",{code:e.code,reason:e.reason}),await this.abend("WEBSOCKET-ONCLOSE",{code:e.code,reason:e.reason})},this.ws.onerror=async()=>{this.writeWebSocketSignalingLog("onerror"),await this.abend("WEBSOCKET-ONERROR")})}monitorPeerConnectionState(){this.pc&&(this.pc.oniceconnectionstatechange=async()=>{this.pc&&this.pc.connectionState===void 0&&(this.writePeerConnectionTimelineLog("oniceconnectionstatechange",{connectionState:this.pc.connectionState,iceConnectionState:this.pc.iceConnectionState,iceGatheringState:this.pc.iceGatheringState}),this.trace("ONICECONNECTIONSTATECHANGE ICECONNECTIONSTATE",this.pc.iceConnectionState),clearTimeout(this.monitorIceConnectionStateChangeTimerId),"failed"===this.pc.iceConnectionState?await this.abendPeerConnectionState("ICE-CONNECTION-STATE-FAILED"):"disconnected"===this.pc.iceConnectionState&&(this.monitorIceConnectionStateChangeTimerId=setTimeout(async()=>{this.pc&&"disconnected"===this.pc.iceConnectionState&&(await this.abendPeerConnectionState("ICE-CONNECTION-STATE-DISCONNECTED-TIMEOUT"))},1e4)))},this.pc.onconnectionstatechange=async()=>{this.pc&&(this.writePeerConnectionTimelineLog("onconnectionstatechange",{connectionState:this.pc.connectionState,iceConnectionState:this.pc.iceConnectionState,iceGatheringState:this.pc.iceGatheringState}),"failed"===this.pc.connectionState&&(await this.abendPeerConnectionState("CONNECTION-STATE-FAILED")))})}setConnectionTimeout(){return new Promise((e,n)=>{0{if(!this.pc||this.pc&&this.pc.connectionState!==void 0&&"connected"!==this.pc.connectionState){const e=new Error;e.message="Signaling connection timeout",this.callbacks.timeout(),this.trace("DISCONNECT","Signaling connection timeout"),this.writePeerConnectionTimelineLog("signaling-connection-timeout",{connectionTimeout:this.connectionTimeout}),await this.signalingTerminate(),n(e)}},this.connectionTimeout))})}clearConnectionTimeout(){clearTimeout(this.connectionTimeoutTimerId)}clearMonitorSignalingWebSocketEvent(){clearInterval(this.monitorSignalingWebSocketEventTimerId)}clearMonitorIceConnectionStateChange(){clearInterval(this.monitorIceConnectionStateChangeTimerId)}trace(e,n){this.callbacks.log(e,n);this.debug&&A(this.clientId,e,n)}writeWebSocketSignalingLog(e,n){this.callbacks.signaling(Z(e,n,"websocket")),this.writeWebSocketTimelineLog(e,n)}writeDataChannelSignalingLog(e,n,i){this.callbacks.signaling(Z(e,i,"datachannel")),this.writeDataChannelTimelineLog(e,n,i)}writeWebSocketTimelineLog(e,n){const i=b(e,n,"websocket");this.callbacks.timeline(i)}writeDataChannelTimelineLog(e,n,i){const t=b(e,i,"datachannel",n.id,n.label);this.callbacks.timeline(t)}writePeerConnectionTimelineLog(e,n){const i=b(e,n,"peerconnection");this.callbacks.timeline(i)}writeSoraTimelineLog(e,n){const i=b(e,n,"sora");this.callbacks.timeline(i)}signalingOnMessageE2EE(e){if(this.e2ee){const n=new Uint8Array(e),i=this.e2ee.receiveMessage(n);this.e2ee.postRemoteSecretKeyMaterials(i),i.messages.forEach(e=>{this.sendE2EEMessage(e.buffer)})}}signalingOnMessageTypeOffer(e){if(this.clientId=e.client_id,this.connectionId=e.connection_id,void 0!==e.metadata&&(this.authMetadata=e.metadata),Array.isArray(e.encodings)&&(this.encodings=e.encodings),void 0!==e.mid&&void 0!==e.mid.audio&&(this.mids.audio=e.mid.audio),void 0!==e.mid&&void 0!==e.mid.video&&(this.mids.video=e.mid.video),e.data_channels)for(const n of e.data_channels)this.dataChannelsCompress[n.label]=n.compress;this.trace("SIGNALING OFFER MESSAGE",e),this.trace("OFFER SDP",e.sdp)}sendUpdateAnswer(){this.pc&&this.ws&&this.pc.localDescription&&(this.trace("ANSWER SDP",this.pc.localDescription.sdp),this.sendMessage({type:"update",sdp:this.pc.localDescription.sdp}))}sendReAnswer(){this.pc&&this.pc.localDescription&&(this.trace("RE ANSWER SDP",this.pc.localDescription.sdp),this.sendMessage({type:"re-answer",sdp:this.pc.localDescription.sdp}))}async signalingOnMessageTypeUpdate(e){this.trace("SIGNALING UPDATE MESSGE",e),this.trace("UPDATE SDP",e.sdp),await this.setRemoteDescription(e),await this.createAnswer(e),this.sendUpdateAnswer()}async signalingOnMessageTypeReOffer(e){this.trace("SIGNALING RE OFFER MESSGE",e),this.trace("RE OFFER SDP",e.sdp),await this.setRemoteDescription(e),await this.createAnswer(e),this.sendReAnswer()}async signalingOnMessageTypePing(e){const n={type:"pong"};if(e.stats){const e=await this.getStats();n.stats=e}this.ws&&this.ws.send(JSON.stringify(n))}signalingOnMessageTypeNotify(e,n){if("connection.created"===e.event_type){const n=e.connection_id;if(this.connectionId!==n){const i=I(e),t=m(i);if(t&&this.e2ee&&n){const e=this.e2ee.startSession(n,t);this.e2ee.postRemoteSecretKeyMaterials(e),e.messages.forEach(e=>{this.sendE2EEMessage(e.buffer)}),this.e2ee.postSelfSecretKeyMaterial(e.selfConnectionId,e.selfKeyId,e.selfSecretKeyMaterial)}}const i=r(e);i.forEach(e=>{const n=I(e),i=m(n),t=e.connection_id;t&&this.e2ee&&i&&this.e2ee.addPreKeyBundle(t,i)})}else if("connection.destroyed"===e.event_type){const n=I(e),i=m(n),t=e.connection_id;if(i&&this.e2ee&&t){const e=this.e2ee.stopSession(t);this.e2ee.postSelfSecretKeyMaterial(e.selfConnectionId,e.selfKeyId,e.selfSecretKeyMaterial,5e3),e.messages.forEach(e=>{this.sendE2EEMessage(e.buffer)}),this.e2ee.postRemoveRemoteDeriveKey(t)}}this.callbacks.notify(e,n)}signalingOnMessageTypeSwitched(e){this.signalingSwitched=!0;!this.ws||e.ignore_disconnect_websocket&&(this.ws&&(this.ws.onclose=null,this.ws.close(),this.ws=null),this.writeWebSocketSignalingLog("close"))}async setSenderParameters(e,n){const i=e.sender.getParameters();return i.encodings=n,await e.sender.setParameters(i),this.trace("TRANSCEIVER SENDER SET_PARAMETERS",i),void this.writePeerConnectionTimelineLog("transceiver-sender-set-parameters",i)}async getStats(){const e=[];if(!this.pc)return e;const n=await this.pc.getStats();return n.forEach(n=>{e.push(n)}),e}onDataChannel(e){const n=e.channel;this.writeDataChannelTimelineLog("ondatachannel",n,u(n)),e.channel.onbufferedamountlow=e=>{const n=e.currentTarget;this.writeDataChannelTimelineLog("onbufferedamountlow",n)},e.channel.onopen=e=>{const n=e.currentTarget;n.bufferedAmountLowThreshold=65536,n.binaryType="arraybuffer",this.dataChannels[n.label]=n,this.trace("OPEN DATA CHANNEL",n.label),"signaling"===n.label&&this.ws?this.writeDataChannelSignalingLog("onopen",n):this.writeDataChannelTimelineLog("onopen",n)},e.channel.onclose=async e=>{const n=e.currentTarget;this.writeDataChannelTimelineLog("onclose",n),this.trace("CLOSE DATA CHANNEL",n.label),await this.disconnect()},e.channel.onerror=async e=>{const n=e.currentTarget;this.writeDataChannelTimelineLog("onerror",n),this.trace("ERROR DATA CHANNEL",n.label),await this.abend("DATA-CHANNEL-ONERROR",{params:{label:n.label}})},"signaling"===e.channel.label?e.channel.onmessage=async e=>{const n=e.currentTarget;let i=e.data;if(!0===this.dataChannelsCompress.signaling){const n=l(new Uint8Array(e.data));i=new TextDecoder().decode(n)}const t=JSON.parse(i);this.writeDataChannelSignalingLog(`onmessage-${t.type}`,n,t),"re-offer"===t.type&&(await this.signalingOnMessageTypeReOffer(t))}:"notify"===e.channel.label?e.channel.onmessage=e=>{const n=e.currentTarget;let i=e.data;if(!0===this.dataChannelsCompress.notify){const n=l(new Uint8Array(e.data));i=new TextDecoder().decode(n)}const t=JSON.parse(i);"connection.created"===t.event_type?this.writeDataChannelTimelineLog("notify-connection.created",n,t):"connection.destroyed"===t.event_type&&this.writeDataChannelTimelineLog("notify-connection.destroyed",n,t),this.signalingOnMessageTypeNotify(t,"datachannel")}:"push"===e.channel.label?e.channel.onmessage=e=>{let n=e.data;if(!0===this.dataChannelsCompress.push){const i=l(new Uint8Array(e.data));n=new TextDecoder().decode(i)}const i=JSON.parse(n);this.callbacks.push(i,"datachannel")}:"e2ee"===e.channel.label?e.channel.onmessage=e=>{const n=e.currentTarget,i=e.data;this.signalingOnMessageE2EE(i),this.writeDataChannelSignalingLog("onmessage-e2ee",n,i)}:"stats"===e.channel.label&&(e.channel.onmessage=async e=>{let n=e.data;if(!0===this.dataChannelsCompress.stats){const i=l(new Uint8Array(e.data));n=new TextDecoder().decode(i)}const i=JSON.parse(n);if("req-stats"===i.type){const e=await this.getStats();this.sendStatsMessage(e)}})}sendMessage(e){if(this.dataChannels.signaling){if(!0===this.dataChannelsCompress.signaling){const n=new TextEncoder().encode(JSON.stringify(e)),i=o(n,{});this.dataChannels.signaling.send(i)}else this.dataChannels.signaling.send(JSON.stringify(e));this.writeDataChannelSignalingLog(`send-${e.type}`,this.dataChannels.signaling,e)}else null!==this.ws&&(this.ws.send(JSON.stringify(e)),this.writeWebSocketSignalingLog(`send-${e.type}`,e))}sendE2EEMessage(e){this.dataChannels.e2ee?(this.dataChannels.e2ee.send(e),this.writeDataChannelSignalingLog("send-e2ee",this.dataChannels.e2ee,e)):null!==this.ws&&(this.ws.send(e),this.writeWebSocketSignalingLog("send-e2ee",e))}sendStatsMessage(e){if(this.dataChannels.stats){const n={type:"stats",reports:e};if(!0===this.dataChannelsCompress.stats){const e=new TextEncoder().encode(JSON.stringify(n)),i=o(e,{});this.dataChannels.stats.send(i)}else this.dataChannels.stats.send(JSON.stringify(n))}}getAudioTransceiver(){if(this.pc&&this.mids.audio){const e=this.pc.getTransceivers().find(e=>e.mid===this.mids.audio);return e||null}return null}getVideoTransceiver(){if(this.pc&&this.mids.video){const e=this.pc.getTransceivers().find(e=>e.mid===this.mids.video);return e||null}return null}soraCloseEvent(e,n,i){const t=class extends Event{constructor(e,n,i){super(e),i&&(i.code&&(this.code=i.code),i.reason&&(this.reason=i.reason),i.params&&(this.params=i.params)),this.title=n}};return new t(e,n,i)}get e2eeSelfFingerprint(){return this.options.e2ee&&this.e2ee?this.e2ee.selfFingerprint():void 0}get e2eeRemoteFingerprints(){return this.options.e2ee&&this.e2ee?this.e2ee.remoteFingerprints():void 0}get audio(){return null!==this.getAudioTransceiver()}get video(){return null!==this.getVideoTransceiver()}}class ue extends Ze{async connect(e){return this.options.multistream?await Promise.race([this.multiStream(e).finally(()=>{this.clearConnectionTimeout(),this.clearMonitorSignalingWebSocketEvent()}),this.setConnectionTimeout(),this.monitorSignalingWebSocketEvent()]):await Promise.race([this.singleStream(e).finally(()=>{this.clearConnectionTimeout(),this.clearMonitorSignalingWebSocketEvent()}),this.setConnectionTimeout(),this.monitorSignalingWebSocketEvent()]),this.monitorWebSocketEvent(),this.monitorPeerConnectionState(),e}async singleStream(e){await this.disconnect(),this.setupE2EE();const n=await this.createOffer(),i=await this.signaling(n);return this.startE2EE(),await this.connectPeerConnection(i),await this.setRemoteDescription(i),e.getTracks().forEach(n=>{this.pc&&this.pc.addTrack(n,e)}),this.stream=e,await this.createAnswer(i),this.sendAnswer(),this.pc&&this.e2ee&&this.pc.getSenders().forEach(e=>{this.e2ee&&this.e2ee.setupSenderTransform(e)}),await this.onIceCandidate(),await this.waitChangeConnectionStateConnected(),e}async multiStream(e){await this.disconnect(),this.setupE2EE();const n=await this.createOffer(),i=await this.signaling(n);return this.startE2EE(),await this.connectPeerConnection(i),this.pc&&(this.pc.ontrack=e=>{const n=e.streams[0];if(n){const i={"stream.id":n.id,id:e.track.id,label:e.track.label,enabled:e.track.enabled,kind:e.track.kind,muted:e.track.muted,readyState:e.track.readyState};(this.writePeerConnectionTimelineLog("ontrack",i),"default"!==n.id)&&n.id!==this.connectionId&&(this.e2ee&&this.e2ee.setupReceiverTransform(e.receiver),this.callbacks.track(e),n.onremovetrack=e=>{if(this.callbacks.removetrack(e),e.target){const n=this.remoteConnectionIds.indexOf(e.target.id);-1{this.pc&&this.pc.addTrack(n,e)}),this.stream=e,await this.createAnswer(i),this.sendAnswer(),this.pc&&this.e2ee&&this.pc.getSenders().forEach(e=>{this.e2ee&&this.e2ee.setupSenderTransform(e)}),await this.onIceCandidate(),await this.waitChangeConnectionStateConnected(),e}}class be extends Ze{async connect(){if(this.options.multistream)return await Promise.race([this.multiStream().finally(()=>{this.clearConnectionTimeout(),this.clearMonitorSignalingWebSocketEvent()}),this.setConnectionTimeout(),this.monitorSignalingWebSocketEvent()]),this.monitorWebSocketEvent(),void this.monitorPeerConnectionState();else{const e=await Promise.race([this.singleStream().finally(()=>{this.clearConnectionTimeout(),this.clearMonitorSignalingWebSocketEvent()}),this.setConnectionTimeout(),this.monitorSignalingWebSocketEvent()]);return this.monitorWebSocketEvent(),this.monitorPeerConnectionState(),e}}async singleStream(){await this.disconnect(),this.setupE2EE();const e=await this.createOffer(),n=await this.signaling(e);return this.startE2EE(),await this.connectPeerConnection(n),this.pc&&(this.pc.ontrack=e=>{this.stream=e.streams[0];const n=this.stream.id;if("default"!==n){const i={"stream.id":n,id:e.track.id,label:e.track.label,enabled:e.track.enabled,kind:e.track.kind,muted:e.track.muted,readyState:e.track.readyState};this.writePeerConnectionTimelineLog("ontrack",i),this.e2ee&&this.e2ee.setupReceiverTransform(e.receiver),this.callbacks.track(e),this.stream.onremovetrack=e=>{if(this.callbacks.removetrack(e),e.target){const n=this.remoteConnectionIds.indexOf(e.target.id);-1{const n=e.streams[0];if("default"!==n.id&&n.id!==this.connectionId){const i={"stream.id":n.id,id:e.track.id,label:e.track.label,enabled:e.track.enabled,kind:e.track.kind,muted:e.track.muted,readyState:e.track.readyState};this.writePeerConnectionTimelineLog("ontrack",i),this.e2ee&&this.e2ee.setupReceiverTransform(e.receiver),this.callbacks.track(e),n.onremovetrack=e=>{if(this.callbacks.removetrack(e),e.target){const n=this.remoteConnectionIds.indexOf(e.target.id);-1