@webex/plugin-meetings 3.0.0-stream-classes.4 → 3.0.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 (469) hide show
  1. package/.eslintrc.js +6 -0
  2. package/README.md +12 -0
  3. package/babel.config.js +3 -0
  4. package/dist/annotation/constants.js +12 -20
  5. package/dist/annotation/constants.js.map +1 -1
  6. package/dist/annotation/index.js +25 -10
  7. package/dist/annotation/index.js.map +1 -1
  8. package/dist/breakouts/breakout.js +2 -3
  9. package/dist/breakouts/breakout.js.map +1 -1
  10. package/dist/breakouts/collection.js +1 -2
  11. package/dist/breakouts/collection.js.map +1 -1
  12. package/dist/breakouts/edit-lock-error.js +1 -2
  13. package/dist/breakouts/edit-lock-error.js.map +1 -1
  14. package/dist/breakouts/events.js +1 -2
  15. package/dist/breakouts/events.js.map +1 -1
  16. package/dist/breakouts/index.js +13 -14
  17. package/dist/breakouts/index.js.map +1 -1
  18. package/dist/breakouts/request.js +1 -2
  19. package/dist/breakouts/request.js.map +1 -1
  20. package/dist/breakouts/utils.js +3 -6
  21. package/dist/breakouts/utils.js.map +1 -1
  22. package/dist/common/browser-detection.js +2 -3
  23. package/dist/common/browser-detection.js.map +1 -1
  24. package/dist/common/collection.js +3 -4
  25. package/dist/common/collection.js.map +1 -1
  26. package/dist/common/config.js +1 -2
  27. package/dist/common/config.js.map +1 -1
  28. package/dist/common/errors/captcha-error.js +1 -2
  29. package/dist/common/errors/captcha-error.js.map +1 -1
  30. package/dist/common/errors/intent-to-join.js +1 -2
  31. package/dist/common/errors/intent-to-join.js.map +1 -1
  32. package/dist/common/errors/join-meeting.js +1 -2
  33. package/dist/common/errors/join-meeting.js.map +1 -1
  34. package/dist/common/errors/media.js +1 -2
  35. package/dist/common/errors/media.js.map +1 -1
  36. package/dist/common/errors/no-meeting-info.d.ts +14 -0
  37. package/dist/common/errors/no-meeting-info.js +50 -0
  38. package/dist/common/errors/no-meeting-info.js.map +1 -0
  39. package/dist/common/errors/parameter.js +3 -4
  40. package/dist/common/errors/parameter.js.map +1 -1
  41. package/dist/common/errors/password-error.js +1 -2
  42. package/dist/common/errors/password-error.js.map +1 -1
  43. package/dist/common/errors/permission.js +1 -2
  44. package/dist/common/errors/permission.js.map +1 -1
  45. package/dist/common/errors/reclaim-host-role-errors.d.ts +60 -0
  46. package/dist/common/errors/reclaim-host-role-errors.js +154 -0
  47. package/dist/common/errors/reclaim-host-role-errors.js.map +1 -0
  48. package/dist/common/errors/reconnection-in-progress.js +1 -2
  49. package/dist/common/errors/reconnection-in-progress.js.map +1 -1
  50. package/dist/common/errors/reconnection.js +1 -2
  51. package/dist/common/errors/reconnection.js.map +1 -1
  52. package/dist/common/errors/stats.js +1 -2
  53. package/dist/common/errors/stats.js.map +1 -1
  54. package/dist/{types/common → common}/errors/webex-errors.d.ts +13 -1
  55. package/dist/common/errors/webex-errors.js +35 -16
  56. package/dist/common/errors/webex-errors.js.map +1 -1
  57. package/dist/common/errors/webex-meetings-error.js +1 -2
  58. package/dist/common/errors/webex-meetings-error.js.map +1 -1
  59. package/dist/common/events/events-scope.js +1 -2
  60. package/dist/common/events/events-scope.js.map +1 -1
  61. package/dist/common/events/events.js +1 -2
  62. package/dist/common/events/events.js.map +1 -1
  63. package/dist/common/events/trigger-proxy.js +1 -2
  64. package/dist/common/events/trigger-proxy.js.map +1 -1
  65. package/dist/common/events/util.js +1 -2
  66. package/dist/common/events/util.js.map +1 -1
  67. package/dist/common/logs/logger-config.js +1 -2
  68. package/dist/common/logs/logger-config.js.map +1 -1
  69. package/dist/common/logs/logger-proxy.js +1 -2
  70. package/dist/common/logs/logger-proxy.js.map +1 -1
  71. package/dist/{types/common → common}/logs/request.d.ts +3 -1
  72. package/dist/common/logs/request.js +8 -5
  73. package/dist/common/logs/request.js.map +1 -1
  74. package/dist/common/queue.js +2 -4
  75. package/dist/common/queue.js.map +1 -1
  76. package/dist/{types/config.d.ts → config.d.ts} +1 -1
  77. package/dist/config.js +3 -3
  78. package/dist/config.js.map +1 -1
  79. package/dist/{types/constants.d.ts → constants.d.ts} +72 -15
  80. package/dist/constants.js +254 -371
  81. package/dist/constants.js.map +1 -1
  82. package/dist/controls-options-manager/constants.js +3 -6
  83. package/dist/controls-options-manager/constants.js.map +1 -1
  84. package/dist/controls-options-manager/enums.js +7 -10
  85. package/dist/controls-options-manager/enums.js.map +1 -1
  86. package/dist/controls-options-manager/index.js +27 -32
  87. package/dist/controls-options-manager/index.js.map +1 -1
  88. package/dist/controls-options-manager/util.js +1 -2
  89. package/dist/controls-options-manager/util.js.map +1 -1
  90. package/dist/index.js +8 -5
  91. package/dist/index.js.map +1 -1
  92. package/dist/interceptors/index.d.ts +2 -0
  93. package/dist/interceptors/index.js +15 -0
  94. package/dist/interceptors/index.js.map +1 -0
  95. package/dist/interceptors/locusRetry.d.ts +27 -0
  96. package/dist/interceptors/locusRetry.js +94 -0
  97. package/dist/interceptors/locusRetry.js.map +1 -0
  98. package/dist/interpretation/collection.js +1 -2
  99. package/dist/interpretation/collection.js.map +1 -1
  100. package/dist/interpretation/index.js +2 -3
  101. package/dist/interpretation/index.js.map +1 -1
  102. package/dist/interpretation/siLanguage.js +2 -3
  103. package/dist/interpretation/siLanguage.js.map +1 -1
  104. package/dist/locus-info/controlsUtils.js +12 -13
  105. package/dist/locus-info/controlsUtils.js.map +1 -1
  106. package/dist/locus-info/embeddedAppsUtils.js +3 -4
  107. package/dist/locus-info/embeddedAppsUtils.js.map +1 -1
  108. package/dist/locus-info/fullState.js +1 -2
  109. package/dist/locus-info/fullState.js.map +1 -1
  110. package/dist/locus-info/hostUtils.js +1 -2
  111. package/dist/locus-info/hostUtils.js.map +1 -1
  112. package/dist/{types/locus-info → locus-info}/index.d.ts +1 -1
  113. package/dist/locus-info/index.js +63 -38
  114. package/dist/locus-info/index.js.map +1 -1
  115. package/dist/locus-info/infoUtils.js +3 -4
  116. package/dist/locus-info/infoUtils.js.map +1 -1
  117. package/dist/locus-info/mediaSharesUtils.js +16 -3
  118. package/dist/locus-info/mediaSharesUtils.js.map +1 -1
  119. package/dist/{types/locus-info → locus-info}/parser.d.ts +3 -2
  120. package/dist/locus-info/parser.js +48 -31
  121. package/dist/locus-info/parser.js.map +1 -1
  122. package/dist/locus-info/selfUtils.js +7 -6
  123. package/dist/locus-info/selfUtils.js.map +1 -1
  124. package/dist/media/index.js +15 -10
  125. package/dist/media/index.js.map +1 -1
  126. package/dist/media/properties.js +16 -7
  127. package/dist/media/properties.js.map +1 -1
  128. package/dist/media/util.js +1 -2
  129. package/dist/media/util.js.map +1 -1
  130. package/dist/mediaQualityMetrics/config.d.ts +241 -0
  131. package/dist/mediaQualityMetrics/config.js +135 -339
  132. package/dist/mediaQualityMetrics/config.js.map +1 -1
  133. package/dist/{types/meeting → meeting}/in-meeting-actions.d.ts +4 -0
  134. package/dist/meeting/in-meeting-actions.js +18 -2
  135. package/dist/meeting/in-meeting-actions.js.map +1 -1
  136. package/dist/{types/meeting → meeting}/index.d.ts +331 -44
  137. package/dist/meeting/index.js +2639 -1367
  138. package/dist/meeting/index.js.map +1 -1
  139. package/dist/{types/meeting → meeting}/locusMediaRequest.d.ts +1 -2
  140. package/dist/meeting/locusMediaRequest.js +4 -5
  141. package/dist/meeting/locusMediaRequest.js.map +1 -1
  142. package/dist/meeting/muteState.js +2 -4
  143. package/dist/meeting/muteState.js.map +1 -1
  144. package/dist/{types/meeting → meeting}/request.d.ts +4 -1
  145. package/dist/meeting/request.js +47 -32
  146. package/dist/meeting/request.js.map +1 -1
  147. package/dist/meeting/state.js +1 -2
  148. package/dist/meeting/state.js.map +1 -1
  149. package/dist/{types/meeting → meeting}/util.d.ts +26 -1
  150. package/dist/meeting/util.js +83 -10
  151. package/dist/meeting/util.js.map +1 -1
  152. package/dist/meeting/voicea-meeting.d.ts +16 -0
  153. package/dist/meeting/voicea-meeting.js +169 -0
  154. package/dist/meeting/voicea-meeting.js.map +1 -0
  155. package/dist/meeting-info/collection.js +3 -4
  156. package/dist/meeting-info/collection.js.map +1 -1
  157. package/dist/{types/meeting-info → meeting-info}/index.d.ts +7 -0
  158. package/dist/meeting-info/index.js +53 -27
  159. package/dist/meeting-info/index.js.map +1 -1
  160. package/dist/{types/meeting-info → meeting-info}/meeting-info-v2.d.ts +1 -0
  161. package/dist/meeting-info/meeting-info-v2.js +52 -33
  162. package/dist/meeting-info/meeting-info-v2.js.map +1 -1
  163. package/dist/meeting-info/request.js +1 -2
  164. package/dist/meeting-info/request.js.map +1 -1
  165. package/dist/meeting-info/util.js +8 -8
  166. package/dist/meeting-info/util.js.map +1 -1
  167. package/dist/meeting-info/utilv2.js +12 -9
  168. package/dist/meeting-info/utilv2.js.map +1 -1
  169. package/dist/{types/meetings → meetings}/collection.d.ts +9 -0
  170. package/dist/meetings/collection.js +21 -5
  171. package/dist/meetings/collection.js.map +1 -1
  172. package/dist/{types/meetings → meetings}/index.d.ts +45 -16
  173. package/dist/meetings/index.js +166 -74
  174. package/dist/meetings/index.js.map +1 -1
  175. package/dist/meetings/request.js +2 -3
  176. package/dist/meetings/request.js.map +1 -1
  177. package/dist/meetings/util.js +3 -10
  178. package/dist/meetings/util.js.map +1 -1
  179. package/dist/{types/member → member}/index.d.ts +1 -0
  180. package/dist/member/index.js +10 -3
  181. package/dist/member/index.js.map +1 -1
  182. package/dist/member/member.types.d.ts +11 -0
  183. package/dist/member/member.types.js +17 -0
  184. package/dist/member/member.types.js.map +1 -0
  185. package/dist/member/types.js +6 -8
  186. package/dist/member/types.js.map +1 -1
  187. package/dist/member/util.js +12 -2
  188. package/dist/member/util.js.map +1 -1
  189. package/dist/members/collection.js +1 -2
  190. package/dist/members/collection.js.map +1 -1
  191. package/dist/members/index.js +25 -8
  192. package/dist/members/index.js.map +1 -1
  193. package/dist/members/request.js +2 -3
  194. package/dist/members/request.js.map +1 -1
  195. package/dist/{types/members → members}/types.d.ts +1 -0
  196. package/dist/members/types.js +3 -4
  197. package/dist/members/types.js.map +1 -1
  198. package/dist/{types/members → members}/util.d.ts +6 -1
  199. package/dist/members/util.js +18 -8
  200. package/dist/members/util.js.map +1 -1
  201. package/dist/{types/metrics → metrics}/constants.d.ts +15 -0
  202. package/dist/metrics/constants.js +16 -3
  203. package/dist/metrics/constants.js.map +1 -1
  204. package/dist/metrics/index.js +3 -2
  205. package/dist/metrics/index.js.map +1 -1
  206. package/dist/multistream/mediaRequestManager.js +9 -11
  207. package/dist/multistream/mediaRequestManager.js.map +1 -1
  208. package/dist/multistream/receiveSlot.js +3 -5
  209. package/dist/multistream/receiveSlot.js.map +1 -1
  210. package/dist/multistream/receiveSlotManager.js +7 -9
  211. package/dist/multistream/receiveSlotManager.js.map +1 -1
  212. package/dist/multistream/remoteMedia.js +3 -5
  213. package/dist/multistream/remoteMedia.js.map +1 -1
  214. package/dist/multistream/remoteMediaGroup.js +7 -6
  215. package/dist/multistream/remoteMediaGroup.js.map +1 -1
  216. package/dist/{types/multistream → multistream}/remoteMediaManager.d.ts +9 -1
  217. package/dist/multistream/remoteMediaManager.js +74 -36
  218. package/dist/multistream/remoteMediaManager.js.map +1 -1
  219. package/dist/multistream/sendSlotManager.js +9 -6
  220. package/dist/multistream/sendSlotManager.js.map +1 -1
  221. package/dist/networkQualityMonitor/index.js +1 -2
  222. package/dist/networkQualityMonitor/index.js.map +1 -1
  223. package/dist/personal-meeting-room/index.js +2 -3
  224. package/dist/personal-meeting-room/index.js.map +1 -1
  225. package/dist/personal-meeting-room/request.js +2 -3
  226. package/dist/personal-meeting-room/request.js.map +1 -1
  227. package/dist/personal-meeting-room/util.js +1 -2
  228. package/dist/personal-meeting-room/util.js.map +1 -1
  229. package/dist/reachability/clusterReachability.d.ts +109 -0
  230. package/dist/reachability/clusterReachability.js +357 -0
  231. package/dist/reachability/clusterReachability.js.map +1 -0
  232. package/dist/reachability/index.d.ts +105 -0
  233. package/dist/reachability/index.js +279 -436
  234. package/dist/reachability/index.js.map +1 -1
  235. package/dist/{types/reachability → reachability}/request.d.ts +1 -1
  236. package/dist/reachability/request.js +14 -11
  237. package/dist/reachability/request.js.map +1 -1
  238. package/dist/reachability/util.d.ts +8 -0
  239. package/dist/reachability/util.js +29 -0
  240. package/dist/reachability/util.js.map +1 -0
  241. package/dist/reactions/constants.js +1 -2
  242. package/dist/reactions/constants.js.map +1 -1
  243. package/dist/reactions/reactions.js +2 -4
  244. package/dist/reactions/reactions.js.map +1 -1
  245. package/dist/reactions/reactions.type.js +6 -8
  246. package/dist/reactions/reactions.type.js.map +1 -1
  247. package/dist/{types/reconnection-manager → reconnection-manager}/index.d.ts +10 -0
  248. package/dist/reconnection-manager/index.js +129 -106
  249. package/dist/reconnection-manager/index.js.map +1 -1
  250. package/dist/recording-controller/enums.js +4 -5
  251. package/dist/recording-controller/enums.js.map +1 -1
  252. package/dist/recording-controller/index.js +43 -51
  253. package/dist/recording-controller/index.js.map +1 -1
  254. package/dist/recording-controller/util.js +1 -2
  255. package/dist/recording-controller/util.js.map +1 -1
  256. package/dist/{types/roap → roap}/index.d.ts +2 -1
  257. package/dist/roap/index.js +59 -28
  258. package/dist/roap/index.js.map +1 -1
  259. package/dist/{types/roap → roap}/request.d.ts +2 -1
  260. package/dist/roap/request.js +14 -22
  261. package/dist/roap/request.js.map +1 -1
  262. package/dist/{types/roap → roap}/turnDiscovery.d.ts +21 -4
  263. package/dist/roap/turnDiscovery.js +182 -89
  264. package/dist/roap/turnDiscovery.js.map +1 -1
  265. package/dist/rtcMetrics/constants.js +1 -2
  266. package/dist/rtcMetrics/constants.js.map +1 -1
  267. package/dist/{types/rtcMetrics → rtcMetrics}/index.d.ts +15 -1
  268. package/dist/rtcMetrics/index.js +72 -12
  269. package/dist/rtcMetrics/index.js.map +1 -1
  270. package/dist/statsAnalyzer/global.js +1 -2
  271. package/dist/statsAnalyzer/global.js.map +1 -1
  272. package/dist/{types/statsAnalyzer → statsAnalyzer}/index.d.ts +28 -11
  273. package/dist/statsAnalyzer/index.js +371 -318
  274. package/dist/statsAnalyzer/index.js.map +1 -1
  275. package/dist/statsAnalyzer/mqaUtil.d.ts +48 -0
  276. package/dist/statsAnalyzer/mqaUtil.js +295 -162
  277. package/dist/statsAnalyzer/mqaUtil.js.map +1 -1
  278. package/dist/transcription/index.js +1 -2
  279. package/dist/transcription/index.js.map +1 -1
  280. package/dist/webinar/collection.d.ts +16 -0
  281. package/dist/webinar/collection.js +43 -0
  282. package/dist/webinar/collection.js.map +1 -0
  283. package/dist/webinar/index.d.ts +5 -0
  284. package/dist/webinar/index.js +68 -0
  285. package/dist/webinar/index.js.map +1 -0
  286. package/jest.config.js +3 -0
  287. package/package.json +44 -24
  288. package/process +1 -0
  289. package/src/common/errors/no-meeting-info.ts +24 -0
  290. package/src/common/errors/reclaim-host-role-errors.ts +134 -0
  291. package/src/common/errors/webex-errors.ts +19 -2
  292. package/src/common/logs/request.ts +5 -1
  293. package/src/config.ts +3 -5
  294. package/src/constants.ts +78 -8
  295. package/src/index.ts +4 -0
  296. package/src/interceptors/index.ts +3 -0
  297. package/src/interceptors/locusRetry.ts +67 -0
  298. package/src/locus-info/index.ts +52 -16
  299. package/src/locus-info/mediaSharesUtils.ts +16 -0
  300. package/src/locus-info/parser.ts +47 -21
  301. package/src/media/index.ts +8 -6
  302. package/src/media/properties.ts +17 -2
  303. package/src/mediaQualityMetrics/config.ts +103 -238
  304. package/src/meeting/in-meeting-actions.ts +8 -0
  305. package/src/meeting/index.ts +1692 -627
  306. package/src/meeting/request.ts +19 -1
  307. package/src/meeting/util.ts +102 -1
  308. package/src/meeting/voicea-meeting.ts +122 -0
  309. package/src/meeting-info/index.ts +47 -20
  310. package/src/meeting-info/meeting-info-v2.ts +32 -16
  311. package/src/meeting-info/util.ts +12 -9
  312. package/src/meeting-info/utilv2.ts +25 -15
  313. package/src/meetings/collection.ts +13 -0
  314. package/src/meetings/index.ts +112 -31
  315. package/src/meetings/util.ts +2 -8
  316. package/src/member/index.ts +9 -1
  317. package/src/member/member.types.ts +13 -0
  318. package/src/member/util.ts +14 -0
  319. package/src/members/index.ts +29 -2
  320. package/src/members/types.ts +1 -0
  321. package/src/members/util.ts +15 -1
  322. package/src/metrics/constants.ts +14 -0
  323. package/src/multistream/remoteMediaManager.ts +41 -4
  324. package/src/reachability/clusterReachability.ts +320 -0
  325. package/src/reachability/index.ts +221 -382
  326. package/src/reachability/request.ts +1 -1
  327. package/src/reachability/util.ts +24 -0
  328. package/src/reconnection-manager/index.ts +87 -83
  329. package/src/roap/index.ts +60 -24
  330. package/src/roap/request.ts +4 -17
  331. package/src/roap/turnDiscovery.ts +112 -39
  332. package/src/rtcMetrics/index.ts +71 -5
  333. package/src/statsAnalyzer/index.ts +430 -427
  334. package/src/statsAnalyzer/mqaUtil.ts +317 -168
  335. package/src/webinar/collection.ts +31 -0
  336. package/src/webinar/index.ts +62 -0
  337. package/test/integration/spec/converged-space-meetings.js +7 -7
  338. package/test/integration/spec/journey.js +88 -106
  339. package/test/integration/spec/space-meeting.js +10 -10
  340. package/test/unit/spec/breakouts/breakout.ts +2 -1
  341. package/test/unit/spec/breakouts/index.ts +7 -4
  342. package/test/unit/spec/interceptors/locusRetry.ts +131 -0
  343. package/test/unit/spec/locus-info/index.js +206 -13
  344. package/test/unit/spec/locus-info/lib/SeqCmp.json +16 -0
  345. package/test/unit/spec/locus-info/mediaSharesUtils.ts +10 -0
  346. package/test/unit/spec/locus-info/parser.js +54 -13
  347. package/test/unit/spec/locus-info/selfUtils.js +1 -1
  348. package/test/unit/spec/media/index.ts +25 -4
  349. package/test/unit/spec/media/properties.ts +2 -2
  350. package/test/unit/spec/meeting/in-meeting-actions.ts +4 -0
  351. package/test/unit/spec/meeting/index.js +4354 -1285
  352. package/test/unit/spec/meeting/request.js +63 -12
  353. package/test/unit/spec/meeting/utils.js +145 -10
  354. package/test/unit/spec/meeting/voicea-meeting.ts +266 -0
  355. package/test/unit/spec/meeting-info/index.js +180 -61
  356. package/test/unit/spec/meeting-info/meetinginfov2.js +216 -68
  357. package/test/unit/spec/meetings/collection.js +12 -0
  358. package/test/unit/spec/meetings/index.js +676 -195
  359. package/test/unit/spec/meetings/utils.js +35 -12
  360. package/test/unit/spec/member/index.js +8 -7
  361. package/test/unit/spec/member/util.js +32 -0
  362. package/test/unit/spec/members/index.js +130 -17
  363. package/test/unit/spec/members/utils.js +26 -0
  364. package/test/unit/spec/metrics/index.js +1 -2
  365. package/test/unit/spec/multistream/mediaRequestManager.ts +1 -0
  366. package/test/unit/spec/multistream/remoteMediaManager.ts +10 -2
  367. package/test/unit/spec/reachability/clusterReachability.ts +279 -0
  368. package/test/unit/spec/reachability/index.ts +505 -135
  369. package/test/unit/spec/reachability/util.ts +40 -0
  370. package/test/unit/spec/reconnection-manager/index.js +74 -17
  371. package/test/unit/spec/recording-controller/index.js +0 -1
  372. package/test/unit/spec/roap/index.ts +181 -61
  373. package/test/unit/spec/roap/request.ts +27 -3
  374. package/test/unit/spec/roap/turnDiscovery.ts +363 -102
  375. package/test/unit/spec/rtcMetrics/index.ts +57 -3
  376. package/test/unit/spec/stats-analyzer/index.js +1225 -12
  377. package/test/unit/spec/webinar/collection.ts +13 -0
  378. package/test/unit/spec/webinar/index.ts +60 -0
  379. package/test/utils/integrationTestUtils.js +4 -4
  380. package/test/utils/webex-test-users.js +12 -4
  381. package/dist/types/mediaQualityMetrics/config.d.ts +0 -365
  382. package/dist/types/reachability/index.d.ts +0 -158
  383. package/dist/types/statsAnalyzer/mqaUtil.d.ts +0 -24
  384. /package/dist/{types/annotation → annotation}/annotation.types.d.ts +0 -0
  385. /package/dist/{types/annotation → annotation}/constants.d.ts +0 -0
  386. /package/dist/{types/annotation → annotation}/index.d.ts +0 -0
  387. /package/dist/{types/breakouts → breakouts}/breakout.d.ts +0 -0
  388. /package/dist/{types/breakouts → breakouts}/collection.d.ts +0 -0
  389. /package/dist/{types/breakouts → breakouts}/edit-lock-error.d.ts +0 -0
  390. /package/dist/{types/breakouts → breakouts}/events.d.ts +0 -0
  391. /package/dist/{types/breakouts → breakouts}/index.d.ts +0 -0
  392. /package/dist/{types/breakouts → breakouts}/request.d.ts +0 -0
  393. /package/dist/{types/breakouts → breakouts}/utils.d.ts +0 -0
  394. /package/dist/{types/common → common}/browser-detection.d.ts +0 -0
  395. /package/dist/{types/common → common}/collection.d.ts +0 -0
  396. /package/dist/{types/common → common}/config.d.ts +0 -0
  397. /package/dist/{types/common → common}/errors/captcha-error.d.ts +0 -0
  398. /package/dist/{types/common → common}/errors/intent-to-join.d.ts +0 -0
  399. /package/dist/{types/common → common}/errors/join-meeting.d.ts +0 -0
  400. /package/dist/{types/common → common}/errors/media.d.ts +0 -0
  401. /package/dist/{types/common → common}/errors/parameter.d.ts +0 -0
  402. /package/dist/{types/common → common}/errors/password-error.d.ts +0 -0
  403. /package/dist/{types/common → common}/errors/permission.d.ts +0 -0
  404. /package/dist/{types/common → common}/errors/reconnection-in-progress.d.ts +0 -0
  405. /package/dist/{types/common → common}/errors/reconnection.d.ts +0 -0
  406. /package/dist/{types/common → common}/errors/stats.d.ts +0 -0
  407. /package/dist/{types/common → common}/errors/webex-meetings-error.d.ts +0 -0
  408. /package/dist/{types/common → common}/events/events-scope.d.ts +0 -0
  409. /package/dist/{types/common → common}/events/events.d.ts +0 -0
  410. /package/dist/{types/common → common}/events/trigger-proxy.d.ts +0 -0
  411. /package/dist/{types/common → common}/events/util.d.ts +0 -0
  412. /package/dist/{types/common → common}/logs/logger-config.d.ts +0 -0
  413. /package/dist/{types/common → common}/logs/logger-proxy.d.ts +0 -0
  414. /package/dist/{types/common → common}/queue.d.ts +0 -0
  415. /package/dist/{types/controls-options-manager → controls-options-manager}/constants.d.ts +0 -0
  416. /package/dist/{types/controls-options-manager → controls-options-manager}/enums.d.ts +0 -0
  417. /package/dist/{types/controls-options-manager → controls-options-manager}/index.d.ts +0 -0
  418. /package/dist/{types/controls-options-manager → controls-options-manager}/types.d.ts +0 -0
  419. /package/dist/{types/controls-options-manager → controls-options-manager}/util.d.ts +0 -0
  420. /package/dist/{types/index.d.ts → index.d.ts} +0 -0
  421. /package/dist/{types/interpretation → interpretation}/collection.d.ts +0 -0
  422. /package/dist/{types/interpretation → interpretation}/index.d.ts +0 -0
  423. /package/dist/{types/interpretation → interpretation}/siLanguage.d.ts +0 -0
  424. /package/dist/{types/locus-info → locus-info}/controlsUtils.d.ts +0 -0
  425. /package/dist/{types/locus-info → locus-info}/embeddedAppsUtils.d.ts +0 -0
  426. /package/dist/{types/locus-info → locus-info}/fullState.d.ts +0 -0
  427. /package/dist/{types/locus-info → locus-info}/hostUtils.d.ts +0 -0
  428. /package/dist/{types/locus-info → locus-info}/infoUtils.d.ts +0 -0
  429. /package/dist/{types/locus-info → locus-info}/mediaSharesUtils.d.ts +0 -0
  430. /package/dist/{types/locus-info → locus-info}/selfUtils.d.ts +0 -0
  431. /package/dist/{types/media → media}/index.d.ts +0 -0
  432. /package/dist/{types/media → media}/properties.d.ts +0 -0
  433. /package/dist/{types/media → media}/util.d.ts +0 -0
  434. /package/dist/{types/meeting → meeting}/muteState.d.ts +0 -0
  435. /package/dist/{types/meeting → meeting}/request.type.d.ts +0 -0
  436. /package/dist/{types/meeting → meeting}/state.d.ts +0 -0
  437. /package/dist/{types/meeting-info → meeting-info}/collection.d.ts +0 -0
  438. /package/dist/{types/meeting-info → meeting-info}/request.d.ts +0 -0
  439. /package/dist/{types/meeting-info → meeting-info}/util.d.ts +0 -0
  440. /package/dist/{types/meeting-info → meeting-info}/utilv2.d.ts +0 -0
  441. /package/dist/{types/meetings → meetings}/meetings.types.d.ts +0 -0
  442. /package/dist/{types/meetings → meetings}/request.d.ts +0 -0
  443. /package/dist/{types/meetings → meetings}/util.d.ts +0 -0
  444. /package/dist/{types/member → member}/types.d.ts +0 -0
  445. /package/dist/{types/member → member}/util.d.ts +0 -0
  446. /package/dist/{types/members → members}/collection.d.ts +0 -0
  447. /package/dist/{types/members → members}/index.d.ts +0 -0
  448. /package/dist/{types/members → members}/request.d.ts +0 -0
  449. /package/dist/{types/metrics → metrics}/index.d.ts +0 -0
  450. /package/dist/{types/multistream → multistream}/mediaRequestManager.d.ts +0 -0
  451. /package/dist/{types/multistream → multistream}/receiveSlot.d.ts +0 -0
  452. /package/dist/{types/multistream → multistream}/receiveSlotManager.d.ts +0 -0
  453. /package/dist/{types/multistream → multistream}/remoteMedia.d.ts +0 -0
  454. /package/dist/{types/multistream → multistream}/remoteMediaGroup.d.ts +0 -0
  455. /package/dist/{types/multistream → multistream}/sendSlotManager.d.ts +0 -0
  456. /package/dist/{types/networkQualityMonitor → networkQualityMonitor}/index.d.ts +0 -0
  457. /package/dist/{types/personal-meeting-room → personal-meeting-room}/index.d.ts +0 -0
  458. /package/dist/{types/personal-meeting-room → personal-meeting-room}/request.d.ts +0 -0
  459. /package/dist/{types/personal-meeting-room → personal-meeting-room}/util.d.ts +0 -0
  460. /package/dist/{types/reactions → reactions}/constants.d.ts +0 -0
  461. /package/dist/{types/reactions → reactions}/reactions.d.ts +0 -0
  462. /package/dist/{types/reactions → reactions}/reactions.type.d.ts +0 -0
  463. /package/dist/{types/recording-controller → recording-controller}/enums.d.ts +0 -0
  464. /package/dist/{types/recording-controller → recording-controller}/index.d.ts +0 -0
  465. /package/dist/{types/recording-controller → recording-controller}/util.d.ts +0 -0
  466. /package/dist/{types/rtcMetrics → rtcMetrics}/constants.d.ts +0 -0
  467. /package/dist/{types/statsAnalyzer → statsAnalyzer}/global.d.ts +0 -0
  468. /package/dist/{types/transcription → transcription}/index.d.ts +0 -0
  469. /package/test/unit/spec/locus-info/{selfConstant.js → lib/selfConstant.js} +0 -0
