call-control-sdk 6.5.5 → 6.5.6-uat.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Binary file
package/dist/index.js CHANGED
@@ -64,7 +64,7 @@ module.exports = __toCommonJS(index_exports);
64
64
  var import_vault = require("@react-solutions/vault");
65
65
 
66
66
  // call-control-sdk/lib/services/endPoint.ts
67
- var IP = "cti.aighospitals.com";
67
+ var IP = "uat-cti.aighospitals.com";
68
68
  var BASE_URL = `https://${IP}:8095`;
69
69
  var WS_BASE_URL = `wss://${IP}:8095`;
70
70
  var VERSION = {
@@ -1675,7 +1675,7 @@ function ConferenceDialog() {
1675
1675
  onClick: handleTransferConferenceCall,
1676
1676
  disabled: conferenceLineCount <= 1 || isHold || isLineDialing || isOnCall,
1677
1677
  startIcon: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_icons_material.TransferWithinAStation, {}),
1678
- children: "Exit Conference"
1678
+ children: "Transfer Conference"
1679
1679
  }
1680
1680
  ),
1681
1681
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
@@ -3041,6 +3041,83 @@ function createMicController(constraints = { audio: true }) {
3041
3041
  };
3042
3042
  }
3043
3043
 
3044
+ // call-control-sdk/lib/utils/audioLoader.ts
3045
+ var import_incoming = __toESM(require("./incoming-4WP3FJI4.mp3"));
3046
+ var audioBlobUrl = null;
3047
+ var audioBuffer = null;
3048
+ async function loadAudioAsBlob() {
3049
+ if (audioBlobUrl) {
3050
+ return audioBlobUrl;
3051
+ }
3052
+ if (import_incoming.default.startsWith("data:") || import_incoming.default.startsWith("http://") || import_incoming.default.startsWith("https://") || import_incoming.default.startsWith("blob:")) {
3053
+ return import_incoming.default;
3054
+ }
3055
+ try {
3056
+ const response = await fetch(import_incoming.default);
3057
+ if (!response.ok) {
3058
+ throw new Error(`HTTP ${response.status}: ${response.statusText}`);
3059
+ }
3060
+ const blob = await response.blob();
3061
+ if (blob.size === 0) {
3062
+ throw new Error("Empty blob");
3063
+ }
3064
+ audioBlobUrl = URL.createObjectURL(blob);
3065
+ return audioBlobUrl;
3066
+ } catch (error) {
3067
+ console.error("Could not create blob URL, using direct URL:", error);
3068
+ return import_incoming.default;
3069
+ }
3070
+ }
3071
+ async function createAudioElement() {
3072
+ const audio = new Audio();
3073
+ audio.loop = true;
3074
+ audio.volume = 0.7;
3075
+ audio.preload = "auto";
3076
+ let audioUrl = "";
3077
+ try {
3078
+ audioUrl = await loadAudioAsBlob();
3079
+ } catch (error) {
3080
+ console.warn("Failed to load audio as blob, trying direct URL:", error);
3081
+ audioUrl = import_incoming.default;
3082
+ }
3083
+ const tryLoadAudio = async (url) => {
3084
+ return new Promise((resolve) => {
3085
+ const checkCanPlay = () => {
3086
+ const canPlay = audio.readyState >= HTMLMediaElement.HAVE_FUTURE_DATA;
3087
+ if (canPlay) {
3088
+ resolve(true);
3089
+ return;
3090
+ }
3091
+ if (audio.error) {
3092
+ resolve(false);
3093
+ return;
3094
+ }
3095
+ setTimeout(checkCanPlay, 100);
3096
+ };
3097
+ audio.addEventListener("canplay", () => resolve(true), { once: true });
3098
+ audio.addEventListener("error", () => resolve(false), { once: true });
3099
+ audio.src = url;
3100
+ audio.load();
3101
+ setTimeout(() => resolve(false), 2e3);
3102
+ });
3103
+ };
3104
+ let loaded = await tryLoadAudio(audioUrl);
3105
+ if (!loaded && audioUrl !== import_incoming.default) {
3106
+ loaded = await tryLoadAudio(import_incoming.default);
3107
+ if (loaded) {
3108
+ audioUrl = import_incoming.default;
3109
+ }
3110
+ }
3111
+ return audio;
3112
+ }
3113
+ function cleanupAudioResources() {
3114
+ if (audioBlobUrl) {
3115
+ URL.revokeObjectURL(audioBlobUrl);
3116
+ audioBlobUrl = null;
3117
+ }
3118
+ audioBuffer = null;
3119
+ }
3120
+
3044
3121
  // call-control-sdk/lib/components/callControls.tsx
