@webex/plugin-meetings 3.0.0 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (138) hide show
  1. package/dist/breakouts/breakout.js +1 -1
  2. package/dist/breakouts/index.js +1 -1
  3. package/dist/config.d.ts +1 -0
  4. package/dist/config.js +2 -1
  5. package/dist/config.js.map +1 -1
  6. package/dist/constants.d.ts +5 -4
  7. package/dist/constants.js +8 -4
  8. package/dist/constants.js.map +1 -1
  9. package/dist/index.d.ts +1 -1
  10. package/dist/index.js +6 -0
  11. package/dist/index.js.map +1 -1
  12. package/dist/interpretation/index.js +16 -2
  13. package/dist/interpretation/index.js.map +1 -1
  14. package/dist/interpretation/siLanguage.js +1 -1
  15. package/dist/locus-info/mediaSharesUtils.js +15 -1
  16. package/dist/locus-info/mediaSharesUtils.js.map +1 -1
  17. package/dist/locus-info/selfUtils.js +5 -0
  18. package/dist/locus-info/selfUtils.js.map +1 -1
  19. package/dist/media/MediaConnectionAwaiter.d.ts +61 -0
  20. package/dist/media/MediaConnectionAwaiter.js +163 -0
  21. package/dist/media/MediaConnectionAwaiter.js.map +1 -0
  22. package/dist/media/index.js +4 -1
  23. package/dist/media/index.js.map +1 -1
  24. package/dist/media/properties.js +4 -24
  25. package/dist/media/properties.js.map +1 -1
  26. package/dist/meeting/index.d.ts +26 -7
  27. package/dist/meeting/index.js +893 -677
  28. package/dist/meeting/index.js.map +1 -1
  29. package/dist/meeting/muteState.d.ts +2 -8
  30. package/dist/meeting/muteState.js +37 -25
  31. package/dist/meeting/muteState.js.map +1 -1
  32. package/dist/meeting/request.d.ts +3 -0
  33. package/dist/meeting/request.js +32 -23
  34. package/dist/meeting/request.js.map +1 -1
  35. package/dist/meeting/util.js +1 -0
  36. package/dist/meeting/util.js.map +1 -1
  37. package/dist/meeting-info/utilv2.js +4 -1
  38. package/dist/meeting-info/utilv2.js.map +1 -1
  39. package/dist/meetings/index.d.ts +8 -0
  40. package/dist/meetings/index.js +20 -0
  41. package/dist/meetings/index.js.map +1 -1
  42. package/dist/multistream/mediaRequestManager.d.ts +2 -1
  43. package/dist/multistream/mediaRequestManager.js +1 -1
  44. package/dist/multistream/mediaRequestManager.js.map +1 -1
  45. package/dist/multistream/remoteMediaGroup.d.ts +2 -0
  46. package/dist/multistream/remoteMediaGroup.js +16 -2
  47. package/dist/multistream/remoteMediaGroup.js.map +1 -1
  48. package/dist/multistream/remoteMediaManager.d.ts +15 -0
  49. package/dist/multistream/remoteMediaManager.js +179 -65
  50. package/dist/multistream/remoteMediaManager.js.map +1 -1
  51. package/dist/multistream/sendSlotManager.d.ts +9 -1
  52. package/dist/multistream/sendSlotManager.js +22 -0
  53. package/dist/multistream/sendSlotManager.js.map +1 -1
  54. package/dist/reachability/clusterReachability.d.ts +1 -0
  55. package/dist/reachability/clusterReachability.js +29 -15
  56. package/dist/reachability/clusterReachability.js.map +1 -1
  57. package/dist/reachability/index.d.ts +4 -0
  58. package/dist/reachability/index.js +18 -2
  59. package/dist/reachability/index.js.map +1 -1
  60. package/dist/reachability/request.js +12 -10
  61. package/dist/reachability/request.js.map +1 -1
  62. package/dist/reachability/util.d.ts +7 -0
  63. package/dist/reachability/util.js +19 -0
  64. package/dist/reachability/util.js.map +1 -1
  65. package/dist/reconnection-manager/index.js +2 -1
  66. package/dist/reconnection-manager/index.js.map +1 -1
  67. package/dist/roap/index.d.ts +10 -2
  68. package/dist/roap/index.js +15 -0
  69. package/dist/roap/index.js.map +1 -1
  70. package/dist/roap/request.js +3 -3
  71. package/dist/roap/request.js.map +1 -1
  72. package/dist/roap/turnDiscovery.d.ts +64 -17
  73. package/dist/roap/turnDiscovery.js +307 -126
  74. package/dist/roap/turnDiscovery.js.map +1 -1
  75. package/dist/statsAnalyzer/index.js +53 -30
  76. package/dist/statsAnalyzer/index.js.map +1 -1
  77. package/dist/webinar/index.js +1 -1
  78. package/package.json +22 -22
  79. package/src/config.ts +1 -0
  80. package/src/constants.ts +7 -3
  81. package/src/index.ts +1 -0
  82. package/src/interpretation/index.ts +18 -1
  83. package/src/locus-info/mediaSharesUtils.ts +16 -0
  84. package/src/locus-info/selfUtils.ts +5 -0
  85. package/src/media/MediaConnectionAwaiter.ts +174 -0
  86. package/src/media/index.ts +3 -1
  87. package/src/media/properties.ts +6 -31
  88. package/src/meeting/index.ts +321 -106
  89. package/src/meeting/muteState.ts +34 -20
  90. package/src/meeting/request.ts +18 -2
  91. package/src/meeting/util.ts +1 -0
  92. package/src/meeting-info/utilv2.ts +2 -1
  93. package/src/meetings/index.ts +18 -0
  94. package/src/multistream/mediaRequestManager.ts +4 -1
  95. package/src/multistream/remoteMediaGroup.ts +19 -0
  96. package/src/multistream/remoteMediaManager.ts +101 -16
  97. package/src/multistream/sendSlotManager.ts +28 -0
  98. package/src/reachability/clusterReachability.ts +20 -5
  99. package/src/reachability/index.ts +24 -1
  100. package/src/reachability/request.ts +15 -11
  101. package/src/reachability/util.ts +21 -0
  102. package/src/reconnection-manager/index.ts +1 -1
  103. package/src/roap/index.ts +25 -3
  104. package/src/roap/request.ts +3 -3
  105. package/src/roap/turnDiscovery.ts +244 -78
  106. package/src/statsAnalyzer/index.ts +63 -27
  107. package/test/integration/spec/journey.js +14 -14
  108. package/test/integration/spec/space-meeting.js +1 -1
  109. package/test/unit/spec/interpretation/index.ts +39 -3
  110. package/test/unit/spec/locus-info/index.js +28 -19
  111. package/test/unit/spec/locus-info/mediaSharesUtils.ts +9 -0
  112. package/test/unit/spec/locus-info/selfUtils.js +42 -12
  113. package/test/unit/spec/media/MediaConnectionAwaiter.ts +344 -0
  114. package/test/unit/spec/media/index.ts +89 -78
  115. package/test/unit/spec/media/properties.ts +16 -70
  116. package/test/unit/spec/meeting/index.js +638 -139
  117. package/test/unit/spec/meeting/muteState.js +219 -67
  118. package/test/unit/spec/meeting/request.js +21 -0
  119. package/test/unit/spec/meeting/utils.js +6 -1
  120. package/test/unit/spec/meeting-info/utilv2.js +6 -0
  121. package/test/unit/spec/meetings/index.js +40 -20
  122. package/test/unit/spec/multistream/mediaRequestManager.ts +20 -2
  123. package/test/unit/spec/multistream/remoteMediaGroup.ts +79 -1
  124. package/test/unit/spec/multistream/remoteMediaManager.ts +199 -1
  125. package/test/unit/spec/multistream/sendSlotManager.ts +50 -18
  126. package/test/unit/spec/reachability/clusterReachability.ts +86 -22
  127. package/test/unit/spec/reachability/index.ts +197 -60
  128. package/test/unit/spec/reachability/request.js +15 -7
  129. package/test/unit/spec/reachability/util.ts +32 -2
  130. package/test/unit/spec/reconnection-manager/index.js +28 -0
  131. package/test/unit/spec/roap/index.ts +61 -6
  132. package/test/unit/spec/roap/turnDiscovery.ts +298 -16
  133. package/test/unit/spec/stats-analyzer/index.js +179 -0
  134. package/dist/member/member.types.d.ts +0 -11
  135. package/dist/member/member.types.js +0 -17
  136. package/dist/member/member.types.js.map +0 -1
  137. package/src/member/member.types.ts +0 -13
  138. /package/test/unit/spec/locus-info/{lib/selfConstant.js → selfConstant.js} +0 -0
