"use strict";
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __markAsModule = (target) => __defProp(target, "__esModule", { value: true });
var __export = (target, all) => {
  __markAsModule(target);
  for (var name in all)
    __defProp(target, name, { get: all[name], enumerable: true });
};
var __reExport = (target, module2, desc) => {
  if (module2 && typeof module2 === "object" || typeof module2 === "function") {
    for (let key of __getOwnPropNames(module2))
      if (!__hasOwnProp.call(target, key) && key !== "default")
        __defProp(target, key, { get: () => module2[key], enumerable: !(desc = __getOwnPropDesc(module2, key)) || desc.enumerable });
  }
  return target;
};
var __toModule = (module2) => {
  return __reExport(__markAsModule(__defProp(module2 != null ? __create(__getProtoOf(module2)) : {}, "default", module2 && module2.__esModule && "default" in module2 ? { get: () => module2.default, enumerable: true } : { value: module2, enumerable: true })), module2);
};

// src/index.ts
__export(exports, {
  AudioRenderer: () => AudioRenderer,
  AudioSelectButton: () => AudioSelectButton,
  ControlButton: () => ControlButton,
  ControlsView: () => ControlsView,
  DisplayContext: () => DisplayContext,
  LiveKitRoom: () => LiveKitRoom,
  ParticipantView: () => ParticipantView,
  ScreenShareView: () => ScreenShareView,
  StageView: () => StageView,
  VideoRenderer: () => VideoRenderer,
  VideoSelectButton: () => VideoSelectButton,
  createParticipant: () => createParticipant,
  createRoom: () => createRoom,
  sortParticipants: () => sortParticipants,
  useDisplay: () => useDisplay
});

// src/components/AudioRenderer.tsx
var import_solid_js = __toModule(require("solid-js"));
var AudioRenderer = (props) => {
  let audioElement;
  (0, import_solid_js.createEffect)(() => {
    if (!props.isLocal) {
      audioElement = props.track.attach();
      if (props.track.sid) {
        audioElement.setAttribute("data-audio-track-id", props.track.sid);
      }
    }
    (0, import_solid_js.onCleanup)(() => {
      props.track.detach().forEach((element) => element.remove());
    });
  });
  return null;
};

// src/components/AudioSelectButton.tsx
var import_solid_js4 = __toModule(require("solid-js"));
var import_fa2 = __toModule(require("solid-icons/fa"));
var import_livekit_client = __toModule(require("livekit-client"));

// src/components/ControlButton.tsx
var import_solid_js3 = __toModule(require("solid-js"));
var import_fa = __toModule(require("solid-icons/fa"));

// src/components/Popover.tsx
var import_solid_js2 = __toModule(require("solid-js"));
var import_solid_headless = __toModule(require("solid-headless"));
var import_solid_popper = __toModule(require("solid-popper"));
var Popover = (props) => {
  var _a;
  const [anchor, setAnchor] = (0, import_solid_js2.createSignal)();
  const [popper, setPopper] = (0, import_solid_js2.createSignal)();
  (0, import_solid_popper.default)(anchor, popper, {
    placement: (_a = props.placement) != null ? _a : "auto"
  });
  return <import_solid_headless.Popover isOpen={props.isOpen}>{({ isOpen }) => <>
    <import_solid_headless.PopoverButton ref={setAnchor} type="button">{props.children}</import_solid_headless.PopoverButton>
    <import_solid_headless.Transition show={isOpen()}><import_solid_headless.PopoverPanel ref={setPopper}>{props.content}</import_solid_headless.PopoverPanel></import_solid_headless.Transition>
  </>}</import_solid_headless.Popover>;
};

// src/components/ControlButton.tsx
var ControlButton = (props) => {
  const [menuVisible, setMenuVisible] = (0, import_solid_js3.createSignal)(false);
  const [classes, setClasses] = (0, import_solid_js3.createSignal)("button");
  (0, import_solid_js3.createEffect)(() => {
    if (props.className) {
      setClasses((current) => {
        if (props.className) {
          return `${current} ${props.className}`;
        }
        return current;
      });
    }
    if (props.menuItems && props.menuItems.length > 0) {
      setClasses((current) => `${current} hasDropdown`);
    }
  });
  const handleMenuClick = (item) => {
    setMenuVisible(false);
    if (props.onMenuItemClick) {
      props.onMenuItemClick(item);
    }
  };
  const MenuTrigger = () => <import_solid_js3.Show when={props.menuItems}>{(menuItems) => {
    var _a, _b;
    return <import_solid_js3.Show when={menuItems.length > 0}><button disabled={props.disabled} classList={{
      "button dropdown": true,
      [(_a = props.popoverTriggerBtnClassName) != null ? _a : ""]: !!props.popoverTriggerBtnClassName
    }}>
      <div classList={{
        separator: true,
        [(_b = props.popoverTriggerBtnSeparatorClassName) != null ? _b : ""]: !!props.popoverTriggerBtnSeparatorClassName
      }} />
      <import_fa.FaSolidChevronDown height={32} />
    </button></import_solid_js3.Show>;
  }}</import_solid_js3.Show>;
  const Menu = () => <import_solid_js3.Show when={props.menuItems}>{(menuItems) => {
    var _a;
    return <import_solid_js3.Show when={menuItems.length > 0}><div classList={{
      popoverMenu: true,
      [(_a = props.popoverContainerClassName) != null ? _a : ""]: !!props.popoverContainerClassName
    }}><ul className="list"><import_solid_js3.For each={menuItems}>{(item) => <li onClick={() => handleMenuClick(item)}>{item.label}</li>}</import_solid_js3.For></ul></div></import_solid_js3.Show>;
  }}</import_solid_js3.Show>;
  return <Popover isOpen={menuVisible()} placement="top" content={<Menu />}><div className="buttonWrapper">
    <button disabled={props.disabled} className={classes()} onClick={() => {
      if (props.onClick) {
        props.onClick();
      }
    }}>
      <import_solid_js3.Show when={props.icon}>{(icon) => icon}</import_solid_js3.Show>
      {props.label}
    </button>
    <MenuTrigger />
  </div></Popover>;
};