3045
3122
  var import_vault5 = require("@react-solutions/vault");
3046
3123
  var import_jsx_runtime3 = require("react/jsx-runtime");
@@ -3073,7 +3150,7 @@ var formatDuration = (seconds) => {
3073
3150
  return `${mins.toString().padStart(2, "0")}:${secs.toString().padStart(2, "0")}`;
3074
3151
  };
3075
3152
  function CallControls({ onDataChange }) {
3076
- var _a2, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D, _E, _F, _G, _H, _I, _J, _K, _L, _M, _N, _O, _P, _Q, _R, _S, _T, _U, _V, _W, _X, _Y, _Z, __, _$, _aa, _ba, _ca, _da, _ea, _fa, _ga, _ha, _ia, _ja, _ka, _la, _ma, _na, _oa, _pa, _qa, _ra, _sa, _ta, _ua, _va, _wa, _xa, _ya;
3153
+ var _a2, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D, _E, _F, _G, _H, _I, _J, _K, _L, _M, _N, _O, _P, _Q, _R, _S, _T, _U, _V, _W, _X, _Y, _Z, __, _$, _aa, _ba, _ca, _da, _ea, _fa, _ga, _ha, _ia, _ja, _ka, _la, _ma, _na, _oa, _pa, _qa, _ra, _sa, _ta, _ua, _va, _wa, _xa, _ya, _za, _Aa;
3077
3154
  const theme = (0, import_material4.useTheme)();
3078
3155
  const state = useSDKState();
3079
3156
  const { showToast } = useToast();
@@ -3084,6 +3161,7 @@ function CallControls({ onDataChange }) {
3084
3161
  });
3085
3162
  const micRef = (0, import_react11.useRef)(null);
3086
3163
  const webSocketRef = (0, import_react11.useRef)(null);
3164
+ const audioRef = (0, import_react11.useRef)(null);
3087
3165
  const reconnectTimeoutRef = (0, import_react11.useRef)(null);
3088
3166
  const pingIntervalRef = (0, import_react11.useRef)(null);
3089
3167
  const reconnectAttemptsRef = (0, import_react11.useRef)(0);
@@ -3126,16 +3204,8 @@ function CallControls({ onDataChange }) {
3126
3204
  setDialerAnchorEl(null);
3127
3205
  }
3128
3206
  });