@@ -49,7 +49,7 @@ class ReachabilityRequest {
49
49
  const {clusters, joinCookie} = res.body;
50
50
 
51
51
  Object.keys(clusters).forEach((key) => {
52
- clusters[key].isVideoMesh = res.body.clusterClasses?.hybridMedia?.includes(key);
52
+ clusters[key].isVideoMesh = !!res.body.clusterClasses?.hybridMedia?.includes(key);
53
53
  });
54
54
 
55
55
  LoggerProxy.logger.log(
@@ -0,0 +1,24 @@
1
+ /* eslint-disable import/prefer-default-export */
2
+ /**
3
+ * Converts a stun url to a turn url
4
+ *
5
+ * @param {string} stunUrl url of a stun server
6
+ * @param {'tcp'|'udp'} protocol what protocol to use for the turn server
7
+ * @returns {string} url of a turn server
8
+ */
9
+ export function convertStunUrlToTurn(stunUrl: string, protocol: 'udp' | 'tcp') {
10
+ // stunUrl looks like this: "stun:external-media91.public.wjfkm-a-10.prod.infra.webex.com:5004"
11
+ // and we need it to be like this: "turn:external-media91.public.wjfkm-a-10.prod.infra.webex.com:5004?transport=tcp"
12
+ const url = new URL(stunUrl);
13
+
14
+ if (url.protocol !== 'stun:') {
15
+ throw new Error(`Not a STUN URL: ${stunUrl}`);
16
+ }
17
+
18
+ url.protocol = 'turn:';
19
+ if (protocol === 'tcp') {
20
+ url.searchParams.append('transport', 'tcp');
21
+ }
22
+
23
+ return url.toString();
24
+ }
@@ -14,13 +14,14 @@ import {
14
14
  _CALL_,
15
15
  _LEFT_,
16
16
  _ID_,
17
+ RECONNECTION_STATE,
17
18
  } from '../constants';
18
19
  import BEHAVIORAL_METRICS from '../metrics/constants';
19
- import ReconnectionError from '../common/errors/reconnection';
20
20
  import ReconnectInProgress from '../common/errors/reconnection-in-progress';
21
21
  import Metrics from '../metrics';
22
22
  import Meeting from '../meeting';
23
23
  import {MediaRequestManager} from '../multistream/mediaRequestManager';
24
+ import ReconnectionError from '../common/errors/reconnection';
24
25
 
25
26
  /**
26
27
  * Used to indicate that the reconnect logic needs to be retried.
@@ -96,7 +97,7 @@ export default class ReconnectionManager {
96
97
 
97
98
  /**
98
99
  * @instance
99
- * @type {String}
100
+ * @type {RECONNECTION_STATE}
100
101
  * @private
101
102
  * @memberof ReconnectionManager
102
103
  */
@@ -227,7 +228,6 @@ export default class ReconnectionManager {
227
228
  */
228
229
  public cleanUp() {
229
230
  this.reset();
230
- this.meeting = null;
231
231
  }
232
232
 
233
233
  /**
@@ -265,6 +265,18 @@ export default class ReconnectionManager {
265
265
  return this.status === RECONNECTION.STATE.IN_PROGRESS;
266
266
  }
267
267
 
268
+ /**
269
+ * Sets the reconnection status
270
+ *
271
+ * @public
272
+ * @param {RECONNECTION_STATE} status
273
+ * @memberof ReconnectionManager
274
+ * @returns {undefined}
275
+ */
276
+ public setStatus(status: RECONNECTION_STATE) {
277
+ this.status = status;
278
+ }
279
+
268
280
  /**
269
281
  * @returns {Boolean}
270
282
  * @throws {ReconnectionError}
@@ -337,73 +349,66 @@ export default class ReconnectionManager {
337
349
  });
338
350
  }
339
351
 
340
- return this.executeReconnection({networkDisconnect})
341
- .then(() => {
342
- LoggerProxy.logger.info('ReconnectionManager:index#reconnect --> Reconnection successful.');
343
- LoggerProxy.logger.info(
344
- 'ReconnectionManager:index#reconnect --> Sending reconnect success metric.'
345
- );
352
+ try {
353
+ await this.webex.meetings.startReachability();
354
+ } catch (err) {
355
+ LoggerProxy.logger.info(
356
+ 'ReconnectionManager:index#reconnect --> Reachability failed, continuing with reconnection attempt, err: ',
357
+ err
358
+ );
359
+ }
346
360
 
347
- // @ts-ignore
348
- this.webex.internal.newMetrics.submitClientEvent({
349
- name: 'client.media.recovered',
350
- payload: {
351
- recoveredBy: 'new',
352
- },
353
- options: {
354
- meetingId: this.meeting.id,
355
- },
356
- });
357
- })
358
- .catch((reconnectError) => {
359
- if (reconnectError instanceof NeedsRetryError) {
360
- LoggerProxy.logger.info(
361
- 'ReconnectionManager:index#reconnect --> Reconnection not successful, retrying.'
362
- );
363
- // Reset our reconnect status since we are looping back to the beginning
364
- this.status = RECONNECTION.STATE.DEFAULT_STATUS;
365
-
366
- // This is a network retry, so we should not log START metrics again
367
- return this.reconnect({networkDisconnect: true, networkRetry: true});
368
- }
361
+ try {
362
+ const media = await this.executeReconnection({networkDisconnect});
369
363
 
370
- // Reconnect has failed
371
- LoggerProxy.logger.error(
372
- 'ReconnectionManager:index#reconnect --> Reconnection failed.',
373
- reconnectError.message
374
- );
364
+ return media;
365
+ } catch (reconnectError) {
366
+ if (reconnectError instanceof NeedsRetryError) {
375
367
  LoggerProxy.logger.info(
376
- 'ReconnectionManager:index#reconnect --> Sending reconnect abort metric.'
368
+ 'ReconnectionManager:index#reconnect --> Reconnection not successful, retrying.'
377
369
  );
370
+ // Reset our reconnect status since we are looping back to the beginning
371
+ this.status = RECONNECTION.STATE.DEFAULT_STATUS;
378
372
 
379
- // @ts-ignore
380
- this.webex.internal.newMetrics.submitClientEvent({
381
- name: 'client.call.aborted',
382
- payload: {
383
- errors: [
384
- {
385
- category: 'expected',
386
- errorCode: 2008,
387
- fatal: true,
388
- name: 'media-engine',
389
- shownToUser: false,
390
- },
391
- ],
392
- },
393
- options: {
394
- meetingId: this.meeting.id,
395
- },
396
- });
397
- if (reconnectError instanceof NeedsRejoinError) {
398
- // send call aborded event with catogery as expected as we are trying to rejoin
373
+ // This is a network retry, so we should not log START metrics again
374
+ return this.reconnect({networkDisconnect: true, networkRetry: true});
375
+ }
399
376
 
400
- if (this.autoRejoinEnabled) {
401
- return this.rejoinMeeting(reconnectError.wasSharing);
402
- }
403
- }
377
+ // Reconnect has failed
378
+ LoggerProxy.logger.error(
379
+ 'ReconnectionManager:index#reconnect --> Reconnection failed.',
380
+ reconnectError.message
381
+ );
382
+ LoggerProxy.logger.info(
383
+ 'ReconnectionManager:index#reconnect --> Sending reconnect abort metric.'
384
+ );
404
385
 
405
- throw reconnectError;
386
+ // send call aborted event with catogery as expected as we are trying to rejoin
387
+ // @ts-ignore
388
+ this.webex.internal.newMetrics.submitClientEvent({
389
+ name: 'client.call.aborted',
390
+ payload: {
391
+ errors: [
392
+ {
393
+ category: 'expected',
394
+ errorCode: 2008,
395
+ fatal: true,
396
+ name: 'media-engine',
397
+ shownToUser: false,
398
+ },
399
+ ],
400
+ },
401
+ options: {
402
+ meetingId: this.meeting.id,
403
+ },
406
404
  });
405
+
406
+ if (reconnectError instanceof NeedsRejoinError && this.autoRejoinEnabled) {
407
+ return this.rejoinMeeting(reconnectError.wasSharing);
408
+ }
409
+
410
+ throw reconnectError;
411
+ }
407
412
  }
408
413
 
409
414
  /**
@@ -443,19 +448,17 @@ export default class ReconnectionManager {
443
448
  }
444
449
  }
445
450
 
446
- if (!this.webex.credentials.isUnverifiedGuest) {
447
- try {
448
- LoggerProxy.logger.info(
449
- 'ReconnectionManager:index#executeReconnection --> Updating meeting data from server.'
450
- );
451
- await this.webex.meetings.syncMeetings();
452
- } catch (syncError) {
453
- LoggerProxy.logger.info(
454
- 'ReconnectionManager:index#executeReconnection --> Unable to sync meetings, reconnecting.',
455
- syncError
456
- );
457
- throw new NeedsRetryError(syncError);
458
- }
451
+ try {
452
+ LoggerProxy.logger.info(
453
+ 'ReconnectionManager:index#executeReconnection --> Updating meeting data from server.'
454
+ );
455
+ await this.webex.meetings.syncMeetings({keepOnlyLocusMeetings: false});
456
+ } catch (syncError) {
457
+ LoggerProxy.logger.info(
458
+ 'ReconnectionManager:index#executeReconnection --> Unable to sync meetings, reconnecting.',
459
+ syncError
460
+ );
461
+ throw new NeedsRetryError(syncError);
459
462
  }
460
463
 
461
464
  // TODO: try to improve this logic as the reconnection manager saves the instance of deleted meeting object
@@ -485,14 +488,13 @@ export default class ReconnectionManager {
485
488
  const media = await this.reconnectMedia();
486
489
 
487
490
  LoggerProxy.logger.log(
488
- 'ReconnectionManager:index#executeReconnection --> Media reestablished'
491
+ 'ReconnectionManager:index#executeReconnection --> webRTC media connection renewed and local sdp offer sent'
489
492
  );
490
- this.status = RECONNECTION.STATE.COMPLETE;
491
493
 
492
494
  return media;
493
495
  } catch (error) {
494
496
  LoggerProxy.logger.error(
495
- 'ReconnectionManager:index#executeReconnection --> Media reestablishment failed'
497
+ 'ReconnectionManager:index#executeReconnection --> failed to renew webRTC media connection or initiate offer'
496
498
  );
497
499
  this.status = RECONNECTION.STATE.FAILURE;
498
500
 
@@ -559,12 +561,10 @@ export default class ReconnectionManager {
559
561
  * @memberof ReconnectionManager
560
562
  */
561
563
  async reconnectMedia() {
562
- LoggerProxy.logger.log(
563
- 'ReconnectionManager:index#reconnectMedia --> Begin reestablishment of media'
564
- );
564
+ LoggerProxy.logger.log('ReconnectionManager:index#reconnectMedia --> do turn discovery');
565
565
 
566
- // do the TURN server discovery again since the TURN server might change
567
- const turnServerResult = await this.meeting.roap.doTurnDiscovery(this.meeting, true);
566
+ // do the TURN server discovery again and ignore reachability results since the TURN server might change
567
+ const turnServerResult = await this.meeting.roap.doTurnDiscovery(this.meeting, true, true);
568
568
 
569
569
  const iceServers = [];
570
570
 
@@ -576,6 +576,10 @@ export default class ReconnectionManager {
576
576
  });
577
577
  }
578
578
 
579
+ LoggerProxy.logger.log(
580
+ 'ReconnectionManager:index#reconnectMedia --> renew webRTC media connection and send local sdp offer'
581
+ );
582
+
579
583
  await this.meeting.mediaProperties.webrtcMediaConnection.reconnect(iceServers);
580
584
 
581
585
  // resend media requests
package/src/roap/index.ts CHANGED
@@ -8,6 +8,8 @@ import RoapRequest from './request';
8
8
  import TurnDiscovery from './turnDiscovery';
9
9
  import Meeting from '../meeting';
10
10
  import MeetingUtil from '../meeting/util';
11
+ import Metrics from '../metrics';
12
+ import BEHAVIORAL_METRICS from '../metrics/constants';
11
13
 
12
14
  /**
13
15
  * Roap options
@@ -179,39 +181,72 @@ export default class Roap extends StatelessWebexPlugin {
179
181
  * @memberof Roap
180
182
  */
181
183
  sendRoapMediaRequest(options: any) {
182
- const {meeting, seq, sdp, reconnect, tieBreaker} = options;
184
+ const {meeting, seq, sdp, tieBreaker} = options;
183
185
  const roapMessage = {
184
186
  messageType: ROAP.ROAP_TYPES.OFFER,
185
187
  sdps: [sdp],
186
188
  version: ROAP.ROAP_VERSION,
187
189
  seq,
188
190
  tieBreaker,
191
+ headers: ['includeAnswerInHttpResponse', 'noOkInTransaction'],
189
192
  };
190
193
 
191
- // When reconnecting, it's important that the first roap message being sent out has empty media id.
192
- // Normally this is the roap offer, but when TURN discovery is enabled,
193
- // then this is the TURN discovery request message
194
- return this.turnDiscovery.isSkipped(meeting).then((isTurnDiscoverySkipped) => {
195
- const sendEmptyMediaId = reconnect && isTurnDiscoverySkipped;
194
+ // The only time we want to send an empty media id is when we are reconnecting, because this way we tell Locus
195
+ // that it needs to create a new confluence, but when reconnecting we always send TURN_DISCOVERY_REQUEST first,
196
+ // so we don't need to ever send an empty media id here
197
+ const sendEmptyMediaId = false;
196
198
 
197
- return this.roapRequest
198
- .sendRoap({
199
- roapMessage,
200
- locusSelfUrl: meeting.selfUrl,
201
- mediaId: sendEmptyMediaId ? '' : meeting.mediaId,
202
- meetingId: meeting.id,
203
- preferTranscoding: !meeting.isMultistream,
204
- locusMediaRequest: meeting.locusMediaRequest,
205
- ipVersion: MeetingUtil.getIpVersion(meeting.webex),
206
- })
207
- .then(({locus, mediaConnections}) => {
208
- if (mediaConnections) {
209
- meeting.updateMediaConnections(mediaConnections);
199
+ return this.roapRequest
200
+ .sendRoap({
201
+ roapMessage,
202
+ locusSelfUrl: meeting.selfUrl,
203
+ mediaId: sendEmptyMediaId ? '' : meeting.mediaId,
204
+ meetingId: meeting.id,
205
+ preferTranscoding: !meeting.isMultistream,
206
+ locusMediaRequest: meeting.locusMediaRequest,
207
+ ipVersion: MeetingUtil.getIpVersion(meeting.webex),
208
+ })
209
+ .then(({locus, mediaConnections}) => {
210
+ if (mediaConnections) {
211
+ meeting.updateMediaConnections(mediaConnections);
212
+ }
213
+
214
+ let roapAnswer;
215
+
216
+ if (mediaConnections?.[0]?.remoteSdp) {
217
+ const remoteSdp = JSON.parse(mediaConnections[0].remoteSdp);
218
+
219
+ if (remoteSdp.roapMessage) {
220
+ const {
221
+ seq: answerSeq,
222
+ messageType,
223
+ sdps,
224
+ errorType,
225
+ errorCause,
226
+ headers,
227
+ } = remoteSdp.roapMessage;
228
+
229
+ roapAnswer = {
230
+ seq: answerSeq,
231
+ messageType,
232
+ sdp: sdps[0],
233
+ errorType,
234
+ errorCause,
235
+ headers,
236
+ };
210
237
  }
238
+ }
211
239
 
212
- return locus;
213
- });
214
- });
240
+ if (!roapAnswer) {
241
+ Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.ROAP_HTTP_RESPONSE_MISSING, {
242
+ correlationId: meeting.correlationId,
243
+ messageType: 'ANSWER',
244
+ isMultistream: meeting.isMultistream,
245
+ });
246
+ }
247
+
248
+ return {locus, roapAnswer};
249
+ });
215
250
  }
216
251
 
217
252
  /**
@@ -222,9 +257,10 @@ export default class Roap extends StatelessWebexPlugin {
222
257
  * @param {Meeting} meeting
223
258
  * @param {Boolean} isReconnecting should be set to true if this is a new
224
259
  * media connection just after a reconnection
260
+ * @param {Boolean} [isForced]
225
261
  * @returns {Promise}
226
262
  */
227
- doTurnDiscovery(meeting: Meeting, isReconnecting: boolean) {
228
- return this.turnDiscovery.doTurnDiscovery(meeting, isReconnecting);
263
+ doTurnDiscovery(meeting: Meeting, isReconnecting: boolean, isForced?: boolean) {
264
+ return this.turnDiscovery.doTurnDiscovery(meeting, isReconnecting, isForced);
229
265
  }
230
266
  }
@@ -18,23 +18,10 @@ export default class RoapRequest extends StatelessWebexPlugin {
18
18
  let joinCookie;
19
19
 
20
20
  // @ts-ignore
21
- const reachabilityData = await this.webex.boundedStorage
22
- .get(REACHABILITY.namespace, REACHABILITY.localStorageResult)
23
- .catch(() => {});
24
-
25
- if (reachabilityData) {
26
- try {
27
- const reachabilityResult = JSON.parse(reachabilityData);
21
+ const reachabilityResult = await this.webex.meetings.reachability.getReachabilityResults();
28
22
 
29
- /* istanbul ignore else */
30
- if (reachabilityResult && Object.keys(reachabilityResult).length) {
31
- localSdp.reachability = reachabilityResult;
32
- }
33
- } catch (e) {
34
- LoggerProxy.logger.error(
35
- `Roap:request#attachReachabilityData --> Error in parsing reachability data: ${e}`
36
- );
37
- }
23
+ if (reachabilityResult && Object.keys(reachabilityResult).length) {
24
+ localSdp.reachability = reachabilityResult;
38
25
  }
39
26
 
40
27
  // @ts-ignore
@@ -136,7 +123,7 @@ export default class RoapRequest extends StatelessWebexPlugin {
136
123
  );
137
124
  const {locus} = res.body;
138
125
 
139
- locus.roapSeq = options.roapMessage.seq;
126
+ locus.roapSeq = roapMessage.seq;
140
127
 
141
128
  return {
142
129
  locus,