// src/components/AudioSelectButton.tsx
var AudioSelectButton = (props) => {
  const mergedProps = (0, import_solid_js4.mergeProps)({
    muteText: "Mute",
    unmuteText: "Unmute"
  }, props);
  const [sources, setSources] = (0, import_solid_js4.createSignal)([]);
  const [menuItems, setMenuItems] = (0, import_solid_js4.createSignal)([]);
  const listAudioDevices = () => {
    import_livekit_client.Room.getLocalDevices("audioinput").then((devices) => {
      setSources(devices);
      setMenuItems(devices.map((item) => ({ label: item.label })));
    }, console.error);
  };
  (0, import_solid_js4.createEffect)(() => {
    listAudioDevices();
    navigator.mediaDevices.addEventListener("devicechange", listAudioDevices);
    (0, import_solid_js4.onCleanup)(() => {
      navigator.mediaDevices.removeEventListener("devicechange", listAudioDevices);
    });
  });
  const handleMenuItem = (item) => {
    const device = sources().find((source) => source.label === item.label);
    if (device && props.onSourceSelected) {
      props.onSourceSelected(device);
    }
  };
  const AudioSelectIcon = () => <import_solid_js4.Show when={props.isMuted} fallback={<import_fa2.FaSolidMicrophone className="icon" height={32} />}><import_fa2.FaSolidMicrophoneSlash className="icon" height={32} /></import_solid_js4.Show>;
  return <ControlButton label={props.isMuted ? mergedProps.unmuteText : mergedProps.muteText} icon={<AudioSelectIcon />} onClick={props.onClick} menuItems={menuItems()} onMenuItemClick={handleMenuItem} className={props.className} popoverContainerClassName={props.popoverContainerClassName} popoverTriggerBtnClassName={props.popoverTriggerBtnClassName} popoverTriggerBtnSeparatorClassName={props.popoverTriggerBtnSeparatorClassName} />;
};

// src/components/ControlsView.tsx
var import_solid_js7 = __toModule(require("solid-js"));
var import_fa4 = __toModule(require("solid-icons/fa"));

// src/signals/createParticipant.ts
var import_solid_js5 = __toModule(require("solid-js"));
var import_livekit_client2 = __toModule(require("livekit-client"));
function createParticipant(participant) {
  const [isAudioMuted, setIsAudioMuted] = (0, import_solid_js5.createSignal)(false);
  const [isVideoMuted, setIsVideoMuted] = (0, import_solid_js5.createSignal)(false);
  const [connectionQuality, setConnectionQuality] = (0, import_solid_js5.createSignal)(participant.connectionQuality);
  const [isSpeaking, setSpeaking] = (0, import_solid_js5.createSignal)(false);
  const [metadata, setMetadata] = (0, import_solid_js5.createSignal)();
  const [publications, setPublications] = (0, import_solid_js5.createSignal)([]);
  const [subscribedTracks, setSubscribedTracks] = (0, import_solid_js5.createSignal)([]);
  const onPublicationsChanged = () => {
    const participantTracks = Array.from(participant.tracks.values());
    setPublications(participantTracks);
    setSubscribedTracks(participantTracks.filter((pub) => pub.isSubscribed && pub.track !== void 0));
  };
  const onMuted = (publication) => {
    if (publication.kind === import_livekit_client2.Track.Kind.Audio) {
      setIsAudioMuted(true);
    } else if (publication.kind === import_livekit_client2.Track.Kind.Video) {
      setIsVideoMuted(true);
    }
  };
  const onUnmuted = (publication) => {
    if (publication.kind === import_livekit_client2.Track.Kind.Audio) {
      setIsAudioMuted(false);
    } else if (publication.kind === import_livekit_client2.Track.Kind.Video) {
      setIsVideoMuted(false);
    }
  };
  const onMetadataChanged = () => {
    if (participant.metadata) {
      setMetadata(participant.metadata);
    }
  };
  const onIsSpeakingChanged = () => {
    setSpeaking(participant.isSpeaking);
  };
  const onConnectionQualityUpdate = () => {
    setConnectionQuality(participant.connectionQuality);
  };
  (0, import_solid_js5.createEffect)(() => {
    participant.on(import_livekit_client2.ParticipantEvent.TrackMuted, onMuted).on(import_livekit_client2.ParticipantEvent.TrackUnmuted, onUnmuted).on(import_livekit_client2.ParticipantEvent.ParticipantMetadataChanged, onMetadataChanged).on(import_livekit_client2.ParticipantEvent.IsSpeakingChanged, onIsSpeakingChanged).on(import_livekit_client2.ParticipantEvent.TrackPublished, onPublicationsChanged).on(import_livekit_client2.ParticipantEvent.TrackUnpublished, onPublicationsChanged).on(import_livekit_client2.ParticipantEvent.TrackSubscribed, onPublicationsChanged).on(import_livekit_client2.ParticipantEvent.TrackUnsubscribed, onPublicationsChanged).on(import_livekit_client2.ParticipantEvent.LocalTrackPublished, onPublicationsChanged).on(import_livekit_client2.ParticipantEvent.LocalTrackUnpublished, onPublicationsChanged).on(import_livekit_client2.ParticipantEvent.ConnectionQualityChanged, onConnectionQualityUpdate);
    onMetadataChanged();
    onIsSpeakingChanged();
    onPublicationsChanged();
  });
  (0, import_solid_js5.onCleanup)(() => {
    participant.off(import_livekit_client2.ParticipantEvent.TrackMuted, onMuted).off(import_livekit_client2.ParticipantEvent.TrackUnmuted, onUnmuted).off(import_livekit_client2.ParticipantEvent.ParticipantMetadataChanged, onMetadataChanged).off(import_livekit_client2.ParticipantEvent.IsSpeakingChanged, onIsSpeakingChanged).off(import_livekit_client2.ParticipantEvent.TrackPublished, onPublicationsChanged).off(import_livekit_client2.ParticipantEvent.TrackUnpublished, onPublicationsChanged).off(import_livekit_client2.ParticipantEvent.TrackSubscribed, onPublicationsChanged).off(import_livekit_client2.ParticipantEvent.TrackUnsubscribed, onPublicationsChanged).off(import_livekit_client2.ParticipantEvent.LocalTrackPublished, onPublicationsChanged).off(import_livekit_client2.ParticipantEvent.LocalTrackUnpublished, onPublicationsChanged).off(import_livekit_client2.ParticipantEvent.ConnectionQualityChanged, onConnectionQualityUpdate);
  });
  (0, import_solid_js5.createEffect)(() => {
    let muted;
    participant.audioTracks.forEach((publication) => {
      muted = publication.isMuted;
    });
    if (typeof muted === "undefined") {
      muted = true;
    }
    setIsAudioMuted((currentValue) => {
      if (currentValue !== muted) {
        return !!muted;
      }
      return currentValue;
    });
    setIsVideoMuted((currentValue) => {
      if (currentValue !== muted) {
        return !!muted;
      }
      return currentValue;
    });
  });
  return () => ({
    isLocal: participant instanceof import_livekit_client2.LocalParticipant,
    isSpeaking: isSpeaking(),
    isAudioMuted: isAudioMuted(),
    isVideoMuted: isVideoMuted(),
    connectionQuality: connectionQuality(),
    publications: publications(),
    subscribedTracks: subscribedTracks(),
    cameraPublication: participant.getTrack(import_livekit_client2.Track.Source.Camera),
    microphonePublication: participant.getTrack(import_livekit_client2.Track.Source.Microphone),
    screenSharePublication: participant.getTrack(import_livekit_client2.Track.Source.ScreenShare),
    metadata: metadata(),
    tracks: participant.tracks
  });
}