3129
- const [holdOrUnHold, { isLoading: holdOrUnHoldLoading }] = usePostRequest({
3130
- // onSuccess: () => {
3131
- // sdkStateManager.setHolding(!state.isHolding);
3132
- // },
3133
- });
3134
- const [muteOrUnMute, { isLoading: muteOrUnMuteLoading }] = usePostRequest({
3135
- // onSuccess: () => {
3136
- // sdkStateManager.setMuted(!state.isMuted);
3137
- // },
3138
- });
3207
+ const [holdOrUnHold, { isLoading: holdOrUnHoldLoading }] = usePostRequest();
3208
+ const [muteOrUnMute, { isLoading: muteOrUnMuteLoading }] = usePostRequest();
3139
3209
  const [readyAgentStatus, { isLoading: agentReadyLoading }] = usePostRequest({
3140
3210
  onSuccess: () => {
3141
3211
  sdkStateManager.setAgentStatus("");
@@ -3346,6 +3416,22 @@ function CallControls({ onDataChange }) {
3346
3416
  if (wrapUpinterval) clearInterval(wrapUpinterval);
3347
3417
  };
3348
3418
  }, [state.callData.status]);
3419
+ (0, import_react11.useEffect)(() => {
3420
+ createAudioElement().then((audio) => {
3421
+ audioRef.current = audio;
3422
+ }).catch((error) => {
3423
+ console.error("Failed to load audio element:", error);
3424
+ });
3425
+ return () => {
3426
+ if (audioRef.current) {
3427
+ audioRef.current.pause();
3428
+ audioRef.current.currentTime = 0;
3429
+ audioRef.current.src = "";
3430
+ audioRef.current = null;
3431
+ }
3432
+ cleanupAudioResources();
3433
+ };
3434
+ }, []);
3349
3435
  (0, import_react11.useEffect)(() => {
3350
3436
  if (onDataChange && state.callData) {
3351
3437
  const { process_id, process_name, status, phone_number, agent_id, convox_id } = state.callData;
@@ -3415,7 +3501,7 @@ function CallControls({ onDataChange }) {
3415
3501
  }, 3e4);
3416
3502
  };
3417
3503
  webSocketRef.current.onmessage = (event) => {
3418
- var _a3, _b2, _c2, _d2;
3504
+ var _a3, _b2, _c2, _d2, _e2;
3419
3505
  try {
3420
3506
  const data = JSON.parse(event.data);
3421
3507
  if (data.type === "pong") {
@@ -3494,6 +3580,16 @@ function CallControls({ onDataChange }) {
3494
3580
  isMergeCall: false
3495
3581
  }
3496
3582
  ]);
3583
+ if ((data == null ? void 0 : data.mode) !== "manual" && audioRef.current && ((_c2 = state == null ? void 0 : state.sdkConfig) == null ? void 0 : _c2.enableRingtone)) {
3584
+ audioRef.current.play().catch((error) => {
3585
+ console.error("Failed to play ringtone:", error);
3586
+ });
3587
+ }
3588
+ } else {
3589
+ if (audioRef.current) {
3590
+ audioRef.current.pause();
3591
+ audioRef.current.currentTime = 0;
3592
+ }
3497
3593
  }
3498
3594
  if (data.status === "IDLE" /* IDLE */) {
3499
3595
  USB_LIGHT_REQUEST(USB_LIGHT_ON("green"));
@@ -3506,8 +3602,8 @@ function CallControls({ onDataChange }) {
3506
3602
  } else if (((data == null ? void 0 : data.mute) === 1 || (data == null ? void 0 : data.hold) === 1) && data.status === "ONCALL" /* ONCALL */) {
3507
3603
  USB_LIGHT_REQUEST(USB_LIGHT_FLASH("red", 1));
3508
3604
  } else if (data.status === "BREAK" /* BREAK */) {
3509
- const breakTime = (_c2 = sdkState == null ? void 0 : sdkState.sdkConfig) == null ? void 0 : _c2.break_time;
3510
- const eventTime = (_d2 = data == null ? void 0 : data.event_time) != null ? _d2 : null;
3605
+ const breakTime = (_d2 = sdkState == null ? void 0 : sdkState.sdkConfig) == null ? void 0 : _d2.break_time;
3606
+ const eventTime = (_e2 = data == null ? void 0 : data.event_time) != null ? _e2 : null;
3511
3607
  if (eventTime !== lastEventTimeRef.current) {
3512
3608
  hasFlashedRef.current = false;
3513
3609
  lastEventTimeRef.current = eventTime;
@@ -3847,18 +3943,18 @@ function CallControls({ onDataChange }) {
3847
3943
  {
3848
3944
  variant: state.openCallTransferDialog ? "contained" : "outlined",
3849
3945
  onClick: (e) => {
3850
- var _a3, _b2;
3851
- if (((_b2 = (_a3 = state.callData) == null ? void 0 : _a3.status) == null ? void 0 : _b2.toUpperCase()) === "ONCALL" /* ONCALL */) {
3946
+ var _a3, _b2, _c2;
3947
+ if (((_b2 = (_a3 = state.callData) == null ? void 0 : _a3.status) == null ? void 0 : _b2.toUpperCase()) === "ONCALL" /* ONCALL */ || ((_c2 = state == null ? void 0 : state.conferenceLine[0]) == null ? void 0 : _c2.status) === "HOLD" /* HOLD */) {
3852
3948
  e.stopPropagation();
3853
3949
  sdkStateManager.setOpenCallTransferDialog(true);
3854
3950
  }
3855
3951
  },
3856
- sx: state.openCallTransferDialog ? __spreadValues({}, enabled) : ((_aa = (_$ = state.callData) == null ? void 0 : _$.status) == null ? void 0 : _aa.toUpperCase()) === "ONCALL" /* ONCALL */ ? __spreadValues({}, outlined) : __spreadValues({}, disabled),
3857
- disabled: ((_ca = (_ba = state.callData) == null ? void 0 : _ba.status) == null ? void 0 : _ca.toUpperCase()) !== "ONCALL" /* ONCALL */,
3952
+ sx: state.openCallTransferDialog ? __spreadValues({}, enabled) : ((_aa = (_$ = state.callData) == null ? void 0 : _$.status) == null ? void 0 : _aa.toUpperCase()) === "ONCALL" /* ONCALL */ || ((_ba = state == null ? void 0 : state.conferenceLine[0]) == null ? void 0 : _ba.status) === "HOLD" /* HOLD */ ? __spreadValues({}, outlined) : __spreadValues({}, disabled),
3953
+ disabled: ((_da = (_ca = state.callData) == null ? void 0 : _ca.status) == null ? void 0 : _da.toUpperCase()) !== "ONCALL" /* ONCALL */ || ((_ea = state == null ? void 0 : state.conferenceLine[0]) == null ? void 0 : _ea.status) === "HOLD" /* HOLD */,
3858
3954
  children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_icons_material2.TransferWithinAStation, {})
3859
3955
  }
3860
3956
  ) }),
3861
- !((_da = state.sdkConfig) == null ? void 0 : _da.disableConferenceButton) && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_material4.Tooltip, { title: "Conference Call", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3957
+ !((_fa = state.sdkConfig) == null ? void 0 : _fa.disableConferenceButton) && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_material4.Tooltip, { title: "Conference Call", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3862
3958
  import_material4.Button,
3863
3959
  {
3864
3960
  variant: state.openConferenceDialog ? "contained" : "outlined",
@@ -3869,12 +3965,12 @@ function CallControls({ onDataChange }) {
3869
3965
  sdkStateManager.setOpenConferenceDialog(true);
3870
3966
  }
3871
3967
  },
3872
- sx: state.openConferenceDialog ? __spreadValues({}, enabled) : ((_fa = (_ea = state.callData) == null ? void 0 : _ea.status) == null ? void 0 : _fa.toUpperCase()) === "ONCALL" /* ONCALL */ ? __spreadValues({}, outlined) : __spreadValues({}, disabled),
3873
- disabled: ((_ha = (_ga = state.callData) == null ? void 0 : _ga.status) == null ? void 0 : _ha.toUpperCase()) !== "ONCALL" /* ONCALL */,
3968
+ sx: state.openConferenceDialog ? __spreadValues({}, enabled) : ((_ha = (_ga = state.callData) == null ? void 0 : _ga.status) == null ? void 0 : _ha.toUpperCase()) === "ONCALL" /* ONCALL */ ? __spreadValues({}, outlined) : __spreadValues({}, disabled),
3969
+ disabled: ((_ja = (_ia = state.callData) == null ? void 0 : _ia.status) == null ? void 0 : _ja.toUpperCase()) !== "ONCALL" /* ONCALL */,
3874
3970
  children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_icons_material2.Group, {})
3875
3971
  }
3876
3972
  ) }),