@@ -1 +1 @@
1
- {"version":3,"names":["_common","require","_metrics","_interopRequireDefault","_constants","_loggerProxy","_constants2","_util","TURN_DISCOVERY_TIMEOUT","TURN_DISCOVERY_SEQ","TurnDiscovery","exports","default","roapRequest","_classCallCheck2","_defineProperty2","turnInfo","url","username","password","_createClass2","key","value","waitForTurnDiscoveryResponse","defer","LoggerProxy","logger","warn","_promise","reject","Error","responseTimer","setTimeout","concat","info","promise","handleTurnDiscoveryResponse","roapMessage","from","_this","headers","messageType","ROAP","ROAP_TYPES","TURN_DISCOVERY_RESPONSE","_stringify","expectedHeaders","headerName","field","foundHeaders","forEach","receivedHeader","expectedHeader","startsWith","substring","length","clearTimeout","undefined","resolve","isOkRequired","includes","_handleTurnDiscoveryResponseInHttpResponse","_asyncToGenerator2","_regenerator","mark","_callee","wrap","_callee$","_context","prev","next","abrupt","stop","handleTurnDiscoveryResponseInHttpResponse","_x","apply","arguments","sendRoapTurnDiscoveryRequest","meeting","isReconnecting","Defer","TURN_DISCOVERY_REQUEST","version","ROAP_VERSION","seq","sendRoap","locusSelfUrl","selfUrl","mediaId","meetingId","id","locusMediaRequest","ipVersion","MeetingUtil","getIpVersion","webex","then","response","mediaConnections","turnDiscoveryResponse","_mediaConnections$","updateMediaConnections","remoteSdp","JSON","parse","_remoteSdp$roapMessag","errorType","errorCause","Metrics","sendBehavioralMetric","BEHAVIORAL_METRICS","ROAP_HTTP_RESPONSE_MISSING","correlationId","isMultistream","sendRoapOK","OK","_getSkipReason","_callee2","isAnyPublicClusterReachable","_callee2$","_context2","meetings","reachability","sent","getSkipReason","_x2","_isSkipped","_callee3","skipReason","_callee3$","_context3","isSkipped","_x3","_doTurnDiscovery","_callee4","isForced","turnDiscoverySkippedReason","httpResponse","_ref","_callee4$","_context4","turnServerInfo","t0","TURN_DISCOVERY_REQUIRES_OK","correlation_id","locus_id","locusUrl","split","pop","t1","TURN_DISCOVERY_FAILURE","reason","message","stack","doTurnDiscovery","_x4","_x5","_x6"],"sources":["turnDiscovery.ts"],"sourcesContent":["// @ts-ignore - Types not available for @webex/common\nimport {Defer} from '@webex/common';\n\nimport Metrics from '../metrics';\nimport BEHAVIORAL_METRICS from '../metrics/constants';\nimport LoggerProxy from '../common/logs/logger-proxy';\nimport {ROAP} from '../constants';\n\nimport RoapRequest from './request';\nimport Meeting from '../meeting';\nimport MeetingUtil from '../meeting/util';\n\nconst TURN_DISCOVERY_TIMEOUT = 10; // in seconds\n\n// Roap spec says that seq should start from 1, but TURN discovery works fine with seq=0\n// and this is handy for us, because TURN discovery is always done before the first SDP exchange,\n// so we can do it with seq=0 or not do it at all and then we create the RoapMediaConnection\n// and do the SDP offer with seq=1\nconst TURN_DISCOVERY_SEQ = 0;\n\n/**\n * Handles the process of finding out TURN server information from Linus.\n * This is achieved by sending a TURN_DISCOVERY_REQUEST.\n */\nexport default class TurnDiscovery {\n private roapRequest: RoapRequest;\n\n private defer?: Defer; // used for waiting for the response\n\n private turnInfo: {\n url: string;\n username: string;\n password: string;\n };\n\n private responseTimer?: ReturnType<typeof setTimeout>;\n\n /**\n * Constructor\n *\n * @param {RoapRequest} roapRequest\n */\n constructor(roapRequest: RoapRequest) {\n this.roapRequest = roapRequest;\n this.turnInfo = {\n url: '',\n username: '',\n password: '',\n };\n }\n\n /**\n * waits for TURN_DISCOVERY_RESPONSE message to arrive\n *\n * @returns {Promise}\n * @private\n * @memberof Roap\n */\n private waitForTurnDiscoveryResponse(): Promise<{isOkRequired: boolean}> {\n if (!this.defer) {\n LoggerProxy.logger.warn(\n 'Roap:turnDiscovery#waitForTurnDiscoveryResponse --> TURN discovery is not in progress'\n );\n\n return Promise.reject(\n new Error('waitForTurnDiscoveryResponse() called before sendRoapTurnDiscoveryRequest()')\n );\n }\n\n const {defer} = this;\n\n this.responseTimer = setTimeout(() => {\n LoggerProxy.logger.warn(\n `Roap:turnDiscovery#waitForTurnDiscoveryResponse --> timeout! no response arrived within ${TURN_DISCOVERY_TIMEOUT} seconds`\n );\n\n defer.reject(new Error('Timed out waiting for TURN_DISCOVERY_RESPONSE'));\n }, TURN_DISCOVERY_TIMEOUT * 1000);\n\n LoggerProxy.logger.info(\n 'Roap:turnDiscovery#waitForTurnDiscoveryResponse --> waiting for TURN_DISCOVERY_RESPONSE...'\n );\n\n return defer.promise;\n }\n\n /**\n * handles TURN_DISCOVERY_RESPONSE roap message\n *\n * @param {Object} roapMessage\n * @param {string} from string to indicate how we got the response (used just for logging)\n * @returns {void}\n * @public\n * @memberof Roap\n */\n public handleTurnDiscoveryResponse(roapMessage: any, from: string) {\n const {headers} = roapMessage;\n\n if (!this.defer) {\n LoggerProxy.logger.warn(\n `Roap:turnDiscovery#handleTurnDiscoveryResponse --> unexpected TURN discovery response ${from}`\n );\n\n return;\n }\n\n if (roapMessage.messageType !== ROAP.ROAP_TYPES.TURN_DISCOVERY_RESPONSE) {\n this.defer.reject(\n new Error(\n `TURN_DISCOVERY_RESPONSE ${from} has unexpected messageType: ${JSON.stringify(\n roapMessage\n )}`\n )\n );\n }\n\n const expectedHeaders = [\n {headerName: 'x-cisco-turn-url', field: 'url'},\n {headerName: 'x-cisco-turn-username', field: 'username'},\n {headerName: 'x-cisco-turn-password', field: 'password'},\n ];\n\n let foundHeaders = 0;\n\n headers?.forEach((receivedHeader) => {\n // check if it matches any of our expected headers\n expectedHeaders.forEach((expectedHeader) => {\n if (receivedHeader.startsWith(`${expectedHeader.headerName}=`)) {\n this.turnInfo[expectedHeader.field] = receivedHeader.substring(\n expectedHeader.headerName.length + 1\n );\n foundHeaders += 1;\n }\n });\n });\n\n clearTimeout(this.responseTimer);\n this.responseTimer = undefined;\n\n if (foundHeaders !== expectedHeaders.length) {\n LoggerProxy.logger.warn(\n `Roap:turnDiscovery#handleTurnDiscoveryResponse --> missing some headers, received ${from}: ${JSON.stringify(\n headers\n )}`\n );\n this.defer.reject(\n new Error(\n `TURN_DISCOVERY_RESPONSE ${from} missing some headers: ${JSON.stringify(headers)}`\n )\n );\n } else {\n LoggerProxy.logger.info(\n `Roap:turnDiscovery#handleTurnDiscoveryResponse --> received a valid response ${from}, url=${this.turnInfo.url}`\n );\n\n this.defer.resolve({isOkRequired: !headers?.includes('noOkInTransaction')});\n }\n }\n\n /**\n * handles TURN_DISCOVERY_RESPONSE roap message that came in http response\n *\n * @param {Object} roapMessage\n * @returns {Promise}\n * @memberof Roap\n */\n private async handleTurnDiscoveryResponseInHttpResponse(\n roapMessage: object\n ): Promise<{isOkRequired: boolean}> {\n this.handleTurnDiscoveryResponse(roapMessage, 'in http response');\n\n return this.defer.promise;\n }\n\n /**\n * sends the TURN_DISCOVERY_REQUEST roap request\n *\n * @param {Meeting} meeting\n * @param {Boolean} isReconnecting\n * @returns {Promise}\n * @private\n * @memberof Roap\n */\n sendRoapTurnDiscoveryRequest(meeting: Meeting, isReconnecting: boolean) {\n if (this.defer) {\n LoggerProxy.logger.warn(\n 'Roap:turnDiscovery#sendRoapTurnDiscoveryRequest --> already in progress'\n );\n\n return Promise.resolve();\n }\n\n this.defer = new Defer();\n\n const roapMessage = {\n messageType: ROAP.ROAP_TYPES.TURN_DISCOVERY_REQUEST,\n version: ROAP.ROAP_VERSION,\n seq: TURN_DISCOVERY_SEQ,\n headers: ['includeAnswerInHttpResponse', 'noOkInTransaction'],\n };\n\n LoggerProxy.logger.info(\n 'Roap:turnDiscovery#sendRoapTurnDiscoveryRequest --> sending TURN_DISCOVERY_REQUEST'\n );\n\n return this.roapRequest\n .sendRoap({\n roapMessage,\n // @ts-ignore - Fix missing type\n locusSelfUrl: meeting.selfUrl,\n // @ts-ignore - Fix missing type\n mediaId: isReconnecting ? '' : meeting.mediaId,\n meetingId: meeting.id,\n locusMediaRequest: meeting.locusMediaRequest,\n // @ts-ignore - because of meeting.webex\n ipVersion: MeetingUtil.getIpVersion(meeting.webex),\n })\n .then((response) => {\n const {mediaConnections} = response;\n\n let turnDiscoveryResponse;\n\n if (mediaConnections) {\n meeting.updateMediaConnections(mediaConnections);\n\n if (mediaConnections[0]?.remoteSdp) {\n const remoteSdp = JSON.parse(mediaConnections[0].remoteSdp);\n\n if (remoteSdp.roapMessage) {\n // yes, it's misleading that remoteSdp actually contains a TURN discovery response, but that's how the backend works...\n const {seq, messageType, errorType, errorCause, headers} = remoteSdp.roapMessage;\n\n turnDiscoveryResponse = {\n seq,\n messageType,\n errorType,\n errorCause,\n headers,\n };\n }\n }\n }\n\n if (!turnDiscoveryResponse) {\n Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.ROAP_HTTP_RESPONSE_MISSING, {\n correlationId: meeting.correlationId,\n messageType: 'TURN_DISCOVERY_RESPONSE',\n isMultistream: meeting.isMultistream,\n });\n }\n\n return turnDiscoveryResponse;\n });\n }\n\n /**\n * Sends the OK message that server expects to receive\n * after it sends us TURN_DISCOVERY_RESPONSE\n *\n * @param {Meeting} meeting\n * @returns {Promise}\n */\n sendRoapOK(meeting: Meeting) {\n LoggerProxy.logger.info('Roap:turnDiscovery#sendRoapOK --> sending OK');\n\n return this.roapRequest.sendRoap({\n roapMessage: {\n messageType: ROAP.ROAP_TYPES.OK,\n version: ROAP.ROAP_VERSION,\n seq: TURN_DISCOVERY_SEQ,\n },\n // @ts-ignore - fix type\n locusSelfUrl: meeting.selfUrl,\n // @ts-ignore - fix type\n mediaId: meeting.mediaId,\n meetingId: meeting.id,\n locusMediaRequest: meeting.locusMediaRequest,\n });\n }\n\n /**\n * Gets the reason why reachability is skipped.\n *\n * @param {Meeting} meeting\n * @returns {Promise<string>} Promise with empty string if reachability is not skipped or a reason if it is skipped\n */\n private async getSkipReason(meeting: Meeting): Promise<string> {\n const isAnyPublicClusterReachable =\n // @ts-ignore - fix type\n await meeting.webex.meetings.reachability.isAnyPublicClusterReachable();\n\n if (isAnyPublicClusterReachable) {\n LoggerProxy.logger.info(\n 'Roap:turnDiscovery#getSkipReason --> reachability has not failed, skipping TURN discovery'\n );\n\n return 'reachability';\n }\n\n return '';\n }\n\n /**\n * Checks if TURN discovery is skipped.\n *\n * @param {Meeting} meeting\n * @returns {Boolean} true if TURN discovery is being skipped, false if it is being done\n */\n async isSkipped(meeting) {\n const skipReason = await this.getSkipReason(meeting);\n\n return !!skipReason;\n }\n\n /**\n * Retrieves TURN server information from the backend by doing\n * a roap message exchange:\n * client server\n * | -----TURN_DISCOVERY_REQUEST-----> |\n * | <----TURN_DISCOVERY_RESPONSE----- |\n * | --------------OK----------------> |\n *\n * This TURN discovery roap exchange is always done with seq=0.\n * The RoapMediaConnection SDP exchange always starts with seq=1,\n * so it works fine no matter if TURN discovery is done or not.\n *\n * @param {Meeting} meeting\n * @param {Boolean} [isReconnecting] should be set to true if this is a new\n * media connection just after a reconnection\n * @param {Boolean} [isForced]\n * @returns {Promise}\n */\n async doTurnDiscovery(meeting: Meeting, isReconnecting?: boolean, isForced?: boolean) {\n let turnDiscoverySkippedReason: string;\n\n if (!isForced) {\n turnDiscoverySkippedReason = await this.getSkipReason(meeting);\n }\n\n if (turnDiscoverySkippedReason) {\n return {\n turnServerInfo: undefined,\n turnDiscoverySkippedReason,\n };\n }\n\n try {\n const httpResponse = await this.sendRoapTurnDiscoveryRequest(meeting, isReconnecting);\n\n // if we haven't got the response over http, we need to wait for it to come over the websocket via Mercury\n const {isOkRequired} = httpResponse\n ? await this.handleTurnDiscoveryResponseInHttpResponse(httpResponse)\n : await this.waitForTurnDiscoveryResponse();\n\n if (isOkRequired) {\n await this.sendRoapOK(meeting);\n\n LoggerProxy.logger.info(\n 'Roap:turnDiscovery#doTurnDiscovery --> TURN discovery response requires OK'\n );\n\n Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.TURN_DISCOVERY_REQUIRES_OK, {\n correlation_id: meeting.correlationId,\n locus_id: meeting.locusUrl.split('/').pop(),\n });\n }\n\n this.defer = undefined;\n\n LoggerProxy.logger.info('Roap:turnDiscovery#doTurnDiscovery --> TURN discovery completed');\n\n return {turnServerInfo: this.turnInfo, turnDiscoverySkippedReason: undefined};\n } catch (e) {\n // we catch any errors and resolve with no turn information so that the normal call join flow can continue without TURN\n LoggerProxy.logger.info(\n `Roap:turnDiscovery#doTurnDiscovery --> TURN discovery failed, continuing without TURN: ${e}`\n );\n\n Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.TURN_DISCOVERY_FAILURE, {\n correlation_id: meeting.correlationId,\n locus_id: meeting.locusUrl.split('/').pop(),\n reason: e.message,\n stack: e.stack,\n });\n\n return {turnServerInfo: undefined, turnDiscoverySkippedReason: undefined};\n }\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"names":["_common","require","_metrics","_interopRequireDefault","_constants","_loggerProxy","_constants2","_util","TURN_DISCOVERY_TIMEOUT","TURN_DISCOVERY_SEQ","TurnDiscoverySkipReason","missingHttpResponse","reachability","alreadyInProgress","TurnDiscovery","exports","default","roapRequest","_classCallCheck2","_defineProperty2","turnInfo","url","username","password","_createClass2","key","value","waitForTurnDiscoveryResponse","defer","LoggerProxy","logger","warn","_promise","reject","Error","responseTimer","setTimeout","concat","info","promise","handleTurnDiscoveryResponse","roapMessage","from","_this","headers","messageType","ROAP","ROAP_TYPES","TURN_DISCOVERY_RESPONSE","_stringify","expectedHeaders","headerName","field","foundHeaders","forEach","receivedHeader","expectedHeader","startsWith","substring","length","clearTimeout","undefined","resolve","isOkRequired","includes","_generateTurnDiscoveryRequestMessage","_asyncToGenerator2","_regenerator","mark","_callee","meeting","isForced","turnDiscoverySkippedReason","wrap","_callee$","_context","prev","next","abrupt","getSkipReason","sent","Defer","TURN_DISCOVERY_REQUEST","version","ROAP_VERSION","seq","stop","generateTurnDiscoveryRequestMessage","_x","_x2","apply","arguments","handleTurnDiscoveryFailure","error","Metrics","sendBehavioralMetric","BEHAVIORAL_METRICS","TURN_DISCOVERY_FAILURE","correlation_id","correlationId","locus_id","locusUrl","split","pop","reason","message","stack","turnServerInfo","_handleTurnDiscoveryHttpResponse","_callee2","httpResponse","_yield$this$defer$pro","_callee2$","_context2","parseHttpTurnDiscoveryResponse","sendRoapOK","t0","abort","handleTurnDiscoveryHttpResponse","_x3","_x4","_httpResponse$mediaCo","_httpResponse$mediaCo2","turnDiscoveryResponse","mediaConnections","remoteSdp","JSON","parse","_remoteSdp$roapMessag","errorType","errorCause","ROAP_HTTP_RESPONSE_MISSING","isMultistream","sendRoapTurnDiscoveryRequest","isReconnecting","_this2","sendRoap","locusSelfUrl","selfUrl","mediaId","meetingId","id","locusMediaRequest","ipVersion","MeetingUtil","getIpVersion","webex","then","_ref","_callee3","response","_callee3$","_context3","updateMediaConnections","_x5","TURN_DISCOVERY_REQUIRES_OK","OK","_getSkipReason","_callee4","isAnyPublicClusterReachable","_callee4$","_context4","meetings","_x6","_isSkipped","_callee5","skipReason","_callee5$","_context5","isSkipped","_x7","_doTurnDiscovery","_callee6","turnDiscoveryResult","_yield$this$waitForTu","_callee6$","_context6","doTurnDiscovery","_x8","_x9","_x10"],"sources":["turnDiscovery.ts"],"sourcesContent":["// @ts-ignore - Types not available for @webex/common\nimport {Defer} from '@webex/common';\n\nimport Metrics from '../metrics';\nimport BEHAVIORAL_METRICS from '../metrics/constants';\nimport LoggerProxy from '../common/logs/logger-proxy';\nimport {ROAP, Enum} from '../constants';\n\nimport RoapRequest from './request';\nimport Meeting from '../meeting';\nimport MeetingUtil from '../meeting/util';\n\nconst TURN_DISCOVERY_TIMEOUT = 10; // in seconds\n\n// Roap spec says that seq should start from 1, but TURN discovery works fine with seq=0\n// and this is handy for us, because TURN discovery is always done before the first SDP exchange,\n// so we can do it with seq=0 or not do it at all and then we create the RoapMediaConnection\n// and do the SDP offer with seq=1\nconst TURN_DISCOVERY_SEQ = 0;\n\nconst TurnDiscoverySkipReason = {\n missingHttpResponse: 'missing http response', // when we asked for the TURN discovery response to be in the http response, but it wasn't there\n reachability: 'reachability', // when udp reachability to public clusters is ok, so we don't need TURN (this doens't apply when joinWithMedia() is used)\n alreadyInProgress: 'already in progress', // when we try to start TURN discovery while it's already in progress\n} as const;\n\nexport type TurnDiscoverySkipReason =\n | Enum<typeof TurnDiscoverySkipReason> // this is a kind of FYI, because in practice typescript will infer the type of TurnDiscoverySkipReason as a string\n | string // used in case of errors, contains the error message\n | undefined; // used when TURN discovery is not skipped\n\nexport type TurnServerInfo = {\n url: string;\n username: string;\n password: string;\n};\n\nexport type TurnDiscoveryResult = {\n turnServerInfo?: TurnServerInfo;\n turnDiscoverySkippedReason: TurnDiscoverySkipReason;\n};\n\n/**\n * Handles the process of finding out TURN server information from Linus.\n * This is achieved by sending a TURN_DISCOVERY_REQUEST.\n */\nexport default class TurnDiscovery {\n private roapRequest: RoapRequest;\n\n private defer?: Defer; // used for waiting for the response\n\n private turnInfo: TurnServerInfo;\n\n private responseTimer?: ReturnType<typeof setTimeout>;\n\n /**\n * Constructor\n *\n * @param {RoapRequest} roapRequest\n */\n constructor(roapRequest: RoapRequest) {\n this.roapRequest = roapRequest;\n this.turnInfo = {\n url: '',\n username: '',\n password: '',\n };\n }\n\n /**\n * waits for TURN_DISCOVERY_RESPONSE message to arrive\n *\n * @returns {Promise}\n * @private\n * @memberof Roap\n */\n private waitForTurnDiscoveryResponse(): Promise<{isOkRequired: boolean}> {\n if (!this.defer) {\n LoggerProxy.logger.warn(\n 'Roap:turnDiscovery#waitForTurnDiscoveryResponse --> TURN discovery is not in progress'\n );\n\n return Promise.reject(\n new Error('waitForTurnDiscoveryResponse() called before sendRoapTurnDiscoveryRequest()')\n );\n }\n\n const {defer} = this;\n\n this.responseTimer = setTimeout(() => {\n LoggerProxy.logger.warn(\n `Roap:turnDiscovery#waitForTurnDiscoveryResponse --> timeout! no response arrived within ${TURN_DISCOVERY_TIMEOUT} seconds`\n );\n\n defer.reject(new Error('Timed out waiting for TURN_DISCOVERY_RESPONSE'));\n }, TURN_DISCOVERY_TIMEOUT * 1000);\n\n LoggerProxy.logger.info(\n 'Roap:turnDiscovery#waitForTurnDiscoveryResponse --> waiting for TURN_DISCOVERY_RESPONSE...'\n );\n\n return defer.promise;\n }\n\n /**\n * Handles TURN_DISCOVERY_RESPONSE roap message. Use it if the roap message comes over the websocket,\n * otherwise use handleTurnDiscoveryHttpResponse() if it comes in the http response.\n *\n * @param {Object} roapMessage\n * @param {string} from string to indicate how we got the response (used just for logging)\n * @returns {void}\n * @public\n * @memberof Roap\n */\n public handleTurnDiscoveryResponse(roapMessage: any, from: string) {\n const {headers} = roapMessage;\n\n if (!this.defer) {\n LoggerProxy.logger.warn(\n `Roap:turnDiscovery#handleTurnDiscoveryResponse --> unexpected TURN discovery response ${from}`\n );\n\n return;\n }\n\n if (roapMessage.messageType !== ROAP.ROAP_TYPES.TURN_DISCOVERY_RESPONSE) {\n this.defer.reject(\n new Error(\n `TURN_DISCOVERY_RESPONSE ${from} has unexpected messageType: ${JSON.stringify(\n roapMessage\n )}`\n )\n );\n }\n\n const expectedHeaders = [\n {headerName: 'x-cisco-turn-url', field: 'url'},\n {headerName: 'x-cisco-turn-username', field: 'username'},\n {headerName: 'x-cisco-turn-password', field: 'password'},\n ];\n\n let foundHeaders = 0;\n\n headers?.forEach((receivedHeader) => {\n // check if it matches any of our expected headers\n expectedHeaders.forEach((expectedHeader) => {\n if (receivedHeader.startsWith(`${expectedHeader.headerName}=`)) {\n this.turnInfo[expectedHeader.field] = receivedHeader.substring(\n expectedHeader.headerName.length + 1\n );\n foundHeaders += 1;\n }\n });\n });\n\n clearTimeout(this.responseTimer);\n this.responseTimer = undefined;\n\n if (foundHeaders !== expectedHeaders.length) {\n LoggerProxy.logger.warn(\n `Roap:turnDiscovery#handleTurnDiscoveryResponse --> missing some headers, received ${from}: ${JSON.stringify(\n headers\n )}`\n );\n this.defer.reject(\n new Error(\n `TURN_DISCOVERY_RESPONSE ${from} missing some headers: ${JSON.stringify(headers)}`\n )\n );\n } else {\n LoggerProxy.logger.info(\n `Roap:turnDiscovery#handleTurnDiscoveryResponse --> received a valid response ${from}, url=${this.turnInfo.url}`\n );\n\n this.defer.resolve({isOkRequired: !headers?.includes('noOkInTransaction')});\n }\n }\n\n /**\n * Generates TURN_DISCOVERY_REQUEST roap message. When this method returns a roapMessage, it means that a TURN discovery process has started.\n * It needs be ended by calling handleTurnDiscoveryHttpResponse() once you get a response from the backend. If you don't get any response\n * or want to abort, you need to call abort().\n *\n * @param {Meeting} meeting\n * @param {boolean} isForced\n * @returns {Object}\n */\n public async generateTurnDiscoveryRequestMessage(\n meeting: Meeting,\n isForced: boolean\n ): Promise<{roapMessage?: object; turnDiscoverySkippedReason: TurnDiscoverySkipReason}> {\n if (this.defer) {\n LoggerProxy.logger.warn(\n 'Roap:turnDiscovery#generateTurnDiscoveryRequestMessage --> TURN discovery already in progress'\n );\n\n return {\n roapMessage: undefined,\n turnDiscoverySkippedReason: TurnDiscoverySkipReason.alreadyInProgress,\n };\n }\n\n let turnDiscoverySkippedReason: TurnDiscoverySkipReason;\n\n if (!isForced) {\n turnDiscoverySkippedReason = await this.getSkipReason(meeting);\n }\n\n if (turnDiscoverySkippedReason) {\n return {roapMessage: undefined, turnDiscoverySkippedReason};\n }\n\n this.defer = new Defer();\n\n const roapMessage = {\n messageType: ROAP.ROAP_TYPES.TURN_DISCOVERY_REQUEST,\n version: ROAP.ROAP_VERSION,\n seq: TURN_DISCOVERY_SEQ,\n headers: ['includeAnswerInHttpResponse', 'noOkInTransaction'],\n };\n\n LoggerProxy.logger.info(\n 'Roap:turnDiscovery#generateTurnDiscoveryRequestMessage --> generated TURN_DISCOVERY_REQUEST message'\n );\n\n return {roapMessage, turnDiscoverySkippedReason: undefined};\n }\n\n /**\n * Handles any errors that occur during TURN discovery without re-throwing them.\n *\n * @param {Meeting} meeting\n * @param {Error} error\n * @returns {TurnDiscoveryResult}\n */\n private handleTurnDiscoveryFailure(meeting: Meeting, error: Error): TurnDiscoveryResult {\n // we catch any errors and resolve with no turn information so that the normal call join flow can continue without TURN\n LoggerProxy.logger.info(\n `Roap:turnDiscovery#doTurnDiscovery --> TURN discovery failed, continuing without TURN: ${error}`\n );\n\n Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.TURN_DISCOVERY_FAILURE, {\n correlation_id: meeting.correlationId,\n locus_id: meeting.locusUrl.split('/').pop(),\n reason: error.message,\n stack: error.stack,\n });\n\n return {turnServerInfo: undefined, turnDiscoverySkippedReason: `failure: ${error.message}`};\n }\n\n /**\n * Handles TURN_DISCOVERY_RESPONSE roap message that came in http response. If the response is not valid,\n * it returns an object with turnServerInfo set to undefined. In that case you need to call abort()\n * to end the TURN discovery process.\n *\n * @param {Meeting} meeting\n * @param {Object|undefined} httpResponse can be undefined to indicate that we didn't get the response\n * @returns {Promise<TurnDiscoveryResult>}\n * @memberof Roap\n */\n public async handleTurnDiscoveryHttpResponse(\n meeting: Meeting,\n httpResponse?: object\n ): Promise<TurnDiscoveryResult> {\n if (!this.defer) {\n LoggerProxy.logger.warn(\n 'Roap:turnDiscovery#handleTurnDiscoveryHttpResponse --> unexpected http response, TURN discovery is not in progress'\n );\n\n throw new Error(\n 'handleTurnDiscoveryHttpResponse() called before generateTurnDiscoveryRequestMessage()'\n );\n }\n\n if (httpResponse === undefined) {\n return {\n turnServerInfo: undefined,\n turnDiscoverySkippedReason: TurnDiscoverySkipReason.missingHttpResponse,\n };\n }\n\n try {\n const roapMessage = this.parseHttpTurnDiscoveryResponse(meeting, httpResponse);\n\n if (!roapMessage) {\n return {\n turnServerInfo: undefined,\n turnDiscoverySkippedReason: TurnDiscoverySkipReason.missingHttpResponse,\n };\n }\n\n this.handleTurnDiscoveryResponse(roapMessage, 'in http response');\n\n const {isOkRequired} = await this.defer.promise;\n\n if (isOkRequired) {\n await this.sendRoapOK(meeting);\n }\n\n this.defer = undefined;\n\n LoggerProxy.logger.info('Roap:turnDiscovery#doTurnDiscovery --> TURN discovery completed');\n\n return {turnServerInfo: this.turnInfo, turnDiscoverySkippedReason: undefined};\n } catch (error) {\n this.abort();\n\n return this.handleTurnDiscoveryFailure(meeting, error);\n }\n }\n\n /**\n * Aborts current TURN discovery. This method needs to be called if you called generateTurnDiscoveryRequestMessage(),\n * but then never got any response from the server.\n * @returns {void}\n */\n public abort() {\n if (this.defer) {\n this.defer.reject(new Error('TURN discovery aborted'));\n this.defer = undefined;\n }\n }\n\n /**\n * Parses the TURN_DISCOVERY_RESPONSE roap message out of the http response\n * and returns it.\n *\n * @param {Meeting} meeting\n * @param {any} httpResponse\n * @returns {any}\n */\n private parseHttpTurnDiscoveryResponse(\n meeting: Meeting,\n httpResponse: {mediaConnections?: Array<{remoteSdp?: string}>}\n ) {\n let turnDiscoveryResponse;\n\n if (httpResponse.mediaConnections?.[0]?.remoteSdp) {\n const remoteSdp = JSON.parse(httpResponse.mediaConnections[0].remoteSdp);\n\n if (remoteSdp.roapMessage) {\n // yes, it's misleading that remoteSdp actually contains a TURN discovery response, but that's how the backend works...\n const {seq, messageType, errorType, errorCause, headers} = remoteSdp.roapMessage;\n\n turnDiscoveryResponse = {\n seq,\n messageType,\n errorType,\n errorCause,\n headers,\n };\n }\n }\n\n if (!turnDiscoveryResponse) {\n Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.ROAP_HTTP_RESPONSE_MISSING, {\n correlationId: meeting.correlationId,\n messageType: 'TURN_DISCOVERY_RESPONSE',\n isMultistream: meeting.isMultistream,\n });\n }\n\n return turnDiscoveryResponse;\n }\n\n /**\n * sends the TURN_DISCOVERY_REQUEST roap request\n *\n * @param {Meeting} meeting\n * @param {Boolean} isReconnecting\n * @returns {Promise}\n * @private\n * @memberof Roap\n */\n private sendRoapTurnDiscoveryRequest(\n meeting: Meeting,\n isReconnecting: boolean\n ): Promise<TurnDiscoveryResult> {\n if (this.defer) {\n LoggerProxy.logger.warn(\n 'Roap:turnDiscovery#sendRoapTurnDiscoveryRequest --> already in progress'\n );\n\n return Promise.resolve({\n turnServerInfo: undefined,\n turnDiscoverySkippedReason: TurnDiscoverySkipReason.alreadyInProgress,\n });\n }\n\n this.defer = new Defer();\n\n const roapMessage = {\n messageType: ROAP.ROAP_TYPES.TURN_DISCOVERY_REQUEST,\n version: ROAP.ROAP_VERSION,\n seq: TURN_DISCOVERY_SEQ,\n headers: ['includeAnswerInHttpResponse', 'noOkInTransaction'],\n };\n\n LoggerProxy.logger.info(\n 'Roap:turnDiscovery#sendRoapTurnDiscoveryRequest --> sending TURN_DISCOVERY_REQUEST'\n );\n\n return this.roapRequest\n .sendRoap({\n roapMessage,\n // @ts-ignore - Fix missing type\n locusSelfUrl: meeting.selfUrl,\n // @ts-ignore - Fix missing type\n mediaId: isReconnecting ? '' : meeting.mediaId,\n meetingId: meeting.id,\n locusMediaRequest: meeting.locusMediaRequest,\n // @ts-ignore - because of meeting.webex\n ipVersion: MeetingUtil.getIpVersion(meeting.webex),\n })\n .then(async (response) => {\n const {mediaConnections} = response;\n\n if (mediaConnections) {\n meeting.updateMediaConnections(mediaConnections);\n }\n\n return this.handleTurnDiscoveryHttpResponse(meeting, response);\n });\n }\n\n /**\n * Sends the OK message that server expects to receive\n * after it sends us TURN_DISCOVERY_RESPONSE\n *\n * @param {Meeting} meeting\n * @returns {Promise}\n */\n sendRoapOK(meeting: Meeting) {\n LoggerProxy.logger.info(\n 'Roap:turnDiscovery#sendRoapOK --> TURN discovery response requires OK, sending it...'\n );\n\n Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.TURN_DISCOVERY_REQUIRES_OK, {\n correlation_id: meeting.correlationId,\n locus_id: meeting.locusUrl.split('/').pop(),\n });\n\n return this.roapRequest.sendRoap({\n roapMessage: {\n messageType: ROAP.ROAP_TYPES.OK,\n version: ROAP.ROAP_VERSION,\n seq: TURN_DISCOVERY_SEQ,\n },\n // @ts-ignore - fix type\n locusSelfUrl: meeting.selfUrl,\n // @ts-ignore - fix type\n mediaId: meeting.mediaId,\n meetingId: meeting.id,\n locusMediaRequest: meeting.locusMediaRequest,\n });\n }\n\n /**\n * Gets the reason why reachability is skipped.\n *\n * @param {Meeting} meeting\n * @returns {Promise<string>} Promise with empty string if reachability is not skipped or a reason if it is skipped\n */\n private async getSkipReason(meeting: Meeting): Promise<TurnDiscoverySkipReason> {\n const isAnyPublicClusterReachable =\n // @ts-ignore - fix type\n await meeting.webex.meetings.reachability.isAnyPublicClusterReachable();\n\n if (isAnyPublicClusterReachable) {\n LoggerProxy.logger.info(\n 'Roap:turnDiscovery#getSkipReason --> reachability has not failed, skipping TURN discovery'\n );\n\n return TurnDiscoverySkipReason.reachability;\n }\n\n return undefined;\n }\n\n /**\n * Checks if TURN discovery is skipped.\n *\n * @param {Meeting} meeting\n * @returns {Boolean} true if TURN discovery is being skipped, false if it is being done\n */\n async isSkipped(meeting) {\n const skipReason = await this.getSkipReason(meeting);\n\n return !!skipReason;\n }\n\n /**\n * Retrieves TURN server information from the backend by doing\n * a roap message exchange:\n * client server\n * | -----TURN_DISCOVERY_REQUEST-----> |\n * | <----TURN_DISCOVERY_RESPONSE----- |\n * | --------------OK----------------> |\n *\n * This TURN discovery roap exchange is always done with seq=0.\n * The RoapMediaConnection SDP exchange always starts with seq=1,\n * so it works fine no matter if TURN discovery is done or not.\n *\n * @param {Meeting} meeting\n * @param {Boolean} [isReconnecting] should be set to true if this is a new\n * media connection just after a reconnection\n * @param {Boolean} [isForced]\n * @returns {Promise}\n */\n async doTurnDiscovery(\n meeting: Meeting,\n isReconnecting?: boolean,\n isForced?: boolean\n ): Promise<TurnDiscoveryResult> {\n let turnDiscoverySkippedReason: TurnDiscoverySkipReason;\n\n if (!isForced) {\n turnDiscoverySkippedReason = await this.getSkipReason(meeting);\n }\n\n if (turnDiscoverySkippedReason) {\n return {\n turnServerInfo: undefined,\n turnDiscoverySkippedReason,\n };\n }\n\n try {\n const turnDiscoveryResult = await this.sendRoapTurnDiscoveryRequest(meeting, isReconnecting);\n\n if (\n turnDiscoveryResult.turnDiscoverySkippedReason !==\n TurnDiscoverySkipReason.missingHttpResponse\n ) {\n return turnDiscoveryResult;\n }\n\n // if we haven't got the response over http, we need to wait for it to come over the websocket via Mercury\n const {isOkRequired} = await this.waitForTurnDiscoveryResponse();\n\n if (isOkRequired) {\n await this.sendRoapOK(meeting);\n }\n\n this.defer = undefined;\n\n LoggerProxy.logger.info('Roap:turnDiscovery#doTurnDiscovery --> TURN discovery completed');\n\n return {turnServerInfo: this.turnInfo, turnDiscoverySkippedReason: undefined};\n } catch (e) {\n return this.handleTurnDiscoveryFailure(meeting, e);\n }\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;AACA,IAAAA,OAAA,GAAAC,OAAA;AAEA,IAAAC,QAAA,GAAAC,sBAAA,CAAAF,OAAA;AACA,IAAAG,UAAA,GAAAD,sBAAA,CAAAF,OAAA;AACA,IAAAI,YAAA,GAAAF,sBAAA,CAAAF,OAAA;AACA,IAAAK,WAAA,GAAAL,OAAA;AAIA,IAAAM,KAAA,GAAAJ,sBAAA,CAAAF,OAAA;AAVA;;AAYA,IAAMO,sBAAsB,GAAG,EAAE,CAAC,CAAC;;AAEnC;AACA;AACA;AACA;AACA,IAAMC,kBAAkB,GAAG,CAAC;AAE5B,IAAMC,uBAAuB,GAAG;EAC9BC,mBAAmB,EAAE,uBAAuB;EAAE;EAC9CC,YAAY,EAAE,cAAc;EAAE;EAC9BC,iBAAiB,EAAE,qBAAqB,CAAE;AAC5C,CAAU;;AAKK;AAaf;AACA;AACA;AACA;AAHA,IAIqBC,aAAa,GAAAC,OAAA,CAAAC,OAAA;EAShC;AACF;AACA;AACA;AACA;EACE,SAAAF,cAAYG,WAAwB,EAAE;IAAA,IAAAC,gBAAA,CAAAF,OAAA,QAAAF,aAAA;IAAA,IAAAK,gBAAA,CAAAH,OAAA;IAAA,IAAAG,gBAAA,CAAAH,OAAA;IAXf;IAAA,IAAAG,gBAAA,CAAAH,OAAA;IAAA,IAAAG,gBAAA,CAAAH,OAAA;IAYrB,IAAI,CAACC,WAAW,GAAGA,WAAW;IAC9B,IAAI,CAACG,QAAQ,GAAG;MACdC,GAAG,EAAE,EAAE;MACPC,QAAQ,EAAE,EAAE;MACZC,QAAQ,EAAE;IACZ,CAAC;EACH;;EAEA;AACF;AACA;AACA;AACA;AACA;AACA;EANE,IAAAC,aAAA,CAAAR,OAAA,EAAAF,aAAA;IAAAW,GAAA;IAAAC,KAAA,EAOA,SAAAC,6BAAA,EAAyE;MACvE,IAAI,CAAC,IAAI,CAACC,KAAK,EAAE;QACfC,oBAAW,CAACC,MAAM,CAACC,IAAI,CACrB,uFACF,CAAC;QAED,OAAOC,QAAA,CAAAhB,OAAA,CAAQiB,MAAM,CACnB,IAAIC,KAAK,CAAC,6EAA6E,CACzF,CAAC;MACH;MAEA,IAAON,KAAK,GAAI,IAAI,CAAbA,KAAK;MAEZ,IAAI,CAACO,aAAa,GAAGC,UAAU,CAAC,YAAM;QACpCP,oBAAW,CAACC,MAAM,CAACC,IAAI,4FAAAM,MAAA,CACsE7B,sBAAsB,aACnH,CAAC;QAEDoB,KAAK,CAACK,MAAM,CAAC,IAAIC,KAAK,CAAC,+CAA+C,CAAC,CAAC;MAC1E,CAAC,EAAE1B,sBAAsB,GAAG,IAAI,CAAC;MAEjCqB,oBAAW,CAACC,MAAM,CAACQ,IAAI,CACrB,4FACF,CAAC;MAED,OAAOV,KAAK,CAACW,OAAO;IACtB;;IAEA;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;EATE;IAAAd,GAAA;IAAAC,KAAA,EAUA,SAAAc,4BAAmCC,WAAgB,EAAEC,IAAY,EAAE;MAAA,IAAAC,KAAA;MACjE,IAAOC,OAAO,GAAIH,WAAW,CAAtBG,OAAO;MAEd,IAAI,CAAC,IAAI,CAAChB,KAAK,EAAE;QACfC,oBAAW,CAACC,MAAM,CAACC,IAAI,0FAAAM,MAAA,CACoEK,IAAI,CAC/F,CAAC;QAED;MACF;MAEA,IAAID,WAAW,CAACI,WAAW,KAAKC,gBAAI,CAACC,UAAU,CAACC,uBAAuB,EAAE;QACvE,IAAI,CAACpB,KAAK,CAACK,MAAM,CACf,IAAIC,KAAK,4BAAAG,MAAA,CACoBK,IAAI,mCAAAL,MAAA,CAAgC,IAAAY,UAAA,CAAAjC,OAAA,EAC7DyB,WACF,CAAC,CACH,CACF,CAAC;MACH;MAEA,IAAMS,eAAe,GAAG,CACtB;QAACC,UAAU,EAAE,kBAAkB;QAAEC,KAAK,EAAE;MAAK,CAAC,EAC9C;QAACD,UAAU,EAAE,uBAAuB;QAAEC,KAAK,EAAE;MAAU,CAAC,EACxD;QAACD,UAAU,EAAE,uBAAuB;QAAEC,KAAK,EAAE;MAAU,CAAC,CACzD;MAED,IAAIC,YAAY,GAAG,CAAC;MAEpBT,OAAO,aAAPA,OAAO,uBAAPA,OAAO,CAAEU,OAAO,CAAC,UAACC,cAAc,EAAK;QACnC;QACAL,eAAe,CAACI,OAAO,CAAC,UAACE,cAAc,EAAK;UAC1C,IAAID,cAAc,CAACE,UAAU,IAAApB,MAAA,CAAImB,cAAc,CAACL,UAAU,MAAG,CAAC,EAAE;YAC9DR,KAAI,CAACvB,QAAQ,CAACoC,cAAc,CAACJ,KAAK,CAAC,GAAGG,cAAc,CAACG,SAAS,CAC5DF,cAAc,CAACL,UAAU,CAACQ,MAAM,GAAG,CACrC,CAAC;YACDN,YAAY,IAAI,CAAC;UACnB;QACF,CAAC,CAAC;MACJ,CAAC,CAAC;MAEFO,YAAY,CAAC,IAAI,CAACzB,aAAa,CAAC;MAChC,IAAI,CAACA,aAAa,GAAG0B,SAAS;MAE9B,IAAIR,YAAY,KAAKH,eAAe,CAACS,MAAM,EAAE;QAC3C9B,oBAAW,CAACC,MAAM,CAACC,IAAI,sFAAAM,MAAA,CACgEK,IAAI,QAAAL,MAAA,CAAK,IAAAY,UAAA,CAAAjC,OAAA,EAC5F4B,OACF,CAAC,CACH,CAAC;QACD,IAAI,CAAChB,KAAK,CAACK,MAAM,CACf,IAAIC,KAAK,4BAAAG,MAAA,CACoBK,IAAI,6BAAAL,MAAA,CAA0B,IAAAY,UAAA,CAAAjC,OAAA,EAAe4B,OAAO,CAAC,CAClF,CACF,CAAC;MACH,CAAC,MAAM;QACLf,oBAAW,CAACC,MAAM,CAACQ,IAAI,iFAAAD,MAAA,CAC2DK,IAAI,YAAAL,MAAA,CAAS,IAAI,CAACjB,QAAQ,CAACC,GAAG,CAChH,CAAC;QAED,IAAI,CAACO,KAAK,CAACkC,OAAO,CAAC;UAACC,YAAY,EAAE,EAACnB,OAAO,aAAPA,OAAO,eAAPA,OAAO,CAAEoB,QAAQ,CAAC,mBAAmB,CAAC;QAAA,CAAC,CAAC;MAC7E;IACF;;IAEA;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;EARE;IAAAvC,GAAA;IAAAC,KAAA;MAAA,IAAAuC,oCAAA,OAAAC,kBAAA,CAAAlD,OAAA,gBAAAmD,YAAA,CAAAnD,OAAA,CAAAoD,IAAA,CASA,SAAAC,QACEC,OAAgB,EAChBC,QAAiB;QAAA,IAAAC,0BAAA,EAAA/B,WAAA;QAAA,OAAA0B,YAAA,CAAAnD,OAAA,CAAAyD,IAAA,UAAAC,SAAAC,QAAA;UAAA,kBAAAA,QAAA,CAAAC,IAAA,GAAAD,QAAA,CAAAE,IAAA;YAAA;cAAA,KAEb,IAAI,CAACjD,KAAK;gBAAA+C,QAAA,CAAAE,IAAA;gBAAA;cAAA;cACZhD,oBAAW,CAACC,MAAM,CAACC,IAAI,CACrB,+FACF,CAAC;cAAC,OAAA4C,QAAA,CAAAG,MAAA,WAEK;gBACLrC,WAAW,EAAEoB,SAAS;gBACtBW,0BAA0B,EAAE9D,uBAAuB,CAACG;cACtD,CAAC;YAAA;cAAA,IAKE0D,QAAQ;gBAAAI,QAAA,CAAAE,IAAA;gBAAA;cAAA;cAAAF,QAAA,CAAAE,IAAA;cAAA,OACwB,IAAI,CAACE,aAAa,CAACT,OAAO,CAAC;YAAA;cAA9DE,0BAA0B,GAAAG,QAAA,CAAAK,IAAA;YAAA;cAAA,KAGxBR,0BAA0B;gBAAAG,QAAA,CAAAE,IAAA;gBAAA;cAAA;cAAA,OAAAF,QAAA,CAAAG,MAAA,WACrB;gBAACrC,WAAW,EAAEoB,SAAS;gBAAEW,0BAA0B,EAA1BA;cAA0B,CAAC;YAAA;cAG7D,IAAI,CAAC5C,KAAK,GAAG,IAAIqD,aAAK,CAAC,CAAC;cAElBxC,WAAW,GAAG;gBAClBI,WAAW,EAAEC,gBAAI,CAACC,UAAU,CAACmC,sBAAsB;gBACnDC,OAAO,EAAErC,gBAAI,CAACsC,YAAY;gBAC1BC,GAAG,EAAE5E,kBAAkB;gBACvBmC,OAAO,EAAE,CAAC,6BAA6B,EAAE,mBAAmB;cAC9D,CAAC;cAEDf,oBAAW,CAACC,MAAM,CAACQ,IAAI,CACrB,qGACF,CAAC;cAAC,OAAAqC,QAAA,CAAAG,MAAA,WAEK;gBAACrC,WAAW,EAAXA,WAAW;gBAAE+B,0BAA0B,EAAEX;cAAS,CAAC;YAAA;YAAA;cAAA,OAAAc,QAAA,CAAAW,IAAA;UAAA;QAAA,GAAAjB,OAAA;MAAA,CAC5D;MAAA,SAAAkB,oCAAAC,EAAA,EAAAC,GAAA;QAAA,OAAAxB,oCAAA,CAAAyB,KAAA,OAAAC,SAAA;MAAA;MAAA,OAAAJ,mCAAA;IAAA;IAED;AACF;AACA;AACA;AACA;AACA;AACA;IANE;EAAA;IAAA9D,GAAA;IAAAC,KAAA,EAOA,SAAAkE,2BAAmCtB,OAAgB,EAAEuB,KAAY,EAAuB;MACtF;MACAhE,oBAAW,CAACC,MAAM,CAACQ,IAAI,2FAAAD,MAAA,CACqEwD,KAAK,CACjG,CAAC;MAEDC,gBAAO,CAACC,oBAAoB,CAACC,kBAAkB,CAACC,sBAAsB,EAAE;QACtEC,cAAc,EAAE5B,OAAO,CAAC6B,aAAa;QACrCC,QAAQ,EAAE9B,OAAO,CAAC+B,QAAQ,CAACC,KAAK,CAAC,GAAG,CAAC,CAACC,GAAG,CAAC,CAAC;QAC3CC,MAAM,EAAEX,KAAK,CAACY,OAAO;QACrBC,KAAK,EAAEb,KAAK,CAACa;MACf,CAAC,CAAC;MAEF,OAAO;QAACC,cAAc,EAAE9C,SAAS;QAAEW,0BAA0B,cAAAnC,MAAA,CAAcwD,KAAK,CAACY,OAAO;MAAE,CAAC;IAC7F;;IAEA;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;EATE;IAAAhF,GAAA;IAAAC,KAAA;MAAA,IAAAkF,gCAAA,OAAA1C,kBAAA,CAAAlD,OAAA,gBAAAmD,YAAA,CAAAnD,OAAA,CAAAoD,IAAA,CAUA,SAAAyC,SACEvC,OAAgB,EAChBwC,YAAqB;QAAA,IAAArE,WAAA,EAAAsE,qBAAA,EAAAhD,YAAA;QAAA,OAAAI,YAAA,CAAAnD,OAAA,CAAAyD,IAAA,UAAAuC,UAAAC,SAAA;UAAA,kBAAAA,SAAA,CAAArC,IAAA,GAAAqC,SAAA,CAAApC,IAAA;YAAA;cAAA,IAEhB,IAAI,CAACjD,KAAK;gBAAAqF,SAAA,CAAApC,IAAA;gBAAA;cAAA;cACbhD,oBAAW,CAACC,MAAM,CAACC,IAAI,CACrB,oHACF,CAAC;cAAC,MAEI,IAAIG,KAAK,CACb,uFACF,CAAC;YAAA;cAAA,MAGC4E,YAAY,KAAKjD,SAAS;gBAAAoD,SAAA,CAAApC,IAAA;gBAAA;cAAA;cAAA,OAAAoC,SAAA,CAAAnC,MAAA,WACrB;gBACL6B,cAAc,EAAE9C,SAAS;gBACzBW,0BAA0B,EAAE9D,uBAAuB,CAACC;cACtD,CAAC;YAAA;cAAAsG,SAAA,CAAArC,IAAA;cAIKnC,WAAW,GAAG,IAAI,CAACyE,8BAA8B,CAAC5C,OAAO,EAAEwC,YAAY,CAAC;cAAA,IAEzErE,WAAW;gBAAAwE,SAAA,CAAApC,IAAA;gBAAA;cAAA;cAAA,OAAAoC,SAAA,CAAAnC,MAAA,WACP;gBACL6B,cAAc,EAAE9C,SAAS;gBACzBW,0BAA0B,EAAE9D,uBAAuB,CAACC;cACtD,CAAC;YAAA;cAGH,IAAI,CAAC6B,2BAA2B,CAACC,WAAW,EAAE,kBAAkB,CAAC;cAACwE,SAAA,CAAApC,IAAA;cAAA,OAErC,IAAI,CAACjD,KAAK,CAACW,OAAO;YAAA;cAAAwE,qBAAA,GAAAE,SAAA,CAAAjC,IAAA;cAAxCjB,YAAY,GAAAgD,qBAAA,CAAZhD,YAAY;cAAA,KAEfA,YAAY;gBAAAkD,SAAA,CAAApC,IAAA;gBAAA;cAAA;cAAAoC,SAAA,CAAApC,IAAA;cAAA,OACR,IAAI,CAACsC,UAAU,CAAC7C,OAAO,CAAC;YAAA;cAGhC,IAAI,CAAC1C,KAAK,GAAGiC,SAAS;cAEtBhC,oBAAW,CAACC,MAAM,CAACQ,IAAI,CAAC,iEAAiE,CAAC;cAAC,OAAA2E,SAAA,CAAAnC,MAAA,WAEpF;gBAAC6B,cAAc,EAAE,IAAI,CAACvF,QAAQ;gBAAEoD,0BAA0B,EAAEX;cAAS,CAAC;YAAA;cAAAoD,SAAA,CAAArC,IAAA;cAAAqC,SAAA,CAAAG,EAAA,GAAAH,SAAA;cAE7E,IAAI,CAACI,KAAK,CAAC,CAAC;cAAC,OAAAJ,SAAA,CAAAnC,MAAA,WAEN,IAAI,CAACc,0BAA0B,CAACtB,OAAO,EAAA2C,SAAA,CAAAG,EAAO,CAAC;YAAA;YAAA;cAAA,OAAAH,SAAA,CAAA3B,IAAA;UAAA;QAAA,GAAAuB,QAAA;MAAA,CAEzD;MAAA,SAAAS,gCAAAC,GAAA,EAAAC,GAAA;QAAA,OAAAZ,gCAAA,CAAAlB,KAAA,OAAAC,SAAA;MAAA;MAAA,OAAA2B,+BAAA;IAAA;IAED;AACF;AACA;AACA;AACA;IAJE;EAAA;IAAA7F,GAAA;IAAAC,KAAA,EAKA,SAAA2F,MAAA,EAAe;MACb,IAAI,IAAI,CAACzF,KAAK,EAAE;QACd,IAAI,CAACA,KAAK,CAACK,MAAM,CAAC,IAAIC,KAAK,CAAC,wBAAwB,CAAC,CAAC;QACtD,IAAI,CAACN,KAAK,GAAGiC,SAAS;MACxB;IACF;;IAEA;AACF;AACA;AACA;AACA;AACA;AACA;AACA;EAPE;IAAApC,GAAA;IAAAC,KAAA,EAQA,SAAAwF,+BACE5C,OAAgB,EAChBwC,YAA8D,EAC9D;MAAA,IAAAW,qBAAA,EAAAC,sBAAA;MACA,IAAIC,qBAAqB;MAEzB,KAAAF,qBAAA,GAAIX,YAAY,CAACc,gBAAgB,cAAAH,qBAAA,gBAAAC,sBAAA,GAA7BD,qBAAA,CAAgC,CAAC,CAAC,cAAAC,sBAAA,eAAlCA,sBAAA,CAAoCG,SAAS,EAAE;QACjD,IAAMA,SAAS,GAAGC,IAAI,CAACC,KAAK,CAACjB,YAAY,CAACc,gBAAgB,CAAC,CAAC,CAAC,CAACC,SAAS,CAAC;QAExE,IAAIA,SAAS,CAACpF,WAAW,EAAE;UACzB;UACA,IAAAuF,qBAAA,GAA2DH,SAAS,CAACpF,WAAW;YAAzE4C,GAAG,GAAA2C,qBAAA,CAAH3C,GAAG;YAAExC,WAAW,GAAAmF,qBAAA,CAAXnF,WAAW;YAAEoF,SAAS,GAAAD,qBAAA,CAATC,SAAS;YAAEC,UAAU,GAAAF,qBAAA,CAAVE,UAAU;YAAEtF,OAAO,GAAAoF,qBAAA,CAAPpF,OAAO;UAEvD+E,qBAAqB,GAAG;YACtBtC,GAAG,EAAHA,GAAG;YACHxC,WAAW,EAAXA,WAAW;YACXoF,SAAS,EAATA,SAAS;YACTC,UAAU,EAAVA,UAAU;YACVtF,OAAO,EAAPA;UACF,CAAC;QACH;MACF;MAEA,IAAI,CAAC+E,qBAAqB,EAAE;QAC1B7B,gBAAO,CAACC,oBAAoB,CAACC,kBAAkB,CAACmC,0BAA0B,EAAE;UAC1EhC,aAAa,EAAE7B,OAAO,CAAC6B,aAAa;UACpCtD,WAAW,EAAE,yBAAyB;UACtCuF,aAAa,EAAE9D,OAAO,CAAC8D;QACzB,CAAC,CAAC;MACJ;MAEA,OAAOT,qBAAqB;IAC9B;;IAEA;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;EARE;IAAAlG,GAAA;IAAAC,KAAA,EASA,SAAA2G,6BACE/D,OAAgB,EAChBgE,cAAuB,EACO;MAAA,IAAAC,MAAA;MAC9B,IAAI,IAAI,CAAC3G,KAAK,EAAE;QACdC,oBAAW,CAACC,MAAM,CAACC,IAAI,CACrB,yEACF,CAAC;QAED,OAAOC,QAAA,CAAAhB,OAAA,CAAQ8C,OAAO,CAAC;UACrB6C,cAAc,EAAE9C,SAAS;UACzBW,0BAA0B,EAAE9D,uBAAuB,CAACG;QACtD,CAAC,CAAC;MACJ;MAEA,IAAI,CAACe,KAAK,GAAG,IAAIqD,aAAK,CAAC,CAAC;MAExB,IAAMxC,WAAW,GAAG;QAClBI,WAAW,EAAEC,gBAAI,CAACC,UAAU,CAACmC,sBAAsB;QACnDC,OAAO,EAAErC,gBAAI,CAACsC,YAAY;QAC1BC,GAAG,EAAE5E,kBAAkB;QACvBmC,OAAO,EAAE,CAAC,6BAA6B,EAAE,mBAAmB;MAC9D,CAAC;MAEDf,oBAAW,CAACC,MAAM,CAACQ,IAAI,CACrB,oFACF,CAAC;MAED,OAAO,IAAI,CAACrB,WAAW,CACpBuH,QAAQ,CAAC;QACR/F,WAAW,EAAXA,WAAW;QACX;QACAgG,YAAY,EAAEnE,OAAO,CAACoE,OAAO;QAC7B;QACAC,OAAO,EAAEL,cAAc,GAAG,EAAE,GAAGhE,OAAO,CAACqE,OAAO;QAC9CC,SAAS,EAAEtE,OAAO,CAACuE,EAAE;QACrBC,iBAAiB,EAAExE,OAAO,CAACwE,iBAAiB;QAC5C;QACAC,SAAS,EAAEC,aAAW,CAACC,YAAY,CAAC3E,OAAO,CAAC4E,KAAK;MACnD,CAAC,CAAC,CACDC,IAAI;QAAA,IAAAC,IAAA,OAAAlF,kBAAA,CAAAlD,OAAA,gBAAAmD,YAAA,CAAAnD,OAAA,CAAAoD,IAAA,CAAC,SAAAiF,SAAOC,QAAQ;UAAA,IAAA1B,gBAAA;UAAA,OAAAzD,YAAA,CAAAnD,OAAA,CAAAyD,IAAA,UAAA8E,UAAAC,SAAA;YAAA,kBAAAA,SAAA,CAAA5E,IAAA,GAAA4E,SAAA,CAAA3E,IAAA;cAAA;gBACZ+C,gBAAgB,GAAI0B,QAAQ,CAA5B1B,gBAAgB;gBAEvB,IAAIA,gBAAgB,EAAE;kBACpBtD,OAAO,CAACmF,sBAAsB,CAAC7B,gBAAgB,CAAC;gBAClD;gBAAC,OAAA4B,SAAA,CAAA1E,MAAA,WAEMyD,MAAI,CAACjB,+BAA+B,CAAChD,OAAO,EAAEgF,QAAQ,CAAC;cAAA;cAAA;gBAAA,OAAAE,SAAA,CAAAlE,IAAA;YAAA;UAAA,GAAA+D,QAAA;QAAA,CAC/D;QAAA,iBAAAK,GAAA;UAAA,OAAAN,IAAA,CAAA1D,KAAA,OAAAC,SAAA;QAAA;MAAA,IAAC;IACN;;IAEA;AACF;AACA;AACA;AACA;AACA;AACA;EANE;IAAAlE,GAAA;IAAAC,KAAA,EAOA,SAAAyF,WAAW7C,OAAgB,EAAE;MAC3BzC,oBAAW,CAACC,MAAM,CAACQ,IAAI,CACrB,sFACF,CAAC;MAEDwD,gBAAO,CAACC,oBAAoB,CAACC,kBAAkB,CAAC2D,0BAA0B,EAAE;QAC1EzD,cAAc,EAAE5B,OAAO,CAAC6B,aAAa;QACrCC,QAAQ,EAAE9B,OAAO,CAAC+B,QAAQ,CAACC,KAAK,CAAC,GAAG,CAAC,CAACC,GAAG,CAAC;MAC5C,CAAC,CAAC;MAEF,OAAO,IAAI,CAACtF,WAAW,CAACuH,QAAQ,CAAC;QAC/B/F,WAAW,EAAE;UACXI,WAAW,EAAEC,gBAAI,CAACC,UAAU,CAAC6G,EAAE;UAC/BzE,OAAO,EAAErC,gBAAI,CAACsC,YAAY;UAC1BC,GAAG,EAAE5E;QACP,CAAC;QACD;QACAgI,YAAY,EAAEnE,OAAO,CAACoE,OAAO;QAC7B;QACAC,OAAO,EAAErE,OAAO,CAACqE,OAAO;QACxBC,SAAS,EAAEtE,OAAO,CAACuE,EAAE;QACrBC,iBAAiB,EAAExE,OAAO,CAACwE;MAC7B,CAAC,CAAC;IACJ;;IAEA;AACF;AACA;AACA;AACA;AACA;EALE;IAAArH,GAAA;IAAAC,KAAA;MAAA,IAAAmI,cAAA,OAAA3F,kBAAA,CAAAlD,OAAA,gBAAAmD,YAAA,CAAAnD,OAAA,CAAAoD,IAAA,CAMA,SAAA0F,SAA4BxF,OAAgB;QAAA,IAAAyF,2BAAA;QAAA,OAAA5F,YAAA,CAAAnD,OAAA,CAAAyD,IAAA,UAAAuF,UAAAC,SAAA;UAAA,kBAAAA,SAAA,CAAArF,IAAA,GAAAqF,SAAA,CAAApF,IAAA;YAAA;cAAAoF,SAAA,CAAApF,IAAA;cAAA,OAGlCP,OAAO,CAAC4E,KAAK,CAACgB,QAAQ,CAACtJ,YAAY,CAACmJ,2BAA2B,CAAC,CAAC;YAAA;cAFnEA,2BAA2B,GAAAE,SAAA,CAAAjF,IAAA;cAAA,KAI7B+E,2BAA2B;gBAAAE,SAAA,CAAApF,IAAA;gBAAA;cAAA;cAC7BhD,oBAAW,CAACC,MAAM,CAACQ,IAAI,CACrB,2FACF,CAAC;cAAC,OAAA2H,SAAA,CAAAnF,MAAA,WAEKpE,uBAAuB,CAACE,YAAY;YAAA;cAAA,OAAAqJ,SAAA,CAAAnF,MAAA,WAGtCjB,SAAS;YAAA;YAAA;cAAA,OAAAoG,SAAA,CAAA3E,IAAA;UAAA;QAAA,GAAAwE,QAAA;MAAA,CACjB;MAAA,SAAA/E,cAAAoF,GAAA;QAAA,OAAAN,cAAA,CAAAnE,KAAA,OAAAC,SAAA;MAAA;MAAA,OAAAZ,aAAA;IAAA;IAED;AACF;AACA;AACA;AACA;AACA;IALE;EAAA;IAAAtD,GAAA;IAAAC,KAAA;MAAA,IAAA0I,UAAA,OAAAlG,kBAAA,CAAAlD,OAAA,gBAAAmD,YAAA,CAAAnD,OAAA,CAAAoD,IAAA,CAMA,SAAAiG,SAAgB/F,OAAO;QAAA,IAAAgG,UAAA;QAAA,OAAAnG,YAAA,CAAAnD,OAAA,CAAAyD,IAAA,UAAA8F,UAAAC,SAAA;UAAA,kBAAAA,SAAA,CAAA5F,IAAA,GAAA4F,SAAA,CAAA3F,IAAA;YAAA;cAAA2F,SAAA,CAAA3F,IAAA;cAAA,OACI,IAAI,CAACE,aAAa,CAACT,OAAO,CAAC;YAAA;cAA9CgG,UAAU,GAAAE,SAAA,CAAAxF,IAAA;cAAA,OAAAwF,SAAA,CAAA1F,MAAA,WAET,CAAC,CAACwF,UAAU;YAAA;YAAA;cAAA,OAAAE,SAAA,CAAAlF,IAAA;UAAA;QAAA,GAAA+E,QAAA;MAAA,CACpB;MAAA,SAAAI,UAAAC,GAAA;QAAA,OAAAN,UAAA,CAAA1E,KAAA,OAAAC,SAAA;MAAA;MAAA,OAAA8E,SAAA;IAAA;IAED;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;IAjBE;EAAA;IAAAhJ,GAAA;IAAAC,KAAA;MAAA,IAAAiJ,gBAAA,OAAAzG,kBAAA,CAAAlD,OAAA,gBAAAmD,YAAA,CAAAnD,OAAA,CAAAoD,IAAA,CAkBA,SAAAwG,SACEtG,OAAgB,EAChBgE,cAAwB,EACxB/D,QAAkB;QAAA,IAAAC,0BAAA,EAAAqG,mBAAA,EAAAC,qBAAA,EAAA/G,YAAA;QAAA,OAAAI,YAAA,CAAAnD,OAAA,CAAAyD,IAAA,UAAAsG,UAAAC,SAAA;UAAA,kBAAAA,SAAA,CAAApG,IAAA,GAAAoG,SAAA,CAAAnG,IAAA;YAAA;cAAA,IAIbN,QAAQ;gBAAAyG,SAAA,CAAAnG,IAAA;gBAAA;cAAA;cAAAmG,SAAA,CAAAnG,IAAA;cAAA,OACwB,IAAI,CAACE,aAAa,CAACT,OAAO,CAAC;YAAA;cAA9DE,0BAA0B,GAAAwG,SAAA,CAAAhG,IAAA;YAAA;cAAA,KAGxBR,0BAA0B;gBAAAwG,SAAA,CAAAnG,IAAA;gBAAA;cAAA;cAAA,OAAAmG,SAAA,CAAAlG,MAAA,WACrB;gBACL6B,cAAc,EAAE9C,SAAS;gBACzBW,0BAA0B,EAA1BA;cACF,CAAC;YAAA;cAAAwG,SAAA,CAAApG,IAAA;cAAAoG,SAAA,CAAAnG,IAAA;cAAA,OAIiC,IAAI,CAACwD,4BAA4B,CAAC/D,OAAO,EAAEgE,cAAc,CAAC;YAAA;cAAtFuC,mBAAmB,GAAAG,SAAA,CAAAhG,IAAA;cAAA,MAGvB6F,mBAAmB,CAACrG,0BAA0B,KAC9C9D,uBAAuB,CAACC,mBAAmB;gBAAAqK,SAAA,CAAAnG,IAAA;gBAAA;cAAA;cAAA,OAAAmG,SAAA,CAAAlG,MAAA,WAEpC+F,mBAAmB;YAAA;cAAAG,SAAA,CAAAnG,IAAA;cAAA,OAIC,IAAI,CAAClD,4BAA4B,CAAC,CAAC;YAAA;cAAAmJ,qBAAA,GAAAE,SAAA,CAAAhG,IAAA;cAAzDjB,YAAY,GAAA+G,qBAAA,CAAZ/G,YAAY;cAAA,KAEfA,YAAY;gBAAAiH,SAAA,CAAAnG,IAAA;gBAAA;cAAA;cAAAmG,SAAA,CAAAnG,IAAA;cAAA,OACR,IAAI,CAACsC,UAAU,CAAC7C,OAAO,CAAC;YAAA;cAGhC,IAAI,CAAC1C,KAAK,GAAGiC,SAAS;cAEtBhC,oBAAW,CAACC,MAAM,CAACQ,IAAI,CAAC,iEAAiE,CAAC;cAAC,OAAA0I,SAAA,CAAAlG,MAAA,WAEpF;gBAAC6B,cAAc,EAAE,IAAI,CAACvF,QAAQ;gBAAEoD,0BAA0B,EAAEX;cAAS,CAAC;YAAA;cAAAmH,SAAA,CAAApG,IAAA;cAAAoG,SAAA,CAAA5D,EAAA,GAAA4D,SAAA;cAAA,OAAAA,SAAA,CAAAlG,MAAA,WAEtE,IAAI,CAACc,0BAA0B,CAACtB,OAAO,EAAA0G,SAAA,CAAA5D,EAAG,CAAC;YAAA;YAAA;cAAA,OAAA4D,SAAA,CAAA1F,IAAA;UAAA;QAAA,GAAAsF,QAAA;MAAA,CAErD;MAAA,SAAAK,gBAAAC,GAAA,EAAAC,GAAA,EAAAC,IAAA;QAAA,OAAAT,gBAAA,CAAAjF,KAAA,OAAAC,SAAA;MAAA;MAAA,OAAAsF,eAAA;IAAA;EAAA;EAAA,OAAAnK,aAAA;AAAA"}
@@ -388,7 +388,7 @@ var StatsAnalyzer = exports.StatsAnalyzer = /*#__PURE__*/function (_EventsScope)
388
388
 
389
389
  // Add stats for individual streams
390
390
  (0, _keys.default)(this.statsResults).forEach(function (mediaType) {
391
- if (mediaType.includes('audio-send')) {
391
+ if (mediaType.startsWith('audio-send')) {
392
392
  var audioSenderStream = (0, _lodash.cloneDeep)(_config.emptyAudioTransmitStream);
393
393
  (0, _mqaUtil.getAudioSenderStreamMqa)({
394
394
  audioSenderStream: audioSenderStream,
@@ -398,7 +398,7 @@ var StatsAnalyzer = exports.StatsAnalyzer = /*#__PURE__*/function (_EventsScope)
398
398
  });
399
399
  newMqa.audioTransmit[0].streams.push(audioSenderStream);
400
400
  _this3.lastMqaDataSent[mediaType].send = (0, _lodash.cloneDeep)(_this3.statsResults[mediaType].send);
401
- } else if (mediaType.includes('audio-share-send')) {
401
+ } else if (mediaType.startsWith('audio-share-send')) {
402
402
  var _audioSenderStream = (0, _lodash.cloneDeep)(_config.emptyAudioTransmitStream);
403
403
  (0, _mqaUtil.getAudioSenderStreamMqa)({
404
404
  audioSenderStream: _audioSenderStream,
@@ -408,7 +408,7 @@ var StatsAnalyzer = exports.StatsAnalyzer = /*#__PURE__*/function (_EventsScope)
408
408
  });
409
409
  newMqa.audioTransmit[1].streams.push(_audioSenderStream);
410
410
  _this3.lastMqaDataSent[mediaType].send = (0, _lodash.cloneDeep)(_this3.statsResults[mediaType].send);
411
- } else if (mediaType.includes('audio-recv')) {
411
+ } else if (mediaType.startsWith('audio-recv')) {
412
412
  var audioReceiverStream = (0, _lodash.cloneDeep)(_config.emptyAudioReceiveStream);
413
413
  (0, _mqaUtil.getAudioReceiverStreamMqa)({
414
414
  audioReceiverStream: audioReceiverStream,
@@ -418,7 +418,7 @@ var StatsAnalyzer = exports.StatsAnalyzer = /*#__PURE__*/function (_EventsScope)
418
418
  });
419
419
  newMqa.audioReceive[0].streams.push(audioReceiverStream);
420
420
  _this3.lastMqaDataSent[mediaType].recv = (0, _lodash.cloneDeep)(_this3.statsResults[mediaType].recv);
421
- } else if (mediaType.includes('audio-share-recv')) {
421
+ } else if (mediaType.startsWith('audio-share-recv')) {
422
422
  var _audioReceiverStream = (0, _lodash.cloneDeep)(_config.emptyAudioReceiveStream);
423
423
  (0, _mqaUtil.getAudioReceiverStreamMqa)({
424
424
  audioReceiverStream: _audioReceiverStream,
@@ -428,7 +428,8 @@ var StatsAnalyzer = exports.StatsAnalyzer = /*#__PURE__*/function (_EventsScope)
428
428
  });
429
429
  newMqa.audioReceive[1].streams.push(_audioReceiverStream);
430
430
  _this3.lastMqaDataSent[mediaType].recv = (0, _lodash.cloneDeep)(_this3.statsResults[mediaType].recv);
431
- } else if (mediaType.includes('video-send')) {
431
+ } else if (mediaType.startsWith('video-send-layer')) {
432
+ // We only want the stream-specific stats we get with video-send-layer-0, video-send-layer-1, etc.
432
433
  var videoSenderStream = (0, _lodash.cloneDeep)(_config.emptyVideoTransmitStream);
433
434
  (0, _mqaUtil.getVideoSenderStreamMqa)({
434
435
  videoSenderStream: videoSenderStream,
@@ -438,7 +439,7 @@ var StatsAnalyzer = exports.StatsAnalyzer = /*#__PURE__*/function (_EventsScope)
438
439
  });
439
440
  newMqa.videoTransmit[0].streams.push(videoSenderStream);
440
441
  _this3.lastMqaDataSent[mediaType].send = (0, _lodash.cloneDeep)(_this3.statsResults[mediaType].send);
441
- } else if (mediaType.includes('video-share-send')) {
442
+ } else if (mediaType.startsWith('video-share-send')) {
442
443
  var _videoSenderStream = (0, _lodash.cloneDeep)(_config.emptyVideoTransmitStream);
443
444
  (0, _mqaUtil.getVideoSenderStreamMqa)({
444
445
  videoSenderStream: _videoSenderStream,
@@ -448,7 +449,7 @@ var StatsAnalyzer = exports.StatsAnalyzer = /*#__PURE__*/function (_EventsScope)
448
449
  });
449
450
  newMqa.videoTransmit[1].streams.push(_videoSenderStream);
450
451
  _this3.lastMqaDataSent[mediaType].send = (0, _lodash.cloneDeep)(_this3.statsResults[mediaType].send);
451
- } else if (mediaType.includes('video-recv')) {
452
+ } else if (mediaType.startsWith('video-recv')) {
452
453
  var videoReceiverStream = (0, _lodash.cloneDeep)(_config.emptyVideoReceiveStream);
453
454
  (0, _mqaUtil.getVideoReceiverStreamMqa)({
454
455
  videoReceiverStream: videoReceiverStream,
@@ -458,7 +459,7 @@ var StatsAnalyzer = exports.StatsAnalyzer = /*#__PURE__*/function (_EventsScope)
458
459
  });
459
460
  newMqa.videoReceive[0].streams.push(videoReceiverStream);
460
461
  _this3.lastMqaDataSent[mediaType].recv = (0, _lodash.cloneDeep)(_this3.statsResults[mediaType].recv);
461
- } else if (mediaType.includes('video-share-recv')) {
462
+ } else if (mediaType.startsWith('video-share-recv')) {
462
463
  var _videoReceiverStream = (0, _lodash.cloneDeep)(_config.emptyVideoReceiveStream);
463
464
  (0, _mqaUtil.getVideoReceiverStreamMqa)({
464
465
  videoReceiverStream: _videoReceiverStream,
@@ -483,9 +484,12 @@ var StatsAnalyzer = exports.StatsAnalyzer = /*#__PURE__*/function (_EventsScope)
483
484
  name: _constants.MEDIA_DEVICES.MICROPHONE
484
485
  });
485
486
  }
486
- if (this.statsResults['video-send']) {
487
+ var existingVideoSender = (0, _keys.default)(this.statsResults).find(function (item) {
488
+ return item.includes('video-send');
489
+ });
490
+ if (existingVideoSender) {
487
491
  newMqa.intervalMetadata.peripherals.push({
488
- information: this.statsResults['video-send'].trackLabel || _constants._UNKNOWN_,
492
+ information: this.statsResults[existingVideoSender].trackLabel || _constants._UNKNOWN_,
489
493
  name: _constants.MEDIA_DEVICES.CAMERA
490
494
  });
491
495
  }
@@ -659,9 +663,20 @@ var StatsAnalyzer = exports.StatsAnalyzer = /*#__PURE__*/function (_EventsScope)
659
663
  _this6.successfulCandidatePair = report;
660
664
  }
661
665
  });
666
+ var videoSenderIndex = 0;
662
667
  statsItem.report.forEach(function (result) {
663
668
  if (types.includes(result.type)) {
664
- _this6.parseGetStatsResult(result, type, isSender);
669
+ // if the video sender has multiple streams in the report, it is a new stream object.
670
+ if (type === 'video-send' && result.type === 'outbound-rtp') {
671
+ var newType = "video-send-layer-".concat(videoSenderIndex);
672
+ _this6.parseGetStatsResult(result, newType, isSender);
673
+ videoSenderIndex += 1;
674
+ _this6.statsResults[newType].direction = statsItem.currentDirection;
675
+ _this6.statsResults[newType].trackLabel = statsItem.localTrackLabel;
676
+ _this6.statsResults[newType].csi = statsItem.csi;
677
+ } else {
678
+ _this6.parseGetStatsResult(result, type, isSender);
679
+ }
665
680
  }
666
681
  });
667
682
  if (this.statsResults[type]) {
@@ -710,7 +725,7 @@ var StatsAnalyzer = exports.StatsAnalyzer = /*#__PURE__*/function (_EventsScope)
710
725
  return key.startsWith(keyPrefix);
711
726
  }).reduce(function (prev, cur) {
712
727
  var _this7$statsResults$c;
713
- return prev + (((_this7$statsResults$c = _this7.statsResults[cur]) === null || _this7$statsResults$c === void 0 ? void 0 : _this7$statsResults$c.recv[value]) || 0);
728
+ return prev + (((_this7$statsResults$c = _this7.statsResults[cur]) === null || _this7$statsResults$c === void 0 ? void 0 : _this7$statsResults$c[keyPrefix.includes('send') ? 'send' : 'recv'][value]) || 0);
714
729
  }, 0);
715
730
  };
716
731
  var getPreviousStatsTotals = function getPreviousStatsTotals(keyPrefix, value) {
@@ -718,7 +733,7 @@ var StatsAnalyzer = exports.StatsAnalyzer = /*#__PURE__*/function (_EventsScope)
718
733
  return key.startsWith(keyPrefix);
719
734
  }).reduce(function (prev, cur) {
720
735
  var _this7$lastStatsResul;
721
- return prev + (((_this7$lastStatsResul = _this7.lastStatsResults[cur]) === null || _this7$lastStatsResul === void 0 ? void 0 : _this7$lastStatsResul.recv[value]) || 0);
736
+ return prev + (((_this7$lastStatsResul = _this7.lastStatsResults[cur]) === null || _this7$lastStatsResul === void 0 ? void 0 : _this7$lastStatsResul[keyPrefix.includes('send') ? 'send' : 'recv'][value]) || 0);
722
737
  }, 0);