// src/components/VideoSelectButton.tsx
var import_solid_js6 = __toModule(require("solid-js"));
var import_fa3 = __toModule(require("solid-icons/fa"));
var import_livekit_client3 = __toModule(require("livekit-client"));
var VideoSelectButton = (props) => {
  const mergedProps = (0, import_solid_js6.mergeProps)({
    disableText: "Disable Video",
    enableText: "Enable Video"
  }, props);
  const [sources, setSources] = (0, import_solid_js6.createSignal)([]);
  const [menuItems, setMenuItems] = (0, import_solid_js6.createSignal)([]);
  const listVideoDevices = () => {
    import_livekit_client3.Room.getLocalDevices("videoinput").then((devices) => {
      setSources(devices);
      setMenuItems(devices.map((item) => ({ label: item.label })));
    }, console.error);
  };
  (0, import_solid_js6.createEffect)(() => {
    listVideoDevices();
    navigator.mediaDevices.addEventListener("devicechange", listVideoDevices);
    (0, import_solid_js6.onCleanup)(() => {
      navigator.mediaDevices.removeEventListener("devicechange", listVideoDevices);
    });
  });
  const handleMenuItem = (item) => {
    const device = sources().find((source) => source.label === item.label);
    if (device && props.onSourceSelected) {
      props.onSourceSelected(device);
    }
  };
  const VideoSelectedIcon = () => <import_solid_js6.Show when={props.isEnabled} fallback={<import_fa3.FaSolidVideoSlash className="icon" height={32} />}><import_fa3.FaSolidVideo className="icon" height={32} /></import_solid_js6.Show>;
  return <ControlButton label={props.isEnabled ? mergedProps.disableText : mergedProps.enableText} icon={<VideoSelectedIcon />} onClick={props.onClick} menuItems={menuItems()} onMenuItemClick={handleMenuItem} className={props.className} popoverContainerClassName={props.popoverContainerClassName} popoverTriggerBtnClassName={props.popoverTriggerBtnClassName} popoverTriggerBtnSeparatorClassName={props.popoverTriggerBtnSeparatorClassName} />;
};

// src/components/ControlsView.tsx
var ControlsView = (props) => {
  const mergedProps = (0, import_solid_js7.mergeProps)({
    enableScreenShare: true,
    enableVideo: true,
    enableAudio: true
  }, props);
  const participant = createParticipant(props.room.localParticipant);
  const cameraPublication = () => participant().cameraPublication;
  const MuteButton = () => {
    const enabled = props.room.localParticipant.isMicrophoneEnabled;
    return <import_solid_js7.Show when={mergedProps.enableAudio}><AudioSelectButton isMuted={!enabled} onClick={() => props.room.localParticipant.setMicrophoneEnabled(!enabled)} onSourceSelected={(device) => props.room.switchActiveDevice("audioinput", device.deviceId)} /></import_solid_js7.Show>;
  };
  const VideoButton = () => {
    var _a, _b;
    const enabled = !((_b = (_a = cameraPublication()) == null ? void 0 : _a.isMuted) != null ? _b : true);
    return <import_solid_js7.Show when={mergedProps.enableVideo}><VideoSelectButton isEnabled={enabled} onClick={() => props.room.localParticipant.setCameraEnabled(!enabled)} onSourceSelected={(device) => {
      props.room.switchActiveDevice("videoinput", device.deviceId).catch(console.error);
    }} /></import_solid_js7.Show>;
  };
  const ScreenButton = () => {
    const enabled = props.room.localParticipant.isScreenShareEnabled;
    const ScreenButtonIcon = () => <import_solid_js7.Show when={enabled} fallback={<import_fa4.FaSolidDesktop className="icon" height={32} />}><import_fa4.FaSolidStop className="icon" height={32} /></import_solid_js7.Show>;
    return <import_solid_js7.Show when={mergedProps.enableScreenShare}><ControlButton label={enabled ? "Stop sharing" : "Share screen"} icon={<ScreenButtonIcon />} onClick={() => {
      if (enabled) {
        props.room.localParticipant.setScreenShareEnabled(false).catch(console.error);
      } else {
        props.room.localParticipant.setScreenShareEnabled(true).catch(console.error);
      }
    }} /></import_solid_js7.Show>;
  };
  return <div className="controlsWrapper">
    <MuteButton />
    <VideoButton />
    <ScreenButton />
    <import_solid_js7.Show when={props.onLeave}>{(onLeave) => <ControlButton label="End" className="dangerButton" onClick={() => {
      props.room.disconnect();
      onLeave(props.room);
    }} />}</import_solid_js7.Show>
  </div>;
};