3877
- ((_ia = state.sdkConfig) == null ? void 0 : _ia.enableSmsServices) && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_material4.Tooltip, { title: "Send SMS", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3973
+ ((_ka = state.sdkConfig) == null ? void 0 : _ka.enableSmsServices) && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_material4.Tooltip, { title: "Send SMS", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3878
3974
  import_material4.Button,
3879
3975
  {
3880
3976
  variant: Boolean(ambulanceAnchorEl) ? "contained" : "outlined",
@@ -3888,15 +3984,15 @@ function CallControls({ onDataChange }) {
3888
3984
  }
3889
3985
  },
3890
3986
  sx: Boolean(ambulanceAnchorEl) ? __spreadValues({}, enabled) : ["ONCALL" /* ONCALL */, "WRAPUP" /* WRAPUP */].includes(
3891
- (_ka = (_ja = state.callData) == null ? void 0 : _ja.status) == null ? void 0 : _ka.toUpperCase()
3987
+ (_ma = (_la = state.callData) == null ? void 0 : _la.status) == null ? void 0 : _ma.toUpperCase()
3892
3988
  ) ? __spreadValues({}, outlined) : __spreadValues({}, disabled),
3893
3989
  disabled: !["ONCALL" /* ONCALL */, "WRAPUP" /* WRAPUP */].includes(
3894
- (_ma = (_la = state.callData) == null ? void 0 : _la.status) == null ? void 0 : _ma.toUpperCase()
3990
+ (_oa = (_na = state.callData) == null ? void 0 : _na.status) == null ? void 0 : _oa.toUpperCase()
3895
3991
  ),
3896
3992
  children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_icons_material2.SmsSharp, {})
3897
3993
  }