723
738
  };
724
739
 
@@ -745,23 +760,31 @@ var StatsAnalyzer = exports.StatsAnalyzer = /*#__PURE__*/function (_EventsScope)
745
760
  var currentAudioPacketsReceived = getCurrentStatsTotals('audio-recv', 'totalPacketsReceived');
746
761
  var previousAudioPacketsReceived = getPreviousStatsTotals('audio-recv', 'totalPacketsReceived');
747
762
  this.emitStartStopEvents('audio', previousAudioPacketsReceived, currentAudioPacketsReceived, false);
763
+ var currentTotalPacketsSent = getCurrentStatsTotals('video-send', 'totalPacketsSent');
764
+ var previousTotalPacketsSent = getPreviousStatsTotals('video-send', 'totalPacketsSent');
765
+ var currentFramesEncoded = getCurrentStatsTotals('video-send', 'framesEncoded');
766
+ var previousFramesEncoded = getPreviousStatsTotals('video-send', 'framesEncoded');
767
+ var currentFramesSent = getCurrentStatsTotals('video-send', 'framesSent');
768
+ var previousFramesSent = getPreviousStatsTotals('video-send', 'framesSent');
769
+ var doesVideoSendExist = (0, _keys.default)(this.lastStatsResults).some(function (item) {
770
+ return item.includes('video-send');
771
+ });
748
772
 