// src/components/DisplayContext.tsx
var import_solid_js8 = __toModule(require("solid-js"));
var DisplayContext = (0, import_solid_js8.createContext)({
  stageLayout: "grid",
  showStats: false
});
var useDisplay = () => (0, import_solid_js8.useContext)(DisplayContext);

// src/components/ParticipantView.tsx
var import_solid_js10 = __toModule(require("solid-js"));
var import_solid_aspect_ratio = __toModule(require("solid-aspect-ratio"));
var import_fa5 = __toModule(require("solid-icons/fa"));
var import_livekit_client4 = __toModule(require("livekit-client"));

// src/components/ConnectionQualityLow.tsx
function ConnectionQualityLow() {
  return <svg width="9" height="9" viewBox="0 0 9 9" fill="none" xmlns="http://www.w3.org/2000/svg">
    <path d="M0 6H2V9H0V6Z" fill="#981010" />
    <path d="M3.5 3H5.5V9H3.5V3Z" fill="#1A1B1D" />
    <path d="M7 0H9V9H7V0Z" fill="#1A1B1D" />
  </svg>;
}

// src/components/ConnectionQualityMid.tsx
function ConnectionQualityMid() {
  return <svg width="9" height="9" viewBox="0 0 9 9" fill="none" xmlns="http://www.w3.org/2000/svg">
    <path d="M0 6H2V9H0V6Z" fill="#F89C13" />
    <path d="M3.5 3H5.5V9H3.5V3Z" fill="#F89C13" />
    <path d="M7 0H9V9H7V0Z" fill="#1A1B1D" />
  </svg>;
}

// src/components/ConnectionQualityHigh.tsx
function ConnectionQualityHigh() {
  return <svg width="9" height="9" viewBox="0 0 9 9" fill="none" xmlns="http://www.w3.org/2000/svg">
    <path d="M0 6H2V9H0V6Z" fill="#28994E" />
    <path d="M3.5 3H5.5V9H3.5V3Z" fill="#28994E" />
    <path d="M7 0H9V9H7V0Z" fill="#28994E" />
  </svg>;
}

// src/components/VideoRenderer.tsx
var import_solid_js9 = __toModule(require("solid-js"));
var VideoRenderer = (props) => {
  var _a, _b;
  const [ref, setRef] = (0, import_solid_js9.createSignal)(null);
  (0, import_solid_js9.createEffect)(() => {
    const videoElement = ref();
    if (videoElement) {
      videoElement.muted = true;
      props.track.attach(videoElement);
    }
    (0, import_solid_js9.onCleanup)(() => {
      if (videoElement) {
        props.track.detach(videoElement);
      }
    });
  });
  const handleResize = (event) => {
    if (event.target instanceof HTMLVideoElement) {
      if (props.onSizeChanged) {
        props.onSizeChanged(event.target.videoWidth, event.target.videoHeight);
      }
    }
  };
  (0, import_solid_js9.createEffect)(() => {
    const videoElement = ref();
    if (videoElement) {
      videoElement.addEventListener("resize", handleResize);
    }
    (0, import_solid_js9.onCleanup)(() => {
      videoElement == null ? void 0 : videoElement.removeEventListener("resize", handleResize);
    });
  });
  const isFrontFacing = ((_a = props.track.mediaStreamTrack) == null ? void 0 : _a.getSettings().facingMode) !== "environment";
  const style = () => {
    const currentStyle = {
      transform: props.isLocal && isFrontFacing ? "rotateY(180deg)" : "",
      width: props.width,
      height: props.height
    };
    if (props.objectFit) {
      currentStyle["object-fit"] = props.objectFit;
    }
    return currentStyle;
  };
  return <video ref={setRef} className={(_b = props.className) != null ? _b : "video"} style={style()} />;
};