3898
3994
  ) }),
3899
- !((_na = state.sdkConfig) == null ? void 0 : _na.disableEndCallButton) && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_material4.Tooltip, { title: "End Call", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3995
+ !((_pa = state.sdkConfig) == null ? void 0 : _pa.disableEndCallButton) && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_material4.Tooltip, { title: "End Call", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3900
3996
  import_material4.Button,
3901
3997
  {
3902
3998
  variant: [
@@ -3904,7 +4000,7 @@ function CallControls({ onDataChange }) {
3904
4000
  "RINGING" /* RINGING */,
3905
4001
  "DIALING" /* DIALING */,
3906
4002
  "WRAPUP" /* WRAPUP */
3907
- ].includes((_pa = (_oa = state.callData) == null ? void 0 : _oa.status) == null ? void 0 : _pa.toUpperCase()) ? "contained" : "outlined",
4003
+ ].includes((_ra = (_qa = state.callData) == null ? void 0 : _qa.status) == null ? void 0 : _ra.toUpperCase()) ? "contained" : "outlined",
3908
4004
  onClick: (e) => {
3909
4005
  var _a3, _b2;
3910
4006
  if ([
@@ -3922,7 +4018,7 @@ function CallControls({ onDataChange }) {
3922
4018
  "RINGING" /* RINGING */,
3923
4019
  "DIALING" /* DIALING */,
3924
4020
  "WRAPUP" /* WRAPUP */
3925
- ].includes((_ra = (_qa = state.callData) == null ? void 0 : _qa.status) == null ? void 0 : _ra.toUpperCase()) ? __spreadProps(__spreadValues({}, enabled), {
4021
+ ].includes((_ta = (_sa = state.callData) == null ? void 0 : _sa.status) == null ? void 0 : _ta.toUpperCase()) ? __spreadProps(__spreadValues({}, enabled), {
3926
4022
  borderRight: "1px",
3927
4023
  backgroundColor: "error.main",
3928
4024
  minWidth: "60px !important",
@@ -3946,7 +4042,7 @@ function CallControls({ onDataChange }) {
3946
4042
  "RINGING" /* RINGING */,
3947
4043
  "DIALING" /* DIALING */,
3948
4044
  "WRAPUP" /* WRAPUP */
3949
- ].includes((_ta = (_sa = state.callData) == null ? void 0 : _sa.status) == null ? void 0 : _ta.toUpperCase()) || endCallLoading,
4045
+ ].includes((_va = (_ua = state.callData) == null ? void 0 : _ua.status) == null ? void 0 : _va.toUpperCase()) || endCallLoading,
3950
4046
  children: endCallLoading ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3951
4047
  import_material4.CircularProgress,
3952
4048
  {
@@ -3956,7 +4052,7 @@ function CallControls({ onDataChange }) {
3956
4052
  ) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_icons_material2.CallEnd, {})
3957
4053
  }
3958
4054
  ) }),
3959
- !((_ua = state.sdkConfig) == null ? void 0 : _ua.disabledMoreOptionsButton) && processList && (processList == null ? void 0 : processList.length) > 1 && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_material4.Tooltip, { title: "Switch Process", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
4055
+ !((_wa = state.sdkConfig) == null ? void 0 : _wa.disabledMoreOptionsButton) && processList && (processList == null ? void 0 : processList.length) > 1 && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_material4.Tooltip, { title: "Switch Process", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3960
4056
  import_material4.Button,
3961
4057
  {
3962
4058
  variant: Boolean(moreOptionsAnchorEl) ? "contained" : "outlined",
@@ -3971,7 +4067,7 @@ function CallControls({ onDataChange }) {
3971
4067
  },
3972
4068
  sx: Boolean(moreOptionsAnchorEl) ? __spreadValues({}, enabled) : __spreadValues({}, outlined),
3973
4069
  disabled: !["BREAK" /* BREAK */, "IDLE" /* IDLE */].includes(
3974
- (_wa = (_va = state.callData) == null ? void 0 : _va.status) == null ? void 0 : _wa.toUpperCase()
4070
+ (_ya = (_xa = state.callData) == null ? void 0 : _xa.status) == null ? void 0 : _ya.toUpperCase()
3975
4071
  ),
3976
4072
  children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_icons_material2.MoreVert, {})
3977
4073
  }
@@ -4006,7 +4102,7 @@ function CallControls({ onDataChange }) {
4006
4102
  transition: theme.transitions.create(["box-shadow", "transform"], {
4007
4103
  duration: theme.transitions.duration.short
4008
4104
  }),
4009
- visibility: showIframe && !((_xa = state.sdkConfig) == null ? void 0 : _xa.disableSoftPhone) ? "visible" : "hidden",
4105
+ visibility: showIframe && !((_za = state.sdkConfig) == null ? void 0 : _za.disableSoftPhone) ? "visible" : "hidden",
4010
4106
  userSelect: "none"
4011
4107
  },
4012
4108
  children: [
@@ -4040,7 +4136,7 @@ function CallControls({ onDataChange }) {
4040
4136
  /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_material4.Box, { children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
4041
4137
  "iframe",
4042
4138
  {
4043
- src: `https://${IP}/ConVoxCCS/iframe?agent_id=${state.agentId}&process_id=${(_ya = state.process) == null ? void 0 : _ya.process_id}`,
4139
+ src: `https://${IP}/ConVoxCCS/iframe?agent_id=${state.agentId}&process_id=${(_Aa = state.process) == null ? void 0 : _Aa.process_id}`,
4044
4140
  height: 380,
4045
4141
  width: 420,
4046
4142
  allow: "camera; microphone; autoplay",