@ct-player/embed 1.2.0 → 1.2.2
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.
- package/dist/index.cjs +193 -70
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +763 -226
- package/dist/index.d.ts +763 -226
- package/dist/index.js +193 -70
- package/dist/index.js.map +1 -1
- package/dist/styles.css +1 -1
- package/dist/styles.css.map +1 -1
- package/package.json +6 -7
- package/README.md +0 -284
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import * as
|
|
2
|
-
import
|
|
1
|
+
import * as React__default from 'react';
|
|
2
|
+
import React__default__default from 'react';
|
|
3
3
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
4
4
|
import Hls from 'hls.js';
|
|
5
5
|
|
|
@@ -11,7 +11,7 @@ import Hls from 'hls.js';
|
|
|
11
11
|
/**
|
|
12
12
|
* All possible event types in the .ct format
|
|
13
13
|
*/
|
|
14
|
-
type CTEventType = 'init' | 'code' | 'code_edit' | 'language' | 'terminal' | 'terminal_input' | 'stroke_start' | 'whiteboard_points' | 'stroke_end' | 'whiteboard_stroke' | 'whiteboard_clear' | 'whiteboard_undo' | 'whiteboard' | 'whiteboard_point' | 'excalidraw_scene' | 'excalidraw_clear' | 'document_load' | 'document_page' | 'document_zoom' | 'document_scroll' | 'document_clear' | 'file_create' | 'file_update' | 'file_delete' | 'file_rename' | 'file_switch' | 'folder_create' | 'folder_delete' | 'file_select' | 'file_change' | 'file_creation_start' | 'file_creation_input' | 'file_creation_cancel' | 'file_rename_start' | 'file_rename_input' | 'file_rename_cancel' | 'folder_toggle' | 'cursor_move' | 'cursor_click' | 'cursor_enter' | 'cursor_leave' | 'file_hover' | 'text_select' | 'editor_cursor' | 'tool_switch' | 'tool' | 'marker';
|
|
14
|
+
type CTEventType = 'init' | 'code' | 'code_edit' | 'language' | 'terminal' | 'terminal_input' | 'stroke_start' | 'whiteboard_points' | 'stroke_end' | 'whiteboard_stroke' | 'whiteboard_clear' | 'whiteboard_undo' | 'whiteboard' | 'whiteboard_point' | 'excalidraw_scene' | 'excalidraw_clear' | 'excalidraw_pointer' | 'overlay_scene' | 'overlay_clear' | 'overlay_pointer' | 'document_load' | 'document_page' | 'document_zoom' | 'document_scroll' | 'document_clear' | 'file_create' | 'file_update' | 'file_delete' | 'file_rename' | 'file_switch' | 'folder_create' | 'folder_delete' | 'file_select' | 'file_change' | 'file_creation_start' | 'file_creation_input' | 'file_creation_cancel' | 'file_rename_start' | 'file_rename_input' | 'file_rename_cancel' | 'folder_toggle' | 'cursor_move' | 'cursor_click' | 'cursor_enter' | 'cursor_leave' | 'file_hover' | 'text_select' | 'editor_cursor' | 'tool_switch' | 'tool' | 'marker' | 'webcam_state' | 'content_dimensions';
|
|
15
15
|
/**
|
|
16
16
|
* Base event structure with generic type parameter
|
|
17
17
|
*/
|
|
@@ -27,7 +27,7 @@ interface CTEventBase<T extends CTEventType = CTEventType> {
|
|
|
27
27
|
* Discriminated union of all event types.
|
|
28
28
|
* This enables proper type narrowing in switch statements.
|
|
29
29
|
*/
|
|
30
|
-
type CTEvent = CTEventBase<'init'> | CTEventBase<'code'> | CTEventBase<'code_edit'> | CTEventBase<'language'> | CTEventBase<'terminal'> | CTEventBase<'terminal_input'> | CTEventBase<'stroke_start'> | CTEventBase<'whiteboard_points'> | CTEventBase<'stroke_end'> | CTEventBase<'whiteboard_stroke'> | CTEventBase<'whiteboard_clear'> | CTEventBase<'whiteboard_undo'> | CTEventBase<'whiteboard'> | CTEventBase<'whiteboard_point'> | CTEventBase<'excalidraw_scene'> | CTEventBase<'excalidraw_clear'> | CTEventBase<'document_load'> | CTEventBase<'document_page'> | CTEventBase<'document_zoom'> | CTEventBase<'document_scroll'> | CTEventBase<'document_clear'> | CTEventBase<'file_create'> | CTEventBase<'file_update'> | CTEventBase<'file_delete'> | CTEventBase<'file_rename'> | CTEventBase<'file_switch'> | CTEventBase<'folder_create'> | CTEventBase<'folder_delete'> | CTEventBase<'file_select'> | CTEventBase<'file_change'> | CTEventBase<'file_creation_start'> | CTEventBase<'file_creation_input'> | CTEventBase<'file_creation_cancel'> | CTEventBase<'file_rename_start'> | CTEventBase<'file_rename_input'> | CTEventBase<'file_rename_cancel'> | CTEventBase<'folder_toggle'> | CTEventBase<'cursor_move'> | CTEventBase<'cursor_click'> | CTEventBase<'cursor_enter'> | CTEventBase<'cursor_leave'> | CTEventBase<'file_hover'> | CTEventBase<'text_select'> | CTEventBase<'editor_cursor'> | CTEventBase<'tool_switch'> | CTEventBase<'tool'> | CTEventBase<'marker'>;
|
|
30
|
+
type CTEvent = CTEventBase<'init'> | CTEventBase<'code'> | CTEventBase<'code_edit'> | CTEventBase<'language'> | CTEventBase<'terminal'> | CTEventBase<'terminal_input'> | CTEventBase<'stroke_start'> | CTEventBase<'whiteboard_points'> | CTEventBase<'stroke_end'> | CTEventBase<'whiteboard_stroke'> | CTEventBase<'whiteboard_clear'> | CTEventBase<'whiteboard_undo'> | CTEventBase<'whiteboard'> | CTEventBase<'whiteboard_point'> | CTEventBase<'excalidraw_scene'> | CTEventBase<'excalidraw_clear'> | CTEventBase<'excalidraw_pointer'> | CTEventBase<'overlay_scene'> | CTEventBase<'overlay_clear'> | CTEventBase<'overlay_pointer'> | CTEventBase<'document_load'> | CTEventBase<'document_page'> | CTEventBase<'document_zoom'> | CTEventBase<'document_scroll'> | CTEventBase<'document_clear'> | CTEventBase<'file_create'> | CTEventBase<'file_update'> | CTEventBase<'file_delete'> | CTEventBase<'file_rename'> | CTEventBase<'file_switch'> | CTEventBase<'folder_create'> | CTEventBase<'folder_delete'> | CTEventBase<'file_select'> | CTEventBase<'file_change'> | CTEventBase<'file_creation_start'> | CTEventBase<'file_creation_input'> | CTEventBase<'file_creation_cancel'> | CTEventBase<'file_rename_start'> | CTEventBase<'file_rename_input'> | CTEventBase<'file_rename_cancel'> | CTEventBase<'folder_toggle'> | CTEventBase<'cursor_move'> | CTEventBase<'cursor_click'> | CTEventBase<'cursor_enter'> | CTEventBase<'cursor_leave'> | CTEventBase<'file_hover'> | CTEventBase<'text_select'> | CTEventBase<'editor_cursor'> | CTEventBase<'tool_switch'> | CTEventBase<'tool'> | CTEventBase<'marker'> | CTEventBase<'webcam_state'> | CTEventBase<'content_dimensions'>;
|
|
31
31
|
/**
|
|
32
32
|
* Mapping of event types to their data structures
|
|
33
33
|
*/
|
|
@@ -46,6 +46,10 @@ interface CTEventDataMap {
|
|
|
46
46
|
whiteboard_undo: WhiteboardUndoEventData;
|
|
47
47
|
excalidraw_scene: ExcalidrawSceneEventData;
|
|
48
48
|
excalidraw_clear: ExcalidrawClearEventData;
|
|
49
|
+
excalidraw_pointer: ExcalidrawPointerEventData;
|
|
50
|
+
overlay_scene: ExcalidrawSceneEventData;
|
|
51
|
+
overlay_clear: ExcalidrawClearEventData;
|
|
52
|
+
overlay_pointer: ExcalidrawPointerEventData;
|
|
49
53
|
document_load: DocumentLoadEventData;
|
|
50
54
|
document_page: DocumentPageEventData;
|
|
51
55
|
document_zoom: DocumentZoomEventData;
|
|
@@ -74,6 +78,8 @@ interface CTEventDataMap {
|
|
|
74
78
|
editor_cursor: EditorCursorEventData;
|
|
75
79
|
tool_switch: ToolSwitchEventData;
|
|
76
80
|
marker: MarkerEventData;
|
|
81
|
+
webcam_state: WebcamStateEventData;
|
|
82
|
+
content_dimensions: ContentDimensionsEventData;
|
|
77
83
|
tool: ToolEventData;
|
|
78
84
|
whiteboard: WhiteboardEventData;
|
|
79
85
|
whiteboard_point: WhiteboardPointEventData;
|
|
@@ -221,6 +227,10 @@ interface InitEventData {
|
|
|
221
227
|
x: number;
|
|
222
228
|
y: number;
|
|
223
229
|
};
|
|
230
|
+
contentDimensions?: {
|
|
231
|
+
width: number;
|
|
232
|
+
height: number;
|
|
233
|
+
};
|
|
224
234
|
}
|
|
225
235
|
/**
|
|
226
236
|
* Code content change
|
|
@@ -380,6 +390,15 @@ interface ExcalidrawSceneEventData {
|
|
|
380
390
|
*/
|
|
381
391
|
interface ExcalidrawClearEventData {
|
|
382
392
|
}
|
|
393
|
+
/**
|
|
394
|
+
* Excalidraw pointer update (laser pointer, tool changes)
|
|
395
|
+
*/
|
|
396
|
+
interface ExcalidrawPointerEventData {
|
|
397
|
+
x: number;
|
|
398
|
+
y: number;
|
|
399
|
+
tool: 'pointer' | 'laser';
|
|
400
|
+
button: 'down' | 'up';
|
|
401
|
+
}
|
|
383
402
|
/**
|
|
384
403
|
* Load document
|
|
385
404
|
*/
|
|
@@ -587,7 +606,22 @@ interface ToolSwitchEventData {
|
|
|
587
606
|
interface MarkerEventData {
|
|
588
607
|
id: string;
|
|
589
608
|
label: string;
|
|
590
|
-
type: 'chapter' | '
|
|
609
|
+
type: 'chapter' | 'bookmark' | 'quiz' | 'note';
|
|
610
|
+
}
|
|
611
|
+
/**
|
|
612
|
+
* Webcam state event for maximize/minimize during recording
|
|
613
|
+
*/
|
|
614
|
+
interface WebcamStateEventData {
|
|
615
|
+
/** Whether the webcam is maximized (full overlay) */
|
|
616
|
+
maximized: boolean;
|
|
617
|
+
}
|
|
618
|
+
/**
|
|
619
|
+
* Content dimensions event — captures the recording container size
|
|
620
|
+
* for accurate cursor alignment during playback
|
|
621
|
+
*/
|
|
622
|
+
interface ContentDimensionsEventData {
|
|
623
|
+
width: number;
|
|
624
|
+
height: number;
|
|
591
625
|
}
|
|
592
626
|
/**
|
|
593
627
|
* Legacy tool event (same as tool_switch)
|
|
@@ -683,6 +717,32 @@ interface PlaybackState$1 {
|
|
|
683
717
|
textSelection: TextSelectionState | null;
|
|
684
718
|
/** Editor typing cursor (caret) position */
|
|
685
719
|
editorCursor: EditorCursorState | null;
|
|
720
|
+
/** Whether webcam is in maximized (full overlay) mode */
|
|
721
|
+
webcamMaximized: boolean;
|
|
722
|
+
/** Content area dimensions from the recording session.
|
|
723
|
+
* Used to correctly position the cursor overlay during playback when
|
|
724
|
+
* the player container is a different size than the recording container.
|
|
725
|
+
* Without this, the cursor diverges from Excalidraw's absolute coordinates. */
|
|
726
|
+
contentDimensions: {
|
|
727
|
+
width: number;
|
|
728
|
+
height: number;
|
|
729
|
+
} | null;
|
|
730
|
+
/** Excalidraw pointer state (for laser pointer playback) */
|
|
731
|
+
excalidrawPointer: {
|
|
732
|
+
x: number;
|
|
733
|
+
y: number;
|
|
734
|
+
tool: 'pointer' | 'laser';
|
|
735
|
+
button: 'down' | 'up';
|
|
736
|
+
} | null;
|
|
737
|
+
/** Drawing overlay scene (floating overlay on non-whiteboard panels) */
|
|
738
|
+
overlayScene: ExcalidrawScene | null;
|
|
739
|
+
/** Drawing overlay pointer state (laser pointer on overlay) */
|
|
740
|
+
overlayPointer: {
|
|
741
|
+
x: number;
|
|
742
|
+
y: number;
|
|
743
|
+
tool: 'pointer' | 'laser';
|
|
744
|
+
button: 'down' | 'up';
|
|
745
|
+
} | null;
|
|
686
746
|
}
|
|
687
747
|
/**
|
|
688
748
|
* State for file/folder creation UI display during playback
|
|
@@ -1071,7 +1131,7 @@ interface CTManifest {
|
|
|
1071
1131
|
media: CTMediaInfo;
|
|
1072
1132
|
/** Events reference (chunked in v1.1.0+, single file in v1.0.0) */
|
|
1073
1133
|
events: CTEventsInfo;
|
|
1074
|
-
/** Chapter/
|
|
1134
|
+
/** Chapter/bookmark markers */
|
|
1075
1135
|
markers: CTMarker[];
|
|
1076
1136
|
/** Optional embedded assets */
|
|
1077
1137
|
assets?: CTAssets;
|
|
@@ -1144,7 +1204,7 @@ interface CTWaveformInfo {
|
|
|
1144
1204
|
samplesPerSecond: number;
|
|
1145
1205
|
}
|
|
1146
1206
|
/**
|
|
1147
|
-
* Chapter/
|
|
1207
|
+
* Chapter/bookmark marker
|
|
1148
1208
|
*/
|
|
1149
1209
|
interface CTMarker {
|
|
1150
1210
|
/** Unique identifier */
|
|
@@ -1155,13 +1215,16 @@ interface CTMarker {
|
|
|
1155
1215
|
label: string;
|
|
1156
1216
|
/** Marker type */
|
|
1157
1217
|
type: CTMarkerType;
|
|
1158
|
-
/**
|
|
1218
|
+
/**
|
|
1219
|
+
* Type-specific additional data.
|
|
1220
|
+
* When `type === 'quiz'`, this should conform to {@link MCQMarkerData}.
|
|
1221
|
+
*/
|
|
1159
1222
|
data?: Record<string, unknown>;
|
|
1160
1223
|
}
|
|
1161
1224
|
/**
|
|
1162
1225
|
* Marker types
|
|
1163
1226
|
*/
|
|
1164
|
-
type CTMarkerType = 'chapter' | '
|
|
1227
|
+
type CTMarkerType = 'chapter' | 'bookmark' | 'quiz' | 'note';
|
|
1165
1228
|
/**
|
|
1166
1229
|
* Embedded assets manifest
|
|
1167
1230
|
*/
|
|
@@ -1551,6 +1614,21 @@ interface IDEPanelProps extends BasePanelProps {
|
|
|
1551
1614
|
line: number;
|
|
1552
1615
|
column: number;
|
|
1553
1616
|
}) => void;
|
|
1617
|
+
/**
|
|
1618
|
+
* Called when user interacts with the IDE (clicks explorer, terminal, etc).
|
|
1619
|
+
* Use this to pause playback when user starts interacting.
|
|
1620
|
+
*/
|
|
1621
|
+
onInteractionStart?: () => void;
|
|
1622
|
+
/** Whether to show AI inline suggestions (recording mode only). Default: false */
|
|
1623
|
+
aiSuggestionsEnabled?: boolean;
|
|
1624
|
+
/** API endpoint URL for AI completions. Default: '/api/ai/complete' */
|
|
1625
|
+
aiSuggestionsEndpoint?: string;
|
|
1626
|
+
/** Debounce delay in ms before requesting a completion. Default: 300 */
|
|
1627
|
+
aiSuggestionsDebounceMs?: number;
|
|
1628
|
+
/** Whether the AI debug feature is available. Default: false */
|
|
1629
|
+
aiDebugEnabled?: boolean;
|
|
1630
|
+
/** API endpoint for AI debug analysis. Default: '/api/ai/debug' */
|
|
1631
|
+
aiDebugEndpoint?: string;
|
|
1554
1632
|
}
|
|
1555
1633
|
/**
|
|
1556
1634
|
* Excalidraw scene structure (simplified)
|
|
@@ -1570,6 +1648,22 @@ interface WhiteboardPanelProps extends BasePanelProps {
|
|
|
1570
1648
|
onSceneChange?: (scene: WhiteboardScene) => void;
|
|
1571
1649
|
/** Called when scene is cleared */
|
|
1572
1650
|
onSceneClear?: () => void;
|
|
1651
|
+
/** Called when pointer updates (laser pointer, drawing pointer) */
|
|
1652
|
+
onPointerUpdate?: (payload: {
|
|
1653
|
+
pointer: {
|
|
1654
|
+
x: number;
|
|
1655
|
+
y: number;
|
|
1656
|
+
tool: 'pointer' | 'laser';
|
|
1657
|
+
};
|
|
1658
|
+
button: 'down' | 'up';
|
|
1659
|
+
}) => void;
|
|
1660
|
+
/** Excalidraw pointer state for playback (laser trail rendering) */
|
|
1661
|
+
pointerState?: {
|
|
1662
|
+
x: number;
|
|
1663
|
+
y: number;
|
|
1664
|
+
tool: 'pointer' | 'laser';
|
|
1665
|
+
button: 'down' | 'up';
|
|
1666
|
+
} | null;
|
|
1573
1667
|
/** Show Excalidraw toolbar */
|
|
1574
1668
|
showToolbar?: boolean;
|
|
1575
1669
|
/** Background color */
|
|
@@ -1647,6 +1741,8 @@ interface DocumentPanelProps extends BasePanelProps {
|
|
|
1647
1741
|
allowMultiple?: boolean;
|
|
1648
1742
|
/** Background color */
|
|
1649
1743
|
backgroundColor?: string;
|
|
1744
|
+
/** Base URL for asset upload endpoint (e.g. '/api/assets'). PPTX files are uploaded here to get a public URL for iframe embedding. */
|
|
1745
|
+
assetUploadUrl?: string;
|
|
1650
1746
|
}
|
|
1651
1747
|
/**
|
|
1652
1748
|
* Terminal component props
|
|
@@ -1763,13 +1859,15 @@ interface ToolSidebarProps {
|
|
|
1763
1859
|
tools?: ToolType[];
|
|
1764
1860
|
/** Additional CSS classes */
|
|
1765
1861
|
className?: string;
|
|
1862
|
+
/** Inline styles (e.g. background override) */
|
|
1863
|
+
style?: React.CSSProperties;
|
|
1766
1864
|
}
|
|
1767
1865
|
|
|
1768
|
-
declare function ToolSidebar({ activeTool, onToolChange, tools, className, }: ToolSidebarProps): react_jsx_runtime.JSX.Element;
|
|
1866
|
+
declare function ToolSidebar({ activeTool, onToolChange, tools, className, style, }: ToolSidebarProps): react_jsx_runtime.JSX.Element;
|
|
1769
1867
|
|
|
1770
|
-
declare function WhiteboardPanel({ scene, onSceneChange, onSceneClear, mode, isPlaying, onInteract, showToolbar, backgroundColor, className, }: WhiteboardPanelProps): react_jsx_runtime.JSX.Element;
|
|
1868
|
+
declare function WhiteboardPanel({ scene, onSceneChange, onSceneClear, onPointerUpdate, pointerState, mode, isPlaying, onInteract, showToolbar, backgroundColor, className, }: WhiteboardPanelProps): react_jsx_runtime.JSX.Element;
|
|
1771
1869
|
|
|
1772
|
-
declare function DocumentPanel({ documentData, documents: externalDocuments, activeDocumentId: externalActiveId, currentPage, zoom, scrollPosition, onDocumentLoad, onDocumentSelect, onDocumentRemove, onPageChange, onZoomChange, onScrollChange, onDocumentClear, mode, isPlaying, onInteract, showTabBar, showToolbar, showPageIndicator, allowUpload, allowMultiple, backgroundColor, className, }: DocumentPanelProps): react_jsx_runtime.JSX.Element;
|
|
1870
|
+
declare function DocumentPanel({ documentData, documents: externalDocuments, activeDocumentId: externalActiveId, currentPage, zoom, scrollPosition, onDocumentLoad, onDocumentSelect, onDocumentRemove, onPageChange, onZoomChange, onScrollChange, onDocumentClear, mode, isPlaying, onInteract, showTabBar, showToolbar, showPageIndicator, allowUpload, allowMultiple, backgroundColor, assetUploadUrl, className, }: DocumentPanelProps): react_jsx_runtime.JSX.Element;
|
|
1773
1871
|
|
|
1774
1872
|
interface VirtualFileSystem {
|
|
1775
1873
|
getFileTree: () => FileSystemEntry;
|
|
@@ -1784,103 +1882,62 @@ interface VirtualFileSystem {
|
|
|
1784
1882
|
notifyChanged?: () => void;
|
|
1785
1883
|
mkdir?: (path: string) => void;
|
|
1786
1884
|
}
|
|
1787
|
-
declare function IDEPanel({ fileSystem, tree: externalTree, files: externalFiles, code: externalCode, language: externalLanguage, currentFile: externalCurrentFile, onCodeChange, onFileChange, onFileCreate, onFileDelete, onFileRename, onFileSelect, onFolderCreate, onFolderDelete, onTerminalCommand, onTerminalClear, onTerminalAddLines, fileCreationState, onFileCreationStart, onFileCreationInput, onFileCreationCancel, fileRenamingState, onFileRenameStart, onFileRenameInput, onFileRenameCancel, expandedFoldersState, onFolderToggle, terminalLines: externalTerminalLines, terminalInput: externalTerminalInput, onTerminalInputChange, onExecute, onTerminalExecute, mode, isPlaying, defaultShowExplorer, defaultShowTerminal, showRunButton, interactiveLabel, initialFiles, initialActiveFile, hoveredFile, onFileHover, textSelection, onTextSelect, editorCursor, onEditorCursorChange }: IDEPanelProps & {
|
|
1885
|
+
declare function IDEPanel({ fileSystem, tree: externalTree, files: externalFiles, code: externalCode, language: externalLanguage, currentFile: externalCurrentFile, onCodeChange, onFileChange, onFileCreate, onFileDelete, onFileRename, onFileSelect, onFolderCreate, onFolderDelete, onTerminalCommand, onTerminalClear, onTerminalAddLines, fileCreationState, onFileCreationStart, onFileCreationInput, onFileCreationCancel, fileRenamingState, onFileRenameStart, onFileRenameInput, onFileRenameCancel, expandedFoldersState, onFolderToggle, terminalLines: externalTerminalLines, terminalInput: externalTerminalInput, onTerminalInputChange, onExecute, onTerminalExecute, mode, isPlaying, defaultShowExplorer, defaultShowTerminal, showRunButton, interactiveLabel, initialFiles, initialActiveFile, hoveredFile, onFileHover, textSelection, onTextSelect, editorCursor, onEditorCursorChange, onInteractionStart, aiSuggestionsEnabled, aiSuggestionsEndpoint, aiSuggestionsDebounceMs, aiDebugEnabled, aiDebugEndpoint, }: IDEPanelProps & {
|
|
1788
1886
|
fileSystem?: VirtualFileSystem;
|
|
1789
1887
|
}): react_jsx_runtime.JSX.Element;
|
|
1790
1888
|
|
|
1791
1889
|
declare function FileExplorer({ tree, selectedFile, expandedFolders, fileCreation, fileRenaming, mode, isPlaying, hoveredFile, onFileHover, onFileSelect, onFileCreate, onFolderCreate, onFileDelete, onFileRename, onFolderToggle, onFileCreationStart, onFileCreationInput, onFileCreationCancel, onFileRenameStart, onFileRenameInput, onFileRenameCancel, className, }: FileExplorerProps): react_jsx_runtime.JSX.Element;
|
|
1792
1890
|
|
|
1793
|
-
declare const Terminal:
|
|
1891
|
+
declare const Terminal: React__default.ForwardRefExoticComponent<TerminalProps & React__default.RefAttributes<TerminalRef>>;
|
|
1794
1892
|
|
|
1795
1893
|
/**
|
|
1796
|
-
*
|
|
1894
|
+
* Learner Branch Types
|
|
1895
|
+
*
|
|
1896
|
+
* A branch is a saved snapshot of the learner's code edits at a specific
|
|
1897
|
+
* moment in the instructor's timeline. Branches are learner-side only —
|
|
1898
|
+
* they never modify the .ct file, events, or manifest.
|
|
1899
|
+
*
|
|
1900
|
+
* @packageDocumentation
|
|
1797
1901
|
*/
|
|
1798
|
-
type ActiveTool$1 = ToolType;
|
|
1799
1902
|
/**
|
|
1800
|
-
*
|
|
1903
|
+
* A point-in-time capture of the IDE state.
|
|
1904
|
+
* Used for both the instructor's original state and the learner's edited state.
|
|
1801
1905
|
*/
|
|
1802
|
-
interface
|
|
1803
|
-
/**
|
|
1804
|
-
|
|
1805
|
-
/**
|
|
1806
|
-
|
|
1807
|
-
/**
|
|
1808
|
-
|
|
1809
|
-
/**
|
|
1810
|
-
|
|
1811
|
-
/**
|
|
1812
|
-
|
|
1813
|
-
/**
|
|
1814
|
-
|
|
1815
|
-
/**
|
|
1816
|
-
|
|
1817
|
-
/** Theme setting */
|
|
1818
|
-
theme?: 'light' | 'dark' | 'system';
|
|
1819
|
-
/** Aspect ratio of the player */
|
|
1820
|
-
aspectRatio?: '16:9' | '4:3' | 'auto';
|
|
1821
|
-
/** Show playback controls toolbar */
|
|
1822
|
-
showToolbar?: boolean;
|
|
1823
|
-
/** Show timeline below player */
|
|
1824
|
-
showTimeline?: boolean;
|
|
1825
|
-
/** Show chapter markers */
|
|
1826
|
-
showChapters?: boolean;
|
|
1827
|
-
/** Show tool sidebar */
|
|
1828
|
-
showToolSidebar?: boolean;
|
|
1829
|
-
/** Auto-play when loaded */
|
|
1830
|
-
autoPlay?: boolean;
|
|
1831
|
-
/** Default playback speed */
|
|
1832
|
-
defaultSpeed?: number;
|
|
1833
|
-
/** Allow fullscreen mode */
|
|
1834
|
-
allowFullscreen?: boolean;
|
|
1835
|
-
/** Default active tool */
|
|
1836
|
-
defaultTool?: ActiveTool$1;
|
|
1837
|
-
/** Called when player is ready */
|
|
1838
|
-
onReady?: () => void;
|
|
1839
|
-
/** Called when playback starts */
|
|
1840
|
-
onPlay?: () => void;
|
|
1841
|
-
/** Called when playback pauses */
|
|
1842
|
-
onPause?: () => void;
|
|
1843
|
-
/** Called on progress update */
|
|
1844
|
-
onProgress?: (time: number, duration: number) => void;
|
|
1845
|
-
/** Called when playback completes */
|
|
1846
|
-
onComplete?: () => void;
|
|
1847
|
-
/** Called on error */
|
|
1848
|
-
onError?: (error: Error) => void;
|
|
1849
|
-
/** Called when entering interactive mode */
|
|
1850
|
-
onInteractionStart?: () => void;
|
|
1851
|
-
/** Called when exiting interactive mode */
|
|
1852
|
-
onInteractionEnd?: (code: string) => void;
|
|
1853
|
-
/** Called when tool changes */
|
|
1854
|
-
onToolChange?: (tool: string) => void;
|
|
1906
|
+
interface BranchSnapshot {
|
|
1907
|
+
/** Active file's code content */
|
|
1908
|
+
code: string;
|
|
1909
|
+
/** Programming language at snapshot time */
|
|
1910
|
+
language: string;
|
|
1911
|
+
/** Which file tab was active (null if single-file mode) */
|
|
1912
|
+
currentFile: string | null;
|
|
1913
|
+
/** Full file system snapshot — path → content */
|
|
1914
|
+
fileSystem: Record<string, string>;
|
|
1915
|
+
/** Terminal output lines if any existed */
|
|
1916
|
+
terminalOutput?: string[];
|
|
1917
|
+
/** Which tool panel was open (code / terminal / whiteboard / document) */
|
|
1918
|
+
activeTool: string;
|
|
1919
|
+
/** Folder paths created by the learner during interactive mode */
|
|
1920
|
+
folders?: string[];
|
|
1855
1921
|
}
|
|
1856
1922
|
/**
|
|
1857
|
-
*
|
|
1923
|
+
* A learner branch — a saved code snapshot at a point in the timeline.
|
|
1858
1924
|
*/
|
|
1859
|
-
interface
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1925
|
+
interface LearnerBranch {
|
|
1926
|
+
/** Unique branch ID (crypto.randomUUID) */
|
|
1927
|
+
id: string;
|
|
1928
|
+
/** Lesson/recording this branch belongs to */
|
|
1929
|
+
lessonId: string;
|
|
1930
|
+
/** Playback time in milliseconds where the learner paused */
|
|
1931
|
+
timeMs: number;
|
|
1932
|
+
/** Instructor's state at that moment (for comparison / restoring) */
|
|
1933
|
+
originalState: BranchSnapshot;
|
|
1934
|
+
/** Learner's edited state */
|
|
1935
|
+
learnerState: BranchSnapshot;
|
|
1936
|
+
/** ISO timestamp of when the branch was created */
|
|
1937
|
+
createdAt: string;
|
|
1938
|
+
/** User-provided label, defaults to "Branch at MM:SS" */
|
|
1939
|
+
label?: string;
|
|
1870
1940
|
}
|
|
1871
|
-
/**
|
|
1872
|
-
* CoursePlayer component
|
|
1873
|
-
*/
|
|
1874
|
-
declare const CoursePlayer: react.ForwardRefExoticComponent<CoursePlayerProps & react.RefAttributes<CoursePlayerRef>>;
|
|
1875
|
-
|
|
1876
|
-
/**
|
|
1877
|
-
* CT-Courses Player - Remote Streaming Types
|
|
1878
|
-
*
|
|
1879
|
-
* Types for streaming playback from a remote CDN/R2 storage.
|
|
1880
|
-
* These types match the streaming service manifest structure.
|
|
1881
|
-
*
|
|
1882
|
-
* @packageDocumentation
|
|
1883
|
-
*/
|
|
1884
1941
|
|
|
1885
1942
|
/**
|
|
1886
1943
|
* Audio quality level information
|
|
@@ -1981,6 +2038,32 @@ interface StreamingConfig {
|
|
|
1981
2038
|
/** Maximum buffer to maintain (ms) */
|
|
1982
2039
|
maxBufferMs: number;
|
|
1983
2040
|
}
|
|
2041
|
+
/**
|
|
2042
|
+
* An interaction point from the streaming manifest (CDN-safe).
|
|
2043
|
+
* Options intentionally omit `isCorrect` — answers validated server-side only.
|
|
2044
|
+
*/
|
|
2045
|
+
interface InteractionPointManifest {
|
|
2046
|
+
/** Marker ID from the .ct manifest */
|
|
2047
|
+
id: string;
|
|
2048
|
+
/** Interaction type (only 'mcq' for now) */
|
|
2049
|
+
type: 'mcq';
|
|
2050
|
+
/** Time position in milliseconds */
|
|
2051
|
+
timeMs: number;
|
|
2052
|
+
/** Whether to pause playback when this point is reached */
|
|
2053
|
+
pausePlayback: boolean;
|
|
2054
|
+
/** MCQ question data (without isCorrect on options) */
|
|
2055
|
+
mcq: {
|
|
2056
|
+
question: string;
|
|
2057
|
+
options: {
|
|
2058
|
+
id: string;
|
|
2059
|
+
text: string;
|
|
2060
|
+
}[];
|
|
2061
|
+
explanation?: string;
|
|
2062
|
+
allowRetry: boolean;
|
|
2063
|
+
shuffleOptions: boolean;
|
|
2064
|
+
timeoutSeconds: number | null;
|
|
2065
|
+
};
|
|
2066
|
+
}
|
|
1984
2067
|
/**
|
|
1985
2068
|
* Complete streaming manifest structure
|
|
1986
2069
|
* This is the main entry point returned by the streaming service.
|
|
@@ -2000,6 +2083,12 @@ interface StreamingManifest {
|
|
|
2000
2083
|
events: StreamingEventsConfig;
|
|
2001
2084
|
/** Streaming playback hints */
|
|
2002
2085
|
streaming: StreamingConfig;
|
|
2086
|
+
/**
|
|
2087
|
+
* Interaction points extracted from .ct manifest quiz markers.
|
|
2088
|
+
* Options omit `isCorrect` — answers are validated server-side only.
|
|
2089
|
+
* Absent or empty when the recording has no quiz markers.
|
|
2090
|
+
*/
|
|
2091
|
+
interactionPoints?: InteractionPointManifest[];
|
|
2003
2092
|
}
|
|
2004
2093
|
/**
|
|
2005
2094
|
* Options for useRemoteStreamingPlayback hook
|
|
@@ -2107,6 +2196,12 @@ interface RemoteStreamingPlaybackControls {
|
|
|
2107
2196
|
getVideoElement(): HTMLVideoElement | null;
|
|
2108
2197
|
/** Attach HLS video player to a video element (from WebcamOverlay onVideoRef) */
|
|
2109
2198
|
initVideoHls(videoElement: HTMLVideoElement | null): void;
|
|
2199
|
+
/** Get available webcam video quality levels */
|
|
2200
|
+
getVideoQualityLevels(): HLSQualityLevel[];
|
|
2201
|
+
/** Set webcam video quality level (-1 for auto) */
|
|
2202
|
+
setVideoQualityLevel(index: number): void;
|
|
2203
|
+
/** Get current webcam video quality level (-1 = auto) */
|
|
2204
|
+
getVideoQualityLevel(): number;
|
|
2110
2205
|
}
|
|
2111
2206
|
/**
|
|
2112
2207
|
* HLS player configuration
|
|
@@ -2131,81 +2226,12 @@ interface HLSQualityLevel {
|
|
|
2131
2226
|
bitrate: number;
|
|
2132
2227
|
/** Codec string */
|
|
2133
2228
|
codecs: string;
|
|
2229
|
+
/** Video width (0 if audio-only) */
|
|
2230
|
+
width?: number;
|
|
2231
|
+
/** Video height (0 if audio-only) */
|
|
2232
|
+
height?: number;
|
|
2134
2233
|
}
|
|
2135
2234
|
|
|
2136
|
-
type ActiveTool = ToolType;
|
|
2137
|
-
/**
|
|
2138
|
-
* Props for StreamingCoursePlayer
|
|
2139
|
-
*/
|
|
2140
|
-
interface StreamingCoursePlayerProps {
|
|
2141
|
-
/** URL to the streaming manifest.json */
|
|
2142
|
-
manifestUrl: string;
|
|
2143
|
-
/** Theme setting */
|
|
2144
|
-
theme?: 'light' | 'dark' | 'system';
|
|
2145
|
-
/** Aspect ratio of the player */
|
|
2146
|
-
aspectRatio?: '16:9' | '4:3' | 'auto';
|
|
2147
|
-
/** Show playback controls toolbar */
|
|
2148
|
-
showToolbar?: boolean;
|
|
2149
|
-
/** Show tool sidebar */
|
|
2150
|
-
showToolSidebar?: boolean;
|
|
2151
|
-
/** Auto-play when loaded */
|
|
2152
|
-
autoPlay?: boolean;
|
|
2153
|
-
/** Default playback speed */
|
|
2154
|
-
defaultSpeed?: number;
|
|
2155
|
-
/** Allow fullscreen mode */
|
|
2156
|
-
allowFullscreen?: boolean;
|
|
2157
|
-
/** Default active tool */
|
|
2158
|
-
defaultTool?: ActiveTool;
|
|
2159
|
-
/** Maximum chunks to cache */
|
|
2160
|
-
maxCacheSize?: number;
|
|
2161
|
-
/** Additional CSS class */
|
|
2162
|
-
className?: string;
|
|
2163
|
-
/** Called when player is ready */
|
|
2164
|
-
onReady?: () => void;
|
|
2165
|
-
/** Called when playback starts */
|
|
2166
|
-
onPlay?: () => void;
|
|
2167
|
-
/** Called when playback pauses */
|
|
2168
|
-
onPause?: () => void;
|
|
2169
|
-
/** Called on progress update */
|
|
2170
|
-
onProgress?: (time: number, duration: number) => void;
|
|
2171
|
-
/** Called when playback completes */
|
|
2172
|
-
onComplete?: () => void;
|
|
2173
|
-
/** Called on error */
|
|
2174
|
-
onError?: (error: Error) => void;
|
|
2175
|
-
/** Called when buffering state changes */
|
|
2176
|
-
onBuffering?: (isBuffering: boolean) => void;
|
|
2177
|
-
/** Called when tool changes */
|
|
2178
|
-
onToolChange?: (tool: string) => void;
|
|
2179
|
-
/** Go-Judge server URL */
|
|
2180
|
-
goJudgeUrl?: string;
|
|
2181
|
-
/** Go-Judge API key */
|
|
2182
|
-
goJudgeApiKey?: string;
|
|
2183
|
-
/** Show chapter markers */
|
|
2184
|
-
showChapters?: boolean;
|
|
2185
|
-
/** Called when entering interactive mode */
|
|
2186
|
-
onInteractionStart?: () => void;
|
|
2187
|
-
/** Called when exiting interactive mode */
|
|
2188
|
-
onInteractionEnd?: (code: string) => void;
|
|
2189
|
-
}
|
|
2190
|
-
/**
|
|
2191
|
-
* Imperative handle for StreamingCoursePlayer
|
|
2192
|
-
*/
|
|
2193
|
-
interface StreamingCoursePlayerRef {
|
|
2194
|
-
play(): void;
|
|
2195
|
-
pause(): void;
|
|
2196
|
-
seek(timeMs: number): Promise<void>;
|
|
2197
|
-
setSpeed(speed: number): void;
|
|
2198
|
-
getCurrentTime(): number;
|
|
2199
|
-
getDuration(): number;
|
|
2200
|
-
getState(): PlaybackState$1;
|
|
2201
|
-
enterInteractiveMode(): void;
|
|
2202
|
-
exitInteractiveMode(): void;
|
|
2203
|
-
setActiveTool(tool: ActiveTool): void;
|
|
2204
|
-
getManifest(): StreamingManifest | null;
|
|
2205
|
-
getBufferHealth(): RemoteBufferHealth;
|
|
2206
|
-
}
|
|
2207
|
-
declare const StreamingCoursePlayer: react.ForwardRefExoticComponent<StreamingCoursePlayerProps & react.RefAttributes<StreamingCoursePlayerRef>>;
|
|
2208
|
-
|
|
2209
2235
|
/**
|
|
2210
2236
|
* @ct-courses/player - Type Definitions
|
|
2211
2237
|
*/
|
|
@@ -2448,6 +2474,248 @@ interface VolumeControlProps {
|
|
|
2448
2474
|
onMuteToggle: () => void;
|
|
2449
2475
|
className?: string;
|
|
2450
2476
|
}
|
|
2477
|
+
/**
|
|
2478
|
+
* Client-side interaction point (no isCorrect — answers validated server-side).
|
|
2479
|
+
* Mirrors InteractionPointManifest from streaming.ts but usable without a manifest.
|
|
2480
|
+
*/
|
|
2481
|
+
interface InteractionPoint {
|
|
2482
|
+
/** Unique identifier */
|
|
2483
|
+
id: string;
|
|
2484
|
+
/** Interaction type */
|
|
2485
|
+
type: 'mcq';
|
|
2486
|
+
/** Time position in milliseconds */
|
|
2487
|
+
timeMs: number;
|
|
2488
|
+
/** Whether to pause playback when this point is reached */
|
|
2489
|
+
pausePlayback: boolean;
|
|
2490
|
+
/** MCQ question data */
|
|
2491
|
+
mcq: {
|
|
2492
|
+
question: string;
|
|
2493
|
+
options: {
|
|
2494
|
+
id: string;
|
|
2495
|
+
text: string;
|
|
2496
|
+
}[];
|
|
2497
|
+
explanation?: string;
|
|
2498
|
+
allowRetry: boolean;
|
|
2499
|
+
shuffleOptions: boolean;
|
|
2500
|
+
timeoutSeconds: number | null;
|
|
2501
|
+
};
|
|
2502
|
+
}
|
|
2503
|
+
/**
|
|
2504
|
+
* MCQ answer submission from the player
|
|
2505
|
+
*/
|
|
2506
|
+
interface MCQSubmission {
|
|
2507
|
+
/** The interaction point ID */
|
|
2508
|
+
pointId: string;
|
|
2509
|
+
/** Selected option IDs */
|
|
2510
|
+
selectedOptionIds: string[];
|
|
2511
|
+
}
|
|
2512
|
+
/**
|
|
2513
|
+
* MCQ answer result returned from the host app's callback
|
|
2514
|
+
*/
|
|
2515
|
+
interface MCQResult {
|
|
2516
|
+
/** Whether the answer was correct */
|
|
2517
|
+
correct: boolean;
|
|
2518
|
+
/** Optional explanation text */
|
|
2519
|
+
explanation?: string;
|
|
2520
|
+
/** Correct option IDs (revealed after answering) */
|
|
2521
|
+
correctOptionIds?: string[];
|
|
2522
|
+
}
|
|
2523
|
+
|
|
2524
|
+
/**
|
|
2525
|
+
* Active tool type - matches ToolType from @ct-courses/ui
|
|
2526
|
+
*/
|
|
2527
|
+
type ActiveTool$1 = ToolType;
|
|
2528
|
+
/**
|
|
2529
|
+
* Props for the CoursePlayer component
|
|
2530
|
+
*/
|
|
2531
|
+
interface CoursePlayerProps {
|
|
2532
|
+
/** Pre-loaded recording data */
|
|
2533
|
+
recording?: CTRecording;
|
|
2534
|
+
/** URL to a .ct file */
|
|
2535
|
+
recordingUrl?: string;
|
|
2536
|
+
/** Recording ID to fetch from API */
|
|
2537
|
+
recordingId?: string;
|
|
2538
|
+
/** Base API URL for fetching recordings */
|
|
2539
|
+
apiUrl?: string;
|
|
2540
|
+
/** Authentication token */
|
|
2541
|
+
authToken?: string;
|
|
2542
|
+
/** Go-Judge server URL */
|
|
2543
|
+
goJudgeUrl?: string;
|
|
2544
|
+
/** Go-Judge API key */
|
|
2545
|
+
goJudgeApiKey?: string;
|
|
2546
|
+
/** Theme setting */
|
|
2547
|
+
theme?: "light" | "dark" | "system";
|
|
2548
|
+
/** Aspect ratio of the player */
|
|
2549
|
+
aspectRatio?: "16:9" | "4:3" | "auto";
|
|
2550
|
+
/** Show playback controls toolbar */
|
|
2551
|
+
showToolbar?: boolean;
|
|
2552
|
+
/** Show timeline below player */
|
|
2553
|
+
showTimeline?: boolean;
|
|
2554
|
+
/** Show chapter markers */
|
|
2555
|
+
showChapters?: boolean;
|
|
2556
|
+
/** Show tool sidebar */
|
|
2557
|
+
showToolSidebar?: boolean;
|
|
2558
|
+
/** Auto-play when loaded */
|
|
2559
|
+
autoPlay?: boolean;
|
|
2560
|
+
/** Default playback speed */
|
|
2561
|
+
defaultSpeed?: number;
|
|
2562
|
+
/** Allow fullscreen mode */
|
|
2563
|
+
allowFullscreen?: boolean;
|
|
2564
|
+
/** Default active tool */
|
|
2565
|
+
defaultTool?: ActiveTool$1;
|
|
2566
|
+
/** Called when player is ready */
|
|
2567
|
+
onReady?: () => void;
|
|
2568
|
+
/** Called when playback starts */
|
|
2569
|
+
onPlay?: () => void;
|
|
2570
|
+
/** Called when playback pauses */
|
|
2571
|
+
onPause?: () => void;
|
|
2572
|
+
/** Called on progress update */
|
|
2573
|
+
onProgress?: (time: number, duration: number) => void;
|
|
2574
|
+
/** Called when playback completes */
|
|
2575
|
+
onComplete?: () => void;
|
|
2576
|
+
/** Called on error */
|
|
2577
|
+
onError?: (error: Error) => void;
|
|
2578
|
+
/** Called when entering interactive mode */
|
|
2579
|
+
onInteractionStart?: () => void;
|
|
2580
|
+
/** Called when exiting interactive mode */
|
|
2581
|
+
onInteractionEnd?: (code: string) => void;
|
|
2582
|
+
/** Called when tool changes */
|
|
2583
|
+
onToolChange?: (tool: string) => void;
|
|
2584
|
+
/** Interaction points (MCQs) to display during playback */
|
|
2585
|
+
interactionPoints?: InteractionPoint[];
|
|
2586
|
+
/** Pre-answered point IDs (skip these MCQs) */
|
|
2587
|
+
answeredPointIds?: Set<string>;
|
|
2588
|
+
/** Called when a learner submits an MCQ answer. Host app validates server-side. */
|
|
2589
|
+
onSubmitAnswer?: (pointId: string, selectedOptionIds: string[]) => Promise<MCQResult>;
|
|
2590
|
+
/** Info about the next lesson for auto-advance overlay */
|
|
2591
|
+
nextLesson?: {
|
|
2592
|
+
id: string;
|
|
2593
|
+
title: string;
|
|
2594
|
+
} | null;
|
|
2595
|
+
/** Called when the player wants to navigate to the next lesson */
|
|
2596
|
+
onNavigateToLesson?: (lessonId: string) => void;
|
|
2597
|
+
/** Called when the current lesson completes (before transition) */
|
|
2598
|
+
onLessonComplete?: () => void;
|
|
2599
|
+
/** Lesson ID used to scope saved branches in localStorage */
|
|
2600
|
+
lessonId?: string;
|
|
2601
|
+
/** Enable the branch save feature (default: true) */
|
|
2602
|
+
enableBranches?: boolean;
|
|
2603
|
+
/** Called after a branch is saved */
|
|
2604
|
+
onBranchSave?: (branch: LearnerBranch) => void;
|
|
2605
|
+
/** Called when a learner restores a saved branch */
|
|
2606
|
+
onBranchRestore?: (branch: LearnerBranch) => void;
|
|
2607
|
+
/** Called after a branch is deleted */
|
|
2608
|
+
onBranchDelete?: (branchId: string) => void;
|
|
2609
|
+
/** Maximum branches per lesson (default: 50) */
|
|
2610
|
+
maxBranches?: number;
|
|
2611
|
+
}
|
|
2612
|
+
/**
|
|
2613
|
+
* Imperative handle for CoursePlayer
|
|
2614
|
+
*/
|
|
2615
|
+
interface CoursePlayerRef {
|
|
2616
|
+
play(): void;
|
|
2617
|
+
pause(): void;
|
|
2618
|
+
seek(timeMs: number): void;
|
|
2619
|
+
setSpeed(speed: number): void;
|
|
2620
|
+
getCurrentTime(): number;
|
|
2621
|
+
getDuration(): number;
|
|
2622
|
+
getState(): PlaybackState$1;
|
|
2623
|
+
enterInteractiveMode(): void;
|
|
2624
|
+
exitInteractiveMode(): void;
|
|
2625
|
+
setActiveTool(tool: ActiveTool$1): void;
|
|
2626
|
+
}
|
|
2627
|
+
/**
|
|
2628
|
+
* CoursePlayer component
|
|
2629
|
+
*/
|
|
2630
|
+
declare const CoursePlayer: React__default.ForwardRefExoticComponent<CoursePlayerProps & React__default.RefAttributes<CoursePlayerRef>>;
|
|
2631
|
+
|
|
2632
|
+
type ActiveTool = ToolType;
|
|
2633
|
+
/**
|
|
2634
|
+
* Props for StreamingCoursePlayer
|
|
2635
|
+
*/
|
|
2636
|
+
interface StreamingCoursePlayerProps {
|
|
2637
|
+
/** URL to the streaming manifest.json */
|
|
2638
|
+
manifestUrl: string;
|
|
2639
|
+
/** Theme setting */
|
|
2640
|
+
theme?: "light" | "dark" | "system";
|
|
2641
|
+
/** Aspect ratio of the player */
|
|
2642
|
+
aspectRatio?: "16:9" | "4:3" | "auto";
|
|
2643
|
+
/** Show playback controls toolbar */
|
|
2644
|
+
showToolbar?: boolean;
|
|
2645
|
+
/** Show tool sidebar */
|
|
2646
|
+
showToolSidebar?: boolean;
|
|
2647
|
+
/** Auto-play when loaded */
|
|
2648
|
+
autoPlay?: boolean;
|
|
2649
|
+
/** Default playback speed */
|
|
2650
|
+
defaultSpeed?: number;
|
|
2651
|
+
/** Allow fullscreen mode */
|
|
2652
|
+
allowFullscreen?: boolean;
|
|
2653
|
+
/** Default active tool */
|
|
2654
|
+
defaultTool?: ActiveTool;
|
|
2655
|
+
/** Maximum chunks to cache */
|
|
2656
|
+
maxCacheSize?: number;
|
|
2657
|
+
/** Additional CSS class */
|
|
2658
|
+
className?: string;
|
|
2659
|
+
/** Called when player is ready */
|
|
2660
|
+
onReady?: () => void;
|
|
2661
|
+
/** Called when playback starts */
|
|
2662
|
+
onPlay?: () => void;
|
|
2663
|
+
/** Called when playback pauses */
|
|
2664
|
+
onPause?: () => void;
|
|
2665
|
+
/** Called on progress update */
|
|
2666
|
+
onProgress?: (time: number, duration: number) => void;
|
|
2667
|
+
/** Called when playback completes */
|
|
2668
|
+
onComplete?: () => void;
|
|
2669
|
+
/** Called on error */
|
|
2670
|
+
onError?: (error: Error) => void;
|
|
2671
|
+
/** Called when buffering state changes */
|
|
2672
|
+
onBuffering?: (isBuffering: boolean) => void;
|
|
2673
|
+
/** Called when tool changes */
|
|
2674
|
+
onToolChange?: (tool: string) => void;
|
|
2675
|
+
/** Go-Judge server URL */
|
|
2676
|
+
goJudgeUrl?: string;
|
|
2677
|
+
/** Go-Judge API key */
|
|
2678
|
+
goJudgeApiKey?: string;
|
|
2679
|
+
/** Show chapter markers */
|
|
2680
|
+
showChapters?: boolean;
|
|
2681
|
+
/** Called when entering interactive mode */
|
|
2682
|
+
onInteractionStart?: () => void;
|
|
2683
|
+
/** Called when exiting interactive mode */
|
|
2684
|
+
onInteractionEnd?: (code: string) => void;
|
|
2685
|
+
/** Interaction points (MCQs) to display during playback */
|
|
2686
|
+
interactionPoints?: InteractionPoint[];
|
|
2687
|
+
/** Pre-answered point IDs (skip these MCQs) */
|
|
2688
|
+
answeredPointIds?: Set<string>;
|
|
2689
|
+
/** Called when a learner submits an MCQ answer. Host app validates server-side. */
|
|
2690
|
+
onSubmitAnswer?: (pointId: string, selectedOptionIds: string[]) => Promise<MCQResult>;
|
|
2691
|
+
/** Info about the next lesson for auto-advance overlay */
|
|
2692
|
+
nextLesson?: {
|
|
2693
|
+
id: string;
|
|
2694
|
+
title: string;
|
|
2695
|
+
} | null;
|
|
2696
|
+
/** Called when the player wants to navigate to the next lesson */
|
|
2697
|
+
onNavigateToLesson?: (lessonId: string) => void;
|
|
2698
|
+
/** Called when the current lesson completes (before transition) */
|
|
2699
|
+
onLessonComplete?: () => void;
|
|
2700
|
+
}
|
|
2701
|
+
/**
|
|
2702
|
+
* Imperative handle for StreamingCoursePlayer
|
|
2703
|
+
*/
|
|
2704
|
+
interface StreamingCoursePlayerRef {
|
|
2705
|
+
play(): void;
|
|
2706
|
+
pause(): void;
|
|
2707
|
+
seek(timeMs: number): Promise<void>;
|
|
2708
|
+
setSpeed(speed: number): void;
|
|
2709
|
+
getCurrentTime(): number;
|
|
2710
|
+
getDuration(): number;
|
|
2711
|
+
getState(): PlaybackState$1;
|
|
2712
|
+
enterInteractiveMode(): void;
|
|
2713
|
+
exitInteractiveMode(): void;
|
|
2714
|
+
setActiveTool(tool: ActiveTool): void;
|
|
2715
|
+
getManifest(): StreamingManifest | null;
|
|
2716
|
+
getBufferHealth(): RemoteBufferHealth;
|
|
2717
|
+
}
|
|
2718
|
+
declare const StreamingCoursePlayer: React__default.ForwardRefExoticComponent<StreamingCoursePlayerProps & React__default.RefAttributes<StreamingCoursePlayerRef>>;
|
|
2451
2719
|
|
|
2452
2720
|
/**
|
|
2453
2721
|
* usePlayback Hook
|
|
@@ -2509,6 +2777,10 @@ interface PlaybackControls {
|
|
|
2509
2777
|
x: number;
|
|
2510
2778
|
y: number;
|
|
2511
2779
|
}): void;
|
|
2780
|
+
/** Inject a full branch snapshot into the interactive state. Only works when isInteracting is true. */
|
|
2781
|
+
injectInteractiveState(snapshot: BranchSnapshot): void;
|
|
2782
|
+
/** Get the engine's (instructor's) state at a given time, without affecting playback position. */
|
|
2783
|
+
getEngineStateAtTime(timeMs: number): PlaybackState$1 | null;
|
|
2512
2784
|
}
|
|
2513
2785
|
/**
|
|
2514
2786
|
* Options for usePlayback hook
|
|
@@ -2755,7 +3027,7 @@ declare function useAudioSync(options: UseAudioSyncOptions): AudioSyncState & {
|
|
|
2755
3027
|
* Hook for managing audio element lifecycle
|
|
2756
3028
|
*/
|
|
2757
3029
|
declare function useAudioElement(src: string | null): {
|
|
2758
|
-
audioRef:
|
|
3030
|
+
audioRef: React__default.MutableRefObject<HTMLAudioElement | null>;
|
|
2759
3031
|
isLoaded: boolean;
|
|
2760
3032
|
error: Error | null;
|
|
2761
3033
|
duration: number;
|
|
@@ -2826,12 +3098,163 @@ declare function useVideoSync(options: UseVideoSyncOptions): VideoSyncState & {
|
|
|
2826
3098
|
* Hook for managing video element lifecycle
|
|
2827
3099
|
*/
|
|
2828
3100
|
declare function useVideoElement(src: string | null): {
|
|
2829
|
-
videoRef:
|
|
3101
|
+
videoRef: React__default.MutableRefObject<HTMLVideoElement | null>;
|
|
2830
3102
|
isLoaded: boolean;
|
|
2831
3103
|
error: Error | null;
|
|
2832
3104
|
duration: number;
|
|
2833
3105
|
};
|
|
2834
3106
|
|
|
3107
|
+
/**
|
|
3108
|
+
* useInteractionPoints — monitors playback time and triggers MCQ pauses.
|
|
3109
|
+
*
|
|
3110
|
+
* The hook is player-mode agnostic: it only needs the current time (ms),
|
|
3111
|
+
* a pause callback, and a play callback. Both CoursePlayer and
|
|
3112
|
+
* StreamingCoursePlayer can use it.
|
|
3113
|
+
*
|
|
3114
|
+
* Edge cases handled:
|
|
3115
|
+
* - Seek past unanswered MCQ → still triggers (first unanswered point ≤ currentTime)
|
|
3116
|
+
* - Seek backwards past a triggered-but-unanswered point → re-evaluates
|
|
3117
|
+
* - Multiple MCQs at exact same time → triggers in array order
|
|
3118
|
+
* - Race: activePoint takes priority — no duplicate triggers while overlay is open
|
|
3119
|
+
*
|
|
3120
|
+
* @packageDocumentation
|
|
3121
|
+
*/
|
|
3122
|
+
|
|
3123
|
+
interface UseInteractionPointsOptions {
|
|
3124
|
+
/** Sorted interaction points (ascending by timeMs) */
|
|
3125
|
+
interactionPoints: InteractionPoint[];
|
|
3126
|
+
/** Current playback time in milliseconds */
|
|
3127
|
+
currentTimeMs: number;
|
|
3128
|
+
/** Callback to pause playback */
|
|
3129
|
+
pause: () => void;
|
|
3130
|
+
/** Callback to resume playback */
|
|
3131
|
+
play: () => void;
|
|
3132
|
+
/** Pre-loaded set of already-answered point IDs */
|
|
3133
|
+
initialAnsweredPointIds?: Set<string>;
|
|
3134
|
+
}
|
|
3135
|
+
interface UseInteractionPointsResult {
|
|
3136
|
+
/** The interaction point currently requiring attention, or null */
|
|
3137
|
+
activePoint: InteractionPoint | null;
|
|
3138
|
+
/** Dismiss the active point (adds to answered, resumes playback) */
|
|
3139
|
+
dismissPoint: () => void;
|
|
3140
|
+
/** Mark a point as answered without dismissing (for pre-loading state) */
|
|
3141
|
+
markAnswered: (pointId: string) => void;
|
|
3142
|
+
/** Set of all answered point IDs */
|
|
3143
|
+
answeredPointIds: Set<string>;
|
|
3144
|
+
}
|
|
3145
|
+
declare function useInteractionPoints({ interactionPoints, currentTimeMs, pause, play, initialAnsweredPointIds, }: UseInteractionPointsOptions): UseInteractionPointsResult;
|
|
3146
|
+
|
|
3147
|
+
/**
|
|
3148
|
+
* useBranching — manages lesson-to-lesson transition with auto-advance countdown.
|
|
3149
|
+
*
|
|
3150
|
+
* @packageDocumentation
|
|
3151
|
+
*/
|
|
3152
|
+
interface UseBranchingOptions {
|
|
3153
|
+
/** Next lesson info (null = course complete) */
|
|
3154
|
+
nextLesson: {
|
|
3155
|
+
id: string;
|
|
3156
|
+
title: string;
|
|
3157
|
+
} | null;
|
|
3158
|
+
/** Seconds before auto-navigating (default 5) */
|
|
3159
|
+
autoAdvanceSeconds?: number;
|
|
3160
|
+
/** Called when auto-advance or manual skip triggers navigation */
|
|
3161
|
+
onNavigate: (lessonId: string) => void;
|
|
3162
|
+
}
|
|
3163
|
+
interface UseBranchingResult {
|
|
3164
|
+
/** Whether the transition overlay is active */
|
|
3165
|
+
isTransitioning: boolean;
|
|
3166
|
+
/** Current countdown value (seconds remaining, 0 = done) */
|
|
3167
|
+
countdown: number;
|
|
3168
|
+
/** Start the transition overlay + countdown */
|
|
3169
|
+
startTransition: () => void;
|
|
3170
|
+
/** Skip the countdown and navigate immediately */
|
|
3171
|
+
skipToNext: () => void;
|
|
3172
|
+
/** Pause the auto-advance but keep the overlay visible */
|
|
3173
|
+
cancelAutoAdvance: () => void;
|
|
3174
|
+
}
|
|
3175
|
+
declare function useBranching({ nextLesson, autoAdvanceSeconds, onNavigate, }: UseBranchingOptions): UseBranchingResult;
|
|
3176
|
+
|
|
3177
|
+
/**
|
|
3178
|
+
* useBranches — manages learner branch state for a single lesson.
|
|
3179
|
+
*
|
|
3180
|
+
* Handles save / delete / rename / restore of learner code snapshots,
|
|
3181
|
+
* persisted to localStorage via branchStorage utilities.
|
|
3182
|
+
*
|
|
3183
|
+
* @packageDocumentation
|
|
3184
|
+
*/
|
|
3185
|
+
|
|
3186
|
+
interface UseBranchesOptions {
|
|
3187
|
+
/** Lesson/recording ID — branches are scoped to this. Undefined = feature disabled. */
|
|
3188
|
+
lessonId: string | undefined;
|
|
3189
|
+
/** Returns current playback time in milliseconds */
|
|
3190
|
+
getCurrentTimeMs: () => number;
|
|
3191
|
+
/** Captures the learner's current IDE state (interactive mode state) */
|
|
3192
|
+
getCurrentState: () => BranchSnapshot;
|
|
3193
|
+
/** Captures the instructor's state at the current time from the engine */
|
|
3194
|
+
getOriginalState: () => BranchSnapshot;
|
|
3195
|
+
/** Called when the learner wants to restore a branch (parent orchestrates seek + inject) */
|
|
3196
|
+
onRestoreBranch?: (branch: LearnerBranch) => void;
|
|
3197
|
+
/** Called after a branch is successfully saved (for analytics / callbacks) */
|
|
3198
|
+
onBranchSaved?: (branch: LearnerBranch) => void;
|
|
3199
|
+
/** Called after a branch is deleted */
|
|
3200
|
+
onBranchDeleted?: (branchId: string) => void;
|
|
3201
|
+
/** Maximum branches per lesson (default 50) */
|
|
3202
|
+
maxBranches?: number;
|
|
3203
|
+
}
|
|
3204
|
+
interface UseBranchesResult {
|
|
3205
|
+
/** All branches for the current lesson, sorted oldest-first */
|
|
3206
|
+
branches: LearnerBranch[];
|
|
3207
|
+
/** Number of saved branches */
|
|
3208
|
+
branchCount: number;
|
|
3209
|
+
/** Whether the feature is enabled (lessonId is defined) */
|
|
3210
|
+
enabled: boolean;
|
|
3211
|
+
/** Save a new branch from the current interactive state. Returns the created branch, or null if disabled / duplicate. */
|
|
3212
|
+
saveBranch: (label?: string) => LearnerBranch | null;
|
|
3213
|
+
/** Delete a branch by ID */
|
|
3214
|
+
deleteBranch: (branchId: string) => void;
|
|
3215
|
+
/** Rename a branch */
|
|
3216
|
+
renameBranch: (branchId: string, label: string) => void;
|
|
3217
|
+
/** Restore a branch — delegates to parent via onRestoreBranch callback */
|
|
3218
|
+
restoreBranch: (branchId: string) => void;
|
|
3219
|
+
/** Check if a branch at this timeMs with this code already exists (duplicate detection) */
|
|
3220
|
+
isDuplicate: (timeMs: number, code: string) => boolean;
|
|
3221
|
+
}
|
|
3222
|
+
declare function useBranches(options: UseBranchesOptions): UseBranchesResult;
|
|
3223
|
+
|
|
3224
|
+
/**
|
|
3225
|
+
* Branch Storage — localStorage CRUD helpers
|
|
3226
|
+
*
|
|
3227
|
+
* Persists learner branches as JSON arrays keyed by lesson ID.
|
|
3228
|
+
* Key format: `ct-branches:<lessonId>`
|
|
3229
|
+
*
|
|
3230
|
+
* Pure functions — no React, no hooks.
|
|
3231
|
+
*
|
|
3232
|
+
* @packageDocumentation
|
|
3233
|
+
*/
|
|
3234
|
+
|
|
3235
|
+
/**
|
|
3236
|
+
* Load all branches for a lesson from localStorage.
|
|
3237
|
+
* Returns empty array if nothing stored or on parse error.
|
|
3238
|
+
* Sorted by `createdAt` ascending (oldest first).
|
|
3239
|
+
*/
|
|
3240
|
+
declare function loadBranches(lessonId: string): LearnerBranch[];
|
|
3241
|
+
/**
|
|
3242
|
+
* Persist a new branch. Caps at `maxBranches` per lesson (drops oldest).
|
|
3243
|
+
*/
|
|
3244
|
+
declare function saveBranch(lessonId: string, branch: LearnerBranch, maxBranches?: number): void;
|
|
3245
|
+
/**
|
|
3246
|
+
* Delete a single branch by ID.
|
|
3247
|
+
*/
|
|
3248
|
+
declare function deleteBranch(lessonId: string, branchId: string): void;
|
|
3249
|
+
/**
|
|
3250
|
+
* Update the label of an existing branch.
|
|
3251
|
+
*/
|
|
3252
|
+
declare function updateBranchLabel(lessonId: string, branchId: string, label: string): void;
|
|
3253
|
+
/**
|
|
3254
|
+
* Format milliseconds as "MM:SS" for default branch labels.
|
|
3255
|
+
*/
|
|
3256
|
+
declare function formatBranchTime(ms: number): string;
|
|
3257
|
+
|
|
2835
3258
|
/**
|
|
2836
3259
|
* HLS Loader Utility
|
|
2837
3260
|
*
|
|
@@ -2927,7 +3350,14 @@ declare function destroyHlsPlayer(player: HLSPlayerInstance | HLSVideoPlayerInst
|
|
|
2927
3350
|
interface Marker$1 {
|
|
2928
3351
|
time: number;
|
|
2929
3352
|
label?: string;
|
|
2930
|
-
type?:
|
|
3353
|
+
type?: "chapter" | "bookmark" | "quiz";
|
|
3354
|
+
}
|
|
3355
|
+
interface VideoQualityLevel {
|
|
3356
|
+
index: number;
|
|
3357
|
+
bitrate: number;
|
|
3358
|
+
codecs: string;
|
|
3359
|
+
width?: number;
|
|
3360
|
+
height?: number;
|
|
2931
3361
|
}
|
|
2932
3362
|
interface PlayerControlsProps {
|
|
2933
3363
|
isPlaying: boolean;
|
|
@@ -2938,6 +3368,9 @@ interface PlayerControlsProps {
|
|
|
2938
3368
|
playbackSpeed: number;
|
|
2939
3369
|
markers?: Marker$1[];
|
|
2940
3370
|
isFullscreen?: boolean;
|
|
3371
|
+
videoQualityLevels?: VideoQualityLevel[];
|
|
3372
|
+
videoQualityLevel?: number;
|
|
3373
|
+
onVideoQualityChange?: (index: number) => void;
|
|
2941
3374
|
onPlayPause: () => void;
|
|
2942
3375
|
onSeek: (timeMs: number) => void;
|
|
2943
3376
|
onSeekStart?: () => void;
|
|
@@ -2948,11 +3381,28 @@ interface PlayerControlsProps {
|
|
|
2948
3381
|
onMuteToggle: () => void;
|
|
2949
3382
|
onSpeedChange: (speed: number) => void;
|
|
2950
3383
|
onFullscreenToggle?: () => void;
|
|
3384
|
+
/** Called when the user interacts with the code editor area while playing.
|
|
3385
|
+
* The parent should pause playback when this fires. */
|
|
3386
|
+
onEditorInteraction?: () => void;
|
|
3387
|
+
/** Interaction points — purple dots rendered on the seek bar */
|
|
3388
|
+
interactionPoints?: InteractionPoint[];
|
|
3389
|
+
/** Saved learner branches — green diamond markers on the progress bar */
|
|
3390
|
+
branches?: LearnerBranch[];
|
|
3391
|
+
/** Callback when a branch marker is clicked */
|
|
3392
|
+
onBranchClick?: (branch: LearnerBranch) => void;
|
|
3393
|
+
/** Number of saved branches (for badge) */
|
|
3394
|
+
branchCount?: number;
|
|
3395
|
+
/** Whether the branch panel is currently open */
|
|
3396
|
+
isBranchPanelOpen?: boolean;
|
|
3397
|
+
/** Toggle the branch panel */
|
|
3398
|
+
onBranchPanelToggle?: () => void;
|
|
3399
|
+
/** Whether the learner is in interactive/editing mode */
|
|
3400
|
+
isInteractive?: boolean;
|
|
2951
3401
|
showMarkers?: boolean;
|
|
2952
3402
|
compact?: boolean;
|
|
2953
|
-
containerRef?:
|
|
3403
|
+
containerRef?: React__default__default.RefObject<HTMLElement>;
|
|
2954
3404
|
}
|
|
2955
|
-
declare function PlayerControls({ isPlaying, currentTime, duration, volume, muted, playbackSpeed, markers, isFullscreen, onPlayPause, onSeek, onSeekStart, onSeekEnd, onSkip, onRestart, onVolumeChange, onMuteToggle, onSpeedChange, onFullscreenToggle, showMarkers, compact, }: PlayerControlsProps): react_jsx_runtime.JSX.Element;
|
|
3405
|
+
declare function PlayerControls({ isPlaying, currentTime, duration, volume, muted, playbackSpeed, markers, isFullscreen, videoQualityLevels, videoQualityLevel, onVideoQualityChange, onPlayPause, onSeek, onSeekStart, onSeekEnd, onSkip, onRestart, onVolumeChange, onMuteToggle, onSpeedChange, onFullscreenToggle, onEditorInteraction, interactionPoints, branches, onBranchClick, branchCount, isBranchPanelOpen, onBranchPanelToggle, isInteractive, showMarkers, compact, }: PlayerControlsProps): react_jsx_runtime.JSX.Element;
|
|
2956
3406
|
|
|
2957
3407
|
/**
|
|
2958
3408
|
* Timeline Component
|
|
@@ -2969,7 +3419,7 @@ interface Marker {
|
|
|
2969
3419
|
id: string;
|
|
2970
3420
|
time: number;
|
|
2971
3421
|
label: string;
|
|
2972
|
-
type: 'chapter' | '
|
|
3422
|
+
type: 'chapter' | 'bookmark' | 'quiz' | 'note' | 'error';
|
|
2973
3423
|
description?: string;
|
|
2974
3424
|
}
|
|
2975
3425
|
/**
|
|
@@ -3024,6 +3474,128 @@ interface TimelineProps {
|
|
|
3024
3474
|
*/
|
|
3025
3475
|
declare function Timeline({ currentTime, duration, markers, chunks, buffered, onSeek, onMarkerClick, theme, showChapterLabels, showBufferStatus, showChunkIndicators, compact, }: TimelineProps): JSX.Element;
|
|
3026
3476
|
|
|
3477
|
+
/**
|
|
3478
|
+
* MCQOverlay — full-area overlay that renders a multiple-choice question
|
|
3479
|
+
* on top of the player content.
|
|
3480
|
+
*
|
|
3481
|
+
* Phases: Question → Loading → Feedback (with optional retry).
|
|
3482
|
+
* Handles timeout countdown, focus trapping, and keyboard navigation.
|
|
3483
|
+
*
|
|
3484
|
+
* @packageDocumentation
|
|
3485
|
+
*/
|
|
3486
|
+
|
|
3487
|
+
interface MCQOverlayProps {
|
|
3488
|
+
/** The interaction point to display */
|
|
3489
|
+
point: InteractionPoint;
|
|
3490
|
+
/** Called when the learner submits an answer. Returns result from host app. */
|
|
3491
|
+
onSubmit: (selectedOptionIds: string[]) => Promise<MCQResult>;
|
|
3492
|
+
/** Called when the learner is done (correct answer, or gave up) */
|
|
3493
|
+
onDismiss: () => void;
|
|
3494
|
+
/** Optional extra class name for the outer container */
|
|
3495
|
+
className?: string;
|
|
3496
|
+
}
|
|
3497
|
+
declare const MCQOverlay: React__default__default.FC<MCQOverlayProps>;
|
|
3498
|
+
|
|
3499
|
+
/**
|
|
3500
|
+
* BranchTransition — end-of-lesson overlay with auto-advance countdown.
|
|
3501
|
+
*
|
|
3502
|
+
* Shows "Next: [title]" with countdown + skip/cancel, or a "Course Complete"
|
|
3503
|
+
* message when there's no next lesson.
|
|
3504
|
+
*
|
|
3505
|
+
* @packageDocumentation
|
|
3506
|
+
*/
|
|
3507
|
+
|
|
3508
|
+
interface BranchTransitionProps {
|
|
3509
|
+
/** Title of the next lesson */
|
|
3510
|
+
nextLessonTitle: string;
|
|
3511
|
+
/** Countdown seconds remaining */
|
|
3512
|
+
countdown: number;
|
|
3513
|
+
/** Skip countdown and navigate immediately */
|
|
3514
|
+
onSkip: () => void;
|
|
3515
|
+
/** Stop auto-advance (stay on current lesson) */
|
|
3516
|
+
onCancel: () => void;
|
|
3517
|
+
/** If true, show "Course Complete" instead of next lesson */
|
|
3518
|
+
isComplete?: boolean;
|
|
3519
|
+
}
|
|
3520
|
+
declare const BranchTransition: React__default__default.FC<BranchTransitionProps>;
|
|
3521
|
+
|
|
3522
|
+
/**
|
|
3523
|
+
* SaveBranchButton — floating pill button shown in the top-right of the IDE
|
|
3524
|
+
* panel when the learner is in interactive mode and has made code changes.
|
|
3525
|
+
*
|
|
3526
|
+
* @packageDocumentation
|
|
3527
|
+
*/
|
|
3528
|
+
|
|
3529
|
+
interface SaveBranchButtonProps {
|
|
3530
|
+
/** Whether the button should be visible */
|
|
3531
|
+
visible: boolean;
|
|
3532
|
+
/** Called when the learner clicks "Save Branch" */
|
|
3533
|
+
onSave: () => void;
|
|
3534
|
+
/** Whether the max branch limit has been reached */
|
|
3535
|
+
limitReached?: boolean;
|
|
3536
|
+
}
|
|
3537
|
+
declare const SaveBranchButton: React__default__default.FC<SaveBranchButtonProps>;
|
|
3538
|
+
|
|
3539
|
+
/**
|
|
3540
|
+
* BranchSavedToast — brief confirmation toast shown after saving a branch.
|
|
3541
|
+
*
|
|
3542
|
+
* Slides up, holds, then fades out automatically.
|
|
3543
|
+
*
|
|
3544
|
+
* @packageDocumentation
|
|
3545
|
+
*/
|
|
3546
|
+
|
|
3547
|
+
interface BranchSavedToastProps {
|
|
3548
|
+
/** Whether to show the toast */
|
|
3549
|
+
visible: boolean;
|
|
3550
|
+
/** Called when the toast fully disappears */
|
|
3551
|
+
onDismiss: () => void;
|
|
3552
|
+
/** Optional message override (defaults to "Branch saved") */
|
|
3553
|
+
message?: string;
|
|
3554
|
+
/** Show as a duplicate/error toast instead of success */
|
|
3555
|
+
variant?: "success" | "duplicate";
|
|
3556
|
+
}
|
|
3557
|
+
declare const BranchSavedToast: React__default__default.FC<BranchSavedToastProps>;
|
|
3558
|
+
|
|
3559
|
+
/**
|
|
3560
|
+
* UnsavedBranchPrompt — tooltip-style popup that appears near the play button
|
|
3561
|
+
* when the learner exits interactive mode with unsaved code changes.
|
|
3562
|
+
*
|
|
3563
|
+
* Offers "Save & Resume" or "Discard & Resume". Auto-dismisses after 5 seconds.
|
|
3564
|
+
*
|
|
3565
|
+
* @packageDocumentation
|
|
3566
|
+
*/
|
|
3567
|
+
|
|
3568
|
+
interface UnsavedBranchPromptProps {
|
|
3569
|
+
/** Whether to show the prompt */
|
|
3570
|
+
visible: boolean;
|
|
3571
|
+
/** Called when the user chooses "Save & Resume" */
|
|
3572
|
+
onSaveAndResume: () => void;
|
|
3573
|
+
/** Called when the user chooses "Discard & Resume" or prompt auto-dismisses */
|
|
3574
|
+
onDiscardAndResume: () => void;
|
|
3575
|
+
}
|
|
3576
|
+
declare const UnsavedBranchPrompt: React__default__default.FC<UnsavedBranchPromptProps>;
|
|
3577
|
+
|
|
3578
|
+
interface BranchPanelProps {
|
|
3579
|
+
/** Whether the panel is visible */
|
|
3580
|
+
visible: boolean;
|
|
3581
|
+
/** All branches for the current lesson */
|
|
3582
|
+
branches: LearnerBranch[];
|
|
3583
|
+
/** Close the panel */
|
|
3584
|
+
onClose: () => void;
|
|
3585
|
+
/** Restore a branch (seek + interactive + inject) */
|
|
3586
|
+
onRestore: (branch: LearnerBranch) => void;
|
|
3587
|
+
/** Delete a branch by id */
|
|
3588
|
+
onDelete: (branchId: string) => void;
|
|
3589
|
+
/** Rename a branch */
|
|
3590
|
+
onRename: (branchId: string, newLabel: string) => void;
|
|
3591
|
+
/** Maximum branches per lesson (for limit warning) */
|
|
3592
|
+
maxBranches?: number;
|
|
3593
|
+
/** Ref to the anchor element for fixed positioning */
|
|
3594
|
+
anchorRef?: React__default__default.RefObject<HTMLDivElement>;
|
|
3595
|
+
}
|
|
3596
|
+
declare function BranchPanelInner({ visible, branches, onClose, onRestore, onDelete, onRename, maxBranches, anchorRef, }: BranchPanelProps): react_jsx_runtime.JSX.Element | null;
|
|
3597
|
+
declare const BranchPanel: React__default__default.MemoExoticComponent<typeof BranchPanelInner>;
|
|
3598
|
+
|
|
3027
3599
|
/**
|
|
3028
3600
|
* AudioOverlay Component
|
|
3029
3601
|
*
|
|
@@ -3088,89 +3660,54 @@ interface AudioOverlayProps {
|
|
|
3088
3660
|
declare function AudioOverlay({ src, currentTime: _currentTime, isPlaying: _isPlaying, playbackRate: _playbackRate, position, customPosition, visible, draggable, showControls, opacity, onPositionChange, onAudioRef, muted: _muted, volume: _volume, syncTolerance: _syncTolerance, }: AudioOverlayProps): JSX.Element | null;
|
|
3089
3661
|
|
|
3090
3662
|
/**
|
|
3091
|
-
* WebcamOverlay Component
|
|
3663
|
+
* WebcamOverlay Component v3
|
|
3092
3664
|
*
|
|
3093
|
-
*
|
|
3094
|
-
*
|
|
3665
|
+
* Clean webcam video overlay with:
|
|
3666
|
+
* - Draggable circular bubble
|
|
3667
|
+
* - Maximize on hover click
|
|
3668
|
+
* - Smooth animations
|
|
3095
3669
|
*
|
|
3096
3670
|
* @packageDocumentation
|
|
3097
3671
|
*/
|
|
3098
|
-
|
|
3099
|
-
|
|
3100
|
-
*/
|
|
3101
|
-
type OverlayPosition = 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left' | 'custom';
|
|
3102
|
-
/**
|
|
3103
|
-
* Overlay size presets
|
|
3104
|
-
*/
|
|
3105
|
-
type OverlaySize = 'small' | 'medium' | 'large' | 'custom';
|
|
3106
|
-
/**
|
|
3107
|
-
* Custom position
|
|
3108
|
-
*/
|
|
3672
|
+
type OverlayPosition = "top-right" | "top-left" | "bottom-right" | "bottom-left" | "custom";
|
|
3673
|
+
type OverlaySize = "small" | "medium" | "large" | "custom";
|
|
3109
3674
|
interface CustomPosition {
|
|
3110
3675
|
x: number;
|
|
3111
3676
|
y: number;
|
|
3112
3677
|
}
|
|
3113
|
-
/**
|
|
3114
|
-
* Custom size
|
|
3115
|
-
*/
|
|
3116
3678
|
interface CustomSize {
|
|
3117
3679
|
width: number;
|
|
3118
3680
|
height: number;
|
|
3119
3681
|
}
|
|
3120
|
-
/**
|
|
3121
|
-
* Props for WebcamOverlay component
|
|
3122
|
-
*/
|
|
3123
3682
|
interface WebcamOverlayProps {
|
|
3124
|
-
/** Video source URL */
|
|
3125
3683
|
src: string | null;
|
|
3126
|
-
/** Current time to sync to (ms) */
|
|
3127
3684
|
currentTime: number;
|
|
3128
|
-
/** Whether video should be playing */
|
|
3129
3685
|
isPlaying: boolean;
|
|
3130
|
-
/** Playback rate */
|
|
3131
3686
|
playbackRate?: number;
|
|
3132
|
-
/** Overlay position preset */
|
|
3133
3687
|
position?: OverlayPosition;
|
|
3134
|
-
/** Custom position (when position='custom') */
|
|
3135
3688
|
customPosition?: CustomPosition;
|
|
3136
|
-
/** Size preset */
|
|
3137
3689
|
size?: OverlaySize;
|
|
3138
|
-
/** Custom size (when size='custom') */
|
|
3139
3690
|
customSize?: CustomSize;
|
|
3140
|
-
/** Whether to show the overlay */
|
|
3141
3691
|
visible?: boolean;
|
|
3142
|
-
/** Enable dragging */
|
|
3143
3692
|
draggable?: boolean;
|
|
3144
|
-
/** Enable resize */
|
|
3145
3693
|
resizable?: boolean;
|
|
3146
|
-
/** Show controls on hover */
|
|
3147
3694
|
showControls?: boolean;
|
|
3148
|
-
|
|
3149
|
-
borderRadius?: number | 'circle';
|
|
3150
|
-
/** Opacity (0-1) */
|
|
3695
|
+
borderRadius?: number | "circle";
|
|
3151
3696
|
opacity?: number;
|
|
3152
|
-
/** On position change callback */
|
|
3153
3697
|
onPositionChange?: (position: CustomPosition) => void;
|
|
3154
|
-
/** On size change callback */
|
|
3155
3698
|
onSizeChange?: (size: CustomSize) => void;
|
|
3156
|
-
/** On visibility toggle callback */
|
|
3157
3699
|
onVisibilityToggle?: () => void;
|
|
3158
|
-
/** Callback to pass video element reference for sync */
|
|
3159
3700
|
onVideoRef?: (video: HTMLVideoElement | null) => void;
|
|
3160
|
-
/** Whether audio is muted */
|
|
3161
3701
|
muted?: boolean;
|
|
3162
|
-
/** Volume level (0-1) */
|
|
3163
3702
|
volume?: number;
|
|
3164
|
-
/** Sync tolerance in ms */
|
|
3165
3703
|
syncTolerance?: number;
|
|
3166
|
-
|
|
3167
|
-
|
|
3168
|
-
|
|
3169
|
-
|
|
3170
|
-
|
|
3171
|
-
|
|
3172
|
-
|
|
3173
|
-
|
|
3174
|
-
declare function WebcamOverlay({ src, currentTime: _currentTime, isPlaying: _isPlaying, playbackRate: _playbackRate, position, customPosition, size, customSize, visible, draggable, resizable, showControls, borderRadius, opacity, onPositionChange, onSizeChange: _onSizeChange, onVisibilityToggle: _onVisibilityToggle, onVideoRef, muted: _muted, volume: _volume, syncTolerance: _syncTolerance, }: WebcamOverlayProps): JSX.Element | null;
|
|
3704
|
+
/** Whether webcam is in maximized (full overlay) mode - from playback events */
|
|
3705
|
+
maximized?: boolean;
|
|
3706
|
+
/** Callback when user clicks minimize button */
|
|
3707
|
+
onMinimize?: () => void;
|
|
3708
|
+
/** Callback when user clicks maximize button */
|
|
3709
|
+
onMaximize?: () => void;
|
|
3710
|
+
}
|
|
3711
|
+
declare function WebcamOverlay({ src, currentTime: _currentTime, isPlaying: _isPlaying, playbackRate: _playbackRate, position, customPosition, size, customSize, visible, draggable, resizable: _resizable, showControls: _showControls, borderRadius, opacity, onPositionChange, onSizeChange: _onSizeChange, onVisibilityToggle: _onVisibilityToggle, onVideoRef, muted: _muted, volume: _volume, syncTolerance: _syncTolerance, maximized, onMinimize, onMaximize, }: WebcamOverlayProps): JSX.Element | null;
|
|
3175
3712
|
|
|
3176
|
-
export { AudioOverlay, type AudioOverlayProps, type AudioQuality, type AudioSyncControls, type AudioSyncState, type BackendAdapter, type BufferHealth, type CTEvent, type CTManifest, type CTMarker, type CTReadOptions, type CTRecording, CoursePlayer, type CoursePlayerProps, type CoursePlayerRef, type CursorPosition, type CustomPosition$1 as CustomPosition, DocumentPanel, type DocumentPanelProps, FileExplorer, type FileExplorerProps, type FileSystemSnapshot, type HLSPlayerInstance, HLS_EVENTS, IDEPanel, type IDEPanelProps, type InternalEvent, type InternalRecording, type OverlayPosition$1 as OverlayPosition, type PanelMode, type PlaybackControls$1 as PlaybackControls, type PlaybackEngineConfig, type PlaybackHookState, type PlaybackState, PlayerControls, type PlayerControlsProps$1 as PlayerControlsProps, type PlayerProps, type PlayerRef, type RecordingMarker, type RemoteBufferHealth, type RemoteStreamingMetrics, type RemoteStreamingPlaybackControls, type RemoteStreamingPlaybackState, type SpeedSelectorProps, type StreamingAudioConfig, type StreamingConfig, StreamingCoursePlayer, type StreamingCoursePlayerProps, type StreamingCoursePlayerRef, type StreamingEventsConfig, type StreamingManifest, type StreamingMetrics, type StreamingPlaybackControls, type StreamingPlaybackState, type StreamingRecordingInfo, Terminal, type TerminalLineData, type TerminalProps, Timeline, type TimelineProps$1 as TimelineProps, ToolSidebar, type ToolSidebarProps, type ToolType, type UseAudioSyncOptions, type UsePlaybackEngineResult, type UsePlaybackOptions, type UseRemoteStreamingPlaybackOptions, type UseVideoSyncOptions, type ValidationResult$1 as ValidationResult, type VideoSyncControls, type VideoSyncState, type VolumeControlProps, WebcamOverlay, type WebcamOverlayProps, WhiteboardPanel, type WhiteboardPanelProps, type WriteCTOptions, canPlayHls, createEmptyRecording, createHlsPlayer, destroyHlsPlayer, hasNativeHlsSupport, isHlsSupported, readCTFile, readCTManifest, useAudioElement, useAudioSync, useInteractiveMode, usePlayback, usePlayback as usePlaybackEngine, useRemoteStreamingPlayback, useStreamingPlayback, useVideoElement, useVideoSync, validateCTFile, writeCTFile };
|
|
3713
|
+
export { AudioOverlay, type AudioOverlayProps, type AudioQuality, type AudioSyncControls, type AudioSyncState, type BackendAdapter, BranchPanel, type BranchPanelProps, BranchSavedToast, type BranchSavedToastProps, type BranchSnapshot, BranchTransition, type BranchTransitionProps, type BufferHealth, type CTEvent, type CTManifest, type CTMarker, type CTReadOptions, type CTRecording, CoursePlayer, type CoursePlayerProps, type CoursePlayerRef, type CursorPosition, type CustomPosition$1 as CustomPosition, DocumentPanel, type DocumentPanelProps, FileExplorer, type FileExplorerProps, type FileSystemSnapshot, type HLSPlayerInstance, HLS_EVENTS, IDEPanel, type IDEPanelProps, type InteractionPoint, type InternalEvent, type InternalRecording, type LearnerBranch, MCQOverlay, type MCQOverlayProps, type MCQResult, type MCQSubmission, type OverlayPosition$1 as OverlayPosition, type PanelMode, type PlaybackControls$1 as PlaybackControls, type PlaybackEngineConfig, type PlaybackHookState, type PlaybackState, PlayerControls, type PlayerControlsProps$1 as PlayerControlsProps, type PlayerProps, type PlayerRef, type RecordingMarker, type RemoteBufferHealth, type RemoteStreamingMetrics, type RemoteStreamingPlaybackControls, type RemoteStreamingPlaybackState, SaveBranchButton, type SaveBranchButtonProps, type SpeedSelectorProps, type StreamingAudioConfig, type StreamingConfig, StreamingCoursePlayer, type StreamingCoursePlayerProps, type StreamingCoursePlayerRef, type StreamingEventsConfig, type StreamingManifest, type StreamingMetrics, type StreamingPlaybackControls, type StreamingPlaybackState, type StreamingRecordingInfo, Terminal, type TerminalLineData, type TerminalProps, Timeline, type TimelineProps$1 as TimelineProps, ToolSidebar, type ToolSidebarProps, type ToolType, UnsavedBranchPrompt, type UnsavedBranchPromptProps, type UseAudioSyncOptions, type UseBranchesOptions, type UseBranchesResult, type UseBranchingOptions, type UseBranchingResult, type UseInteractionPointsOptions, type UseInteractionPointsResult, type UsePlaybackEngineResult, type UsePlaybackOptions, type UseRemoteStreamingPlaybackOptions, type UseVideoSyncOptions, type ValidationResult$1 as ValidationResult, type VideoSyncControls, type VideoSyncState, type VolumeControlProps, WebcamOverlay, type WebcamOverlayProps, WhiteboardPanel, type WhiteboardPanelProps, type WriteCTOptions, canPlayHls, createEmptyRecording, createHlsPlayer, deleteBranch as deleteBranchFromStorage, destroyHlsPlayer, formatBranchTime, hasNativeHlsSupport, isHlsSupported, loadBranches, readCTFile, readCTManifest, saveBranch as saveBranchToStorage, updateBranchLabel, useAudioElement, useAudioSync, useBranches, useBranching, useInteractionPoints, useInteractiveMode, usePlayback, usePlayback as usePlaybackEngine, useRemoteStreamingPlayback, useStreamingPlayback, useVideoElement, useVideoSync, validateCTFile, writeCTFile };
|