// src/components/ParticipantView.tsx
var ParticipantView = (props) => {
  var _a;
  const participant = createParticipant(props.participant);
  const [videoSize, setVideoSize] = (0, import_solid_js10.createSignal)();
  const [currentBitrate, setCurrentBitrate] = (0, import_solid_js10.createSignal)();
  const [objectFit, setObjectFit] = (0, import_solid_js10.createSignal)("contain");
  const [videoOrientation, setVideoOrientation] = (0, import_solid_js10.createSignal)();
  const [displayName, setDisplayName] = (0, import_solid_js10.createSignal)(props.displayName);
  const display = useDisplay();
  const handleResize = (width, height) => {
    setVideoSize(`${width}x${height}`);
  };
  (0, import_solid_js10.createEffect)(() => {
    const interval = setInterval(() => {
      let total = 0;
      props.participant.tracks.forEach((pub) => {
        if (pub.track instanceof import_livekit_client4.LocalTrack || pub.track instanceof import_livekit_client4.RemoteTrack) {
          total += pub.track.currentBitrate;
        }
      });
      setCurrentBitrate(total);
    }, 1e3);
    (0, import_solid_js10.onCleanup)(() => clearInterval(interval));
  });
  const containerStyles = {
    width: props.width,
    height: props.height
  };
  let { orientation } = props;
  if (!props.orientation && props.aspectWidth && props.aspectHeight) {
    orientation = props.aspectWidth > props.aspectHeight ? "landscape" : "portrait";
  }
  (0, import_solid_js10.createEffect)(() => {
    var _a2;
    const dimensions = (_a2 = participant().cameraPublication) == null ? void 0 : _a2.dimensions;
    if (dimensions) {
      const orientationValue = dimensions.width > dimensions.height ? "landscape" : "portrait";
      setVideoOrientation(orientationValue);
    }
  });
  (0, import_solid_js10.createEffect)(() => {
    if (videoOrientation() === orientation) {
      setObjectFit("cover");
    }
  });
  (0, import_solid_js10.createEffect)(() => {
    setDisplayName((current) => {
      if (!current) {
        const suffix = participant().isLocal ? " (You)" : "";
        return `${props.participant.name || props.participant.identity}${suffix}`;
      }
      return current;
    });
  });
  const MainElement = () => {
    var _a2, _b, _c;
    const publication = () => participant().cameraPublication;
    return <import_solid_js10.Show when={((_a2 = publication()) == null ? void 0 : _a2.isSubscribed) && !((_b = publication()) == null ? void 0 : _b.isMuted) && ((_c = publication()) == null ? void 0 : _c.track)} fallback={<div className="placeholder" />}>{(track) => <VideoRenderer track={track} isLocal={participant().isLocal} objectFit={objectFit()} width="100%" height="100%" onSizeChanged={handleResize} />}</import_solid_js10.Show>;
  };
  const speakerClassName = props.speakerClassName || "speaker";
  return <div classList={{
    participant: true,
    [(_a = props.className) != null ? _a : ""]: !!props.className,
    [speakerClassName]: participant().isSpeaking
  }} style={containerStyles} onMouseEnter={props.onMouseEnter} onMouseLeave={props.onMouseLeave} onClick={props.onClick}>
    <import_solid_js10.Show when={props.aspectWidth} fallback={<MainElement />}>{(aspectWidth) => <import_solid_js10.Show when={props.aspectHeight} fallback={<MainElement />}>{(aspectHeight) => <import_solid_aspect_ratio.default ratio={aspectWidth / aspectHeight}><MainElement /></import_solid_aspect_ratio.default>}</import_solid_js10.Show>}</import_solid_js10.Show>
    <import_solid_js10.Show when={props.showOverlay || display.showStats}><div className="participantBar">
      <div className="name">{displayName}</div>
      <div className="center"><import_solid_js10.Show when={display.showStats}><div className="stats">
        <div>{videoSize}</div>
        <import_solid_js10.Show when={currentBitrate()}>{(bitrate) => <import_solid_js10.Show when={bitrate > 0}><div>
          {Math.round(bitrate / 1024)}
          {" kbps"}
        </div></import_solid_js10.Show>}</import_solid_js10.Show>
      </div></import_solid_js10.Show></div>
      <div><import_solid_js10.Show when={props.showConnectionQuality}><import_solid_js10.Switch>
        <import_solid_js10.Match when={participant().connectionQuality === import_livekit_client4.ConnectionQuality.Excellent}><ConnectionQualityHigh /></import_solid_js10.Match>
        <import_solid_js10.Match when={participant().connectionQuality === import_livekit_client4.ConnectionQuality.Good}><ConnectionQualityMid /></import_solid_js10.Match>
        <import_solid_js10.Match when={participant().connectionQuality === import_livekit_client4.ConnectionQuality.Poor}><ConnectionQualityLow /></import_solid_js10.Match>
      </import_solid_js10.Switch></import_solid_js10.Show></div>
      <div><import_solid_js10.Show when={props.participant.isMicrophoneEnabled} fallback={<import_fa5.FaSolidMicrophoneSlash height={24} className="iconRed" />}><import_fa5.FaSolidMicrophone height={24} className="iconGreen" /></import_solid_js10.Show></div>
    </div></import_solid_js10.Show>
  </div>;
};

// src/components/ScreenShareView.tsx
var ScreenShareView = (props) => <div className="screenShare"><VideoRenderer track={props.track} isLocal={false} width={props.width} height={props.height} /></div>;

// src/components/StageView.tsx
var import_solid_js14 = __toModule(require("solid-js"));
var import_fa6 = __toModule(require("solid-icons/fa"));
var import_livekit_client7 = __toModule(require("livekit-client"));
var import_media = __toModule(require("@solid-primitives/media"));