749
773
  // Video Transmit
750
- if (this.lastStatsResults['video-send']) {
774
+ if (doesVideoSendExist) {
751
775
  // compare video stats sent
752
- var _currentStats = this.statsResults['video-send'].send;
753
- var _previousStats = this.lastStatsResults['video-send'].send;
754
- if (this.meetingMediaStatus.expected.sendVideo && (_currentStats.totalPacketsSent === _previousStats.totalPacketsSent || _currentStats.totalPacketsSent === 0)) {
755
- _loggerProxy.default.logger.info("StatsAnalyzer:index#compareLastStatsResult --> No video RTP packets sent", _currentStats.totalPacketsSent);
776
+
777
+ if (this.meetingMediaStatus.expected.sendVideo && (currentTotalPacketsSent === previousTotalPacketsSent || currentTotalPacketsSent === 0)) {
778
+ _loggerProxy.default.logger.info("StatsAnalyzer:index#compareLastStatsResult --> No video RTP packets sent", currentTotalPacketsSent);
756
779
  } else {
757
- if (this.meetingMediaStatus.expected.sendVideo && (_currentStats.framesEncoded === _previousStats.framesEncoded || _currentStats.framesEncoded === 0)) {
758
- _loggerProxy.default.logger.info("StatsAnalyzer:index#compareLastStatsResult --> No video Frames Encoded", _currentStats.framesEncoded);
780
+ if (this.meetingMediaStatus.expected.sendVideo && (currentFramesEncoded === previousFramesEncoded || currentFramesEncoded === 0)) {
781
+ _loggerProxy.default.logger.info("StatsAnalyzer:index#compareLastStatsResult --> No video Frames Encoded", currentFramesEncoded);
759
782
  }
760
- if (this.meetingMediaStatus.expected.sendVideo && (this.statsResults['video-send'].send.framesSent === this.lastStatsResults['video-send'].send.framesSent || this.statsResults['video-send'].send.framesSent === 0)) {
761
- _loggerProxy.default.logger.info("StatsAnalyzer:index#compareLastStatsResult --> No video Frames sent", this.statsResults['video-send'].send.framesSent);
783
+ if (this.meetingMediaStatus.expected.sendVideo && (currentFramesSent === previousFramesSent || currentFramesSent === 0)) {
784
+ _loggerProxy.default.logger.info("StatsAnalyzer:index#compareLastStatsResult --> No video Frames sent", currentFramesSent);
762
785
  }
763
786
  }
764
- this.emitStartStopEvents('video', _previousStats.framesSent, _currentStats.framesSent, true);
787
+ this.emitStartStopEvents('video', previousFramesSent, currentFramesSent, true);
765
788
  }
766
789
 
767
790
  // Video Receive
@@ -773,19 +796,19 @@ var StatsAnalyzer = exports.StatsAnalyzer = /*#__PURE__*/function (_EventsScope)
773
796
  if (this.lastStatsResults['video-share-send']) {
774
797
  // compare share stats sent
775
798
 
776
- var _currentStats2 = this.statsResults['video-share-send'].send;
777
- var _previousStats2 = this.lastStatsResults['video-share-send'].send;
778
- if (this.meetingMediaStatus.expected.sendShare && (_currentStats2.totalPacketsSent === _previousStats2.totalPacketsSent || _currentStats2.totalPacketsSent === 0)) {
779
- _loggerProxy.default.logger.info("StatsAnalyzer:index#compareLastStatsResult --> No share RTP packets sent", _currentStats2.totalPacketsSent);
799
+ var _currentStats = this.statsResults['video-share-send'].send;
800
+ var _previousStats = this.lastStatsResults['video-share-send'].send;
801
+ if (this.meetingMediaStatus.expected.sendShare && (_currentStats.totalPacketsSent === _previousStats.totalPacketsSent || _currentStats.totalPacketsSent === 0)) {
802
+ _loggerProxy.default.logger.info("StatsAnalyzer:index#compareLastStatsResult --> No share RTP packets sent", _currentStats.totalPacketsSent);
780
803
  } else {
781
- if (this.meetingMediaStatus.expected.sendShare && (_currentStats2.framesEncoded === _previousStats2.framesEncoded || _currentStats2.framesEncoded === 0)) {
782
- _loggerProxy.default.logger.info("StatsAnalyzer:index#compareLastStatsResult --> No share frames getting encoded", _currentStats2.framesEncoded);
804
+ if (this.meetingMediaStatus.expected.sendShare && (_currentStats.framesEncoded === _previousStats.framesEncoded || _currentStats.framesEncoded === 0)) {
805
+ _loggerProxy.default.logger.info("StatsAnalyzer:index#compareLastStatsResult --> No share frames getting encoded", _currentStats.framesEncoded);
783
806
  }
784
807
  if (this.meetingMediaStatus.expected.sendShare && (this.statsResults['video-share-send'].send.framesSent === this.lastStatsResults['video-share-send'].send.framesSent || this.statsResults['video-share-send'].send.framesSent === 0)) {
785
808
  _loggerProxy.default.logger.info("StatsAnalyzer:index#compareLastStatsResult --> No share frames sent", this.statsResults['video-share-send'].send.framesSent);
786
809
  }
787
810
  }
788
- this.emitStartStopEvents('share', _previousStats2.framesSent, _currentStats2.framesSent, true);
811
+ this.emitStartStopEvents('share', _previousStats.framesSent, _currentStats.framesSent, true);
789
812
  }
790
813
 
791
814
  // Share receive