// src/components/desktop/GridStage.tsx
var import_solid_js11 = __toModule(require("solid-js"));
var GridStage = (props) => {
  const [visibleParticipants, setVisibleParticipants] = (0, import_solid_js11.createSignal)([]);
  const [showOverlay, setShowOverlay] = (0, import_solid_js11.createSignal)(false);
  const [gridClass, setGridClass] = (0, import_solid_js11.createSignal)("grid1x1");
  (0, import_solid_js11.createEffect)(() => {
    let numVisible = 1;
    const participantCount = props.roomState.participants.length;
    if (participantCount === 1) {
      setGridClass("grid1x1");
    } else if (participantCount === 2) {
      setGridClass("grid2x1");
      numVisible = 2;
    } else if (participantCount <= 4) {
      setGridClass("grid2x2");
      numVisible = Math.min(participantCount, 4);
    } else if (participantCount <= 9) {
      setGridClass("grid3x3");
      numVisible = Math.min(participantCount, 9);
    } else if (participantCount <= 16) {
      setGridClass("grid4x4");
      numVisible = Math.min(participantCount, 16);
    } else {
      setGridClass("grid5x5");
      numVisible = Math.min(participantCount, 25);
    }
    setVisibleParticipants((current) => {
      var _a;
      const newParticipants = [];
      const currentRoom = props.roomState.room();
      current.forEach((p) => {
        if ((currentRoom == null ? void 0 : currentRoom.participants.has(p.sid)) || (currentRoom == null ? void 0 : currentRoom.localParticipant.sid) === p.sid) {
          newParticipants.push(p);
        }
      });
      (_a = currentRoom == null ? void 0 : currentRoom.activeSpeakers) == null ? void 0 : _a.forEach((speaker) => {
        if (newParticipants.includes(speaker) || speaker !== (currentRoom == null ? void 0 : currentRoom.localParticipant) && !(currentRoom == null ? void 0 : currentRoom.participants.has(speaker.sid))) {
          return;
        }
        const idx = newParticipants.findIndex((participant) => !participant.isSpeaking);
        if (idx >= 0) {
          newParticipants[idx] = speaker;
        } else {
          newParticipants.push(speaker);
        }
      });
      props.roomState.participants().forEach((participant) => {
        const isFull = newParticipants.length >= numVisible;
        const isVisible = newParticipants.includes(participant) || participant.isSpeaking;
        if (!isFull && !isVisible) {
          newParticipants.push(participant);
        }
      });
      if (newParticipants.length > numVisible) {
        newParticipants.splice(numVisible, newParticipants.length - numVisible);
      }
      return newParticipants;
    });
  });
  return <import_solid_js11.Switch fallback={() => {
    var _a, _b;
    const ParticipantRenderer = (_a = props.participantRenderer) != null ? _a : ParticipantView;
    const ControlRenderer = (_b = props.controlRenderer) != null ? _b : ControlsView;
    return <div className="container">
      <div className={`gridStage ${gridClass()}`}><import_solid_js11.For each={visibleParticipants()}>{(participant) => <ParticipantRenderer participant={participant} orientation="landscape" width="100%" height="100%" showOverlay={showOverlay()} showConnectionQuality onMouseEnter={() => setShowOverlay(true)} onMouseLeave={() => setShowOverlay(false)} />}</import_solid_js11.For></div>
      <div className="controlsArea"><import_solid_js11.Show when={props.roomState.room()}>{(room) => <ControlRenderer room={room} onLeave={props.onLeave} />}</import_solid_js11.Show></div>
    </div>;
  }}>
    <import_solid_js11.Match when={props.roomState.error()}>{(error) => <div>
      {"error:"}
      {" "}
      {error == null ? void 0 : error.message}
    </div>}</import_solid_js11.Match>
    <import_solid_js11.Match when={props.roomState.isConnecting()}>{() => <div>connecting</div>}</import_solid_js11.Match>
    <import_solid_js11.Match when={!props.roomState.room()}>{() => <div>room closed</div>}</import_solid_js11.Match>
    <import_solid_js11.Match when={!props.roomState.participants().length}>{() => <div>no one is in the room</div>}</import_solid_js11.Match>
  </import_solid_js11.Switch>;
};

// src/components/desktop/SpeakerStage.tsx
var import_solid_js12 = __toModule(require("solid-js"));
var import_livekit_client5 = __toModule(require("livekit-client"));
var SpeakerStage = (props) => {
  const [showOverlay, setShowOverlay] = (0, import_solid_js12.createSignal)(false);
  return <import_solid_js12.Switch fallback={() => {
    var _a, _b;
    const ParticipantRenderer = (_a = props.participantRenderer) != null ? _a : ParticipantView;
    const ControlRenderer = (_b = props.controlRenderer) != null ? _b : ControlsView;
    const [screenTrack, setScreenTrack] = (0, import_solid_js12.createSignal)();
    (0, import_solid_js12.createEffect)(() => {
      props.roomState.participants().forEach((participant) => {
        setScreenTrack((current) => {
          if (!current) {
            const track = participant.getTrack(import_livekit_client5.Track.Source.ScreenShare);
            if ((track == null ? void 0 : track.isSubscribed) && track.videoTrack) {
              return track.videoTrack;
            }
          }
          return current;
        });
      });
    });
    const otherParticipants = props.roomState.participants;
    const MainView = () => <import_solid_js12.Show when={screenTrack()} fallback={<import_solid_js12.Show when={props.roomState.participants()[0]}>{(participant) => <ParticipantRenderer participant={participant} width="100%" height="100%" orientation="landscape" showOverlay={showOverlay()} showConnectionQuality onMouseEnter={() => setShowOverlay(true)} onMouseLeave={() => setShowOverlay(false)} />}</import_solid_js12.Show>}>{(track) => <ScreenShareView track={track} height="100%" width="100%" />}</import_solid_js12.Show>;
    return <div className="container">
      <div className="stage">
        <div className="stageCenter"><MainView /></div>
        <div className="sidebar"><import_solid_js12.For each={otherParticipants()}>{(participant) => <ParticipantRenderer participant={participant} width="100%" aspectWidth={16} aspectHeight={9} showOverlay={showOverlay()} onMouseEnter={() => setShowOverlay(true)} onMouseLeave={() => setShowOverlay(false)} />}</import_solid_js12.For></div>
      </div>
      <div className="controlsArea"><import_solid_js12.Show when={props.roomState.room()}>{(room) => <ControlRenderer room={room} enableScreenShare={false} onLeave={props.onLeave} />}</import_solid_js12.Show></div>
    </div>;
  }}>
    <import_solid_js12.Match when={props.roomState.error()}>{(error) => <div>
      {"error:"}
      {" "}
      {error == null ? void 0 : error.message}
    </div>}</import_solid_js12.Match>
    <import_solid_js12.Match when={props.roomState.isConnecting()}>{() => <div>connecting</div>}</import_solid_js12.Match>
    <import_solid_js12.Match when={!props.roomState.room()}>{() => <div>room closed</div>}</import_solid_js12.Match>
    <import_solid_js12.Match when={!props.roomState.participants().length}>{() => <div>no one is in the room</div>}</import_solid_js12.Match>
  </import_solid_js12.Switch>;
};

// src/components/mobile/MobileStage.tsx
var import_solid_js13 = __toModule(require("solid-js"));
var import_livekit_client6 = __toModule(require("livekit-client"));
var MobileStage = (props) => {
  const [showOverlay, setShowOverlay] = (0, import_solid_js13.createSignal)(false);
  return <import_solid_js13.Switch fallback={() => {
    var _a, _b;
    const ParticipantRenderer = (_a = props.participantRenderer) != null ? _a : ParticipantView;
    const ControlRenderer = (_b = props.controlRenderer) != null ? _b : ControlsView;
    const [screenTrack, setScreenTrack] = (0, import_solid_js13.createSignal)();
    (0, import_solid_js13.createEffect)(() => {
      props.roomState.participants().forEach((participant) => {
        setScreenTrack((current) => {
          if (!current) {
            const track = participant.getTrack(import_livekit_client6.Track.Source.ScreenShare);
            if ((track == null ? void 0 : track.isSubscribed) && track.videoTrack) {
              return track.videoTrack;
            }
          }
          return current;
        });
      });
    });
    const otherParticipants = props.roomState.participants;
    const MainView = () => <import_solid_js13.Show when={screenTrack()} fallback={<import_solid_js13.Show when={props.roomState.participants()[0]}>{(participant) => <ParticipantRenderer participant={participant} showOverlay={showOverlay()} width="100%" height="100%" orientation="portrait" showConnectionQuality onMouseEnter={() => setShowOverlay(true)} onMouseLeave={() => setShowOverlay(false)} />}</import_solid_js13.Show>}>{(track) => <ScreenShareView track={track} height="100%" width="100%" />}</import_solid_js13.Show>;
    return <div className="container">
      <div className="stage"><MainView /></div>
      <div className="participantsArea"><import_solid_js13.For each={otherParticipants()}>{(participant) => <ParticipantRenderer participant={participant} className="participant" aspectWidth={4} aspectHeight={3} showOverlay={showOverlay()} onMouseEnter={() => setShowOverlay(true)} onMouseLeave={() => setShowOverlay(false)} />}</import_solid_js13.For></div>
      <div className="controlsArea"><import_solid_js13.Show when={props.roomState.room()}>{(room) => <ControlRenderer room={room} enableScreenShare={false} onLeave={props.onLeave} />}</import_solid_js13.Show></div>
    </div>;
  }}>
    <import_solid_js13.Match when={props.roomState.error()}>{(error) => <div>
      {"error:"}
      {" "}
      {error == null ? void 0 : error.message}
    </div>}</import_solid_js13.Match>
    <import_solid_js13.Match when={props.roomState.isConnecting()}>{() => <div>connecting</div>}</import_solid_js13.Match>
    <import_solid_js13.Match when={!props.roomState.room()}>{() => <div>room closed</div>}</import_solid_js13.Match>
    <import_solid_js13.Match when={!props.roomState.participants().length}>{() => <div>no one is in the room</div>}</import_solid_js13.Match>
  </import_solid_js13.Switch>;
};

// src/components/StageView.tsx
var StageView = (props) => {
  var _a;
  const isDesktop = (0, import_media.default)("(min-width: 800px)");
  const display = useDisplay();
  const MainElement = () => <import_solid_js14.Show when={isDesktop()} fallback={<MobileStage {...props} />}>{() => {
    const [screenTrack, setScreenTrack] = (0, import_solid_js14.createSignal)();
    (0, import_solid_js14.createEffect)(() => {
      props.roomState.participants().forEach((participant) => {
        setScreenTrack((current) => {
          if (!current) {
            const track = participant.getTrack(import_livekit_client7.Track.Source.ScreenShare);
            if ((track == null ? void 0 : track.isSubscribed) && track.videoTrack) {
              return track.videoTrack;
            }
          }
          return current;
        });
      });
    });
    return <import_solid_js14.Show when={display.stageLayout === "grid" && screenTrack === void 0} fallback={<SpeakerStage {...props} />}><GridStage {...props} /></import_solid_js14.Show>;
  }}</import_solid_js14.Show>;
  return <div className="container">
    <MainElement />
    <import_solid_js14.For each={props.roomState.audioTracks()}>{(track) => <AudioRenderer track={track} isLocal={false} />}</import_solid_js14.For>
    <import_solid_js14.Show when={((_a = props.roomState.room()) == null ? void 0 : _a.canPlaybackAudio) === false}><div className="overlay"><button className="unmuteButton" onClick={() => {
      var _a2;
      (_a2 = props.roomState.room()) == null ? void 0 : _a2.startAudio().catch(console.error);
    }}>
      <import_fa6.FaSolidVolumeMute className="icon" size="1x" />
      {"Click to Unmute"}
    </button></div></import_solid_js14.Show>
  </div>;
};

// src/LiveKitRoom.tsx
var import_solid_js16 = __toModule(require("solid-js"));

// src/signals/createRoom.ts
var import_solid_js15 = __toModule(require("solid-js"));
var import_livekit_client8 = __toModule(require("livekit-client"));

// src/utils/sortParticipants.ts
function sortParticipants(participants, localParticipant) {
  participants.sort((a, b) => {
    var _a, _b, _c, _d, _e, _f, _g, _h;
    if (a.isSpeaking && b.isSpeaking) {
      return b.audioLevel - a.audioLevel;
    }
    if (a.isSpeaking !== b.isSpeaking) {
      if (a.isSpeaking) {
        return -1;
      }
      return 1;
    }
    if (a.lastSpokeAt !== b.lastSpokeAt) {
      const aLast = (_b = (_a = a.lastSpokeAt) == null ? void 0 : _a.getTime()) != null ? _b : 0;
      const bLast = (_d = (_c = b.lastSpokeAt) == null ? void 0 : _c.getTime()) != null ? _d : 0;
      return bLast - aLast;
    }
    const aVideo = a.videoTracks.size > 0;
    const bVideo = b.videoTracks.size > 0;
    if (aVideo !== bVideo) {
      if (aVideo) {
        return -1;
      }
      return 1;
    }
    return ((_f = (_e = a.joinedAt) == null ? void 0 : _e.getTime()) != null ? _f : 0) - ((_h = (_g = b.joinedAt) == null ? void 0 : _g.getTime()) != null ? _h : 0);
  });
  if (localParticipant) {
    const localIdx = participants.indexOf(localParticipant);
    if (localIdx >= 0) {
      participants.splice(localIdx, 1);
      if (participants.length > 0) {
        participants.splice(1, 0, localParticipant);
      } else {
        participants.push(localParticipant);
      }
    }
  }
}

// src/signals/createRoom.ts
function createRoom(options) {
  var _a;
  const [room, setRoom] = (0, import_solid_js15.createSignal)();
  const [isConnecting, setIsConnecting] = (0, import_solid_js15.createSignal)(false);
  const [error, setError] = (0, import_solid_js15.createSignal)();
  const [participants, setParticipants] = (0, import_solid_js15.createSignal)([]);
  const [audioTracks, setAudioTracks] = (0, import_solid_js15.createSignal)([]);
  const sortFunction = (_a = options == null ? void 0 : options.sortParticipants) != null ? _a : sortParticipants;
  const connectFunction = async (url, token, connectOptions) => {
    setIsConnecting(true);
    try {
      const newRoom = await (0, import_livekit_client8.connect)(url, token, connectOptions);
      setRoom(newRoom);
      const onParticipantsChanged = () => {
        const remotes = Array.from(newRoom.participants.values());
        const localParticipants = [newRoom.localParticipant, ...remotes];
        sortFunction(localParticipants, newRoom.localParticipant);
        setParticipants(localParticipants);
      };
      const onSubscribedTrackChanged = (track) => {
        onParticipantsChanged();
        if (!track || track.kind === import_livekit_client8.Track.Kind.Audio) {
          const tracks = [];
          newRoom.participants.forEach((participant) => {
            participant.audioTracks.forEach(({ audioTrack }) => {
              if (audioTrack) {
                tracks.push(audioTrack);
              }
            });
          });
          setAudioTracks(tracks);
        }
      };
      newRoom.once("disconnected", () => {
        const timeoutId = setTimeout(() => setRoom(void 0));
        newRoom.off("participantConnected", onParticipantsChanged).off("participantDisconnected", onParticipantsChanged).off("activeSpeakersChanged", onParticipantsChanged).off("trackSubscribed", onSubscribedTrackChanged).off("trackUnsubscribed", onSubscribedTrackChanged).off("localTrackPublished", onParticipantsChanged).off("localTrackUnpublished", onParticipantsChanged).off("audioPlaybackChanged", onParticipantsChanged);
        (0, import_solid_js15.onCleanup)(() => clearTimeout(timeoutId));
      });
      newRoom.on("participantConnected", onParticipantsChanged).on("participantDisconnected", onParticipantsChanged).on("activeSpeakersChanged", onParticipantsChanged).on("trackSubscribed", onSubscribedTrackChanged).on("trackUnsubscribed", onSubscribedTrackChanged).on("localTrackPublished", onParticipantsChanged).on("localTrackUnpublished", onParticipantsChanged).on("audioPlaybackChanged", onParticipantsChanged);
      setIsConnecting(false);
      onSubscribedTrackChanged();
      return newRoom;
    } catch (err) {
      setIsConnecting(false);
      if (err instanceof Error) {
        setError(err);
      } else {
        setError(new Error("an error has occured"));
      }
      return void 0;
    }
  };
  return {
    connect: connectFunction,
    isConnecting,
    room,
    error,
    participants,
    audioTracks
  };
}

// src/LiveKitRoom.tsx
var LiveKitRoom = (props) => {
  var _a;
  const mergedProps = (0, import_solid_js16.mergeProps)({ connectOptions: {} }, props);
  const roomState = createRoom({ sortParticipants: props.sortParticipants });
  (0, import_solid_js16.createEffect)(async () => {
    try {
      const room = await roomState.connect(props.url, props.token, mergedProps.connectOptions);
      if (!room) {
        return;
      }
      if (props.onConnected) {
        props.onConnected(room);
      }
      (0, import_solid_js16.onCleanup)(() => {
        room.disconnect();
      });
    } catch (error) {
      console.error(error);
    }
  });
  const selectedStageRenderer = (_a = props.stageRenderer) != null ? _a : StageView;
  return selectedStageRenderer({
    roomState,
    participantRenderer: props.participantRenderer,
    controlRenderer: props.controlRenderer,
    onLeave: props.onLeave
  });
};
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
  AudioRenderer,
  AudioSelectButton,
  ControlButton,
  ControlsView,
  DisplayContext,
  LiveKitRoom,
  ParticipantView,
  ScreenShareView,
  StageView,
  VideoRenderer,
  VideoSelectButton,
  createParticipant,
  createRoom,
  sortParticipants,
  useDisplay
});
//# sourceMappingURL=index.jsx.map
