@readerseye2/cr_viewer 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/CR_Viewer.d.ts +24 -0
- package/dist/CR_Viewer.d.ts.map +1 -0
- package/dist/components/PageSectionWrap.d.ts +15 -0
- package/dist/components/PageSectionWrap.d.ts.map +1 -0
- package/dist/components/PaginationRender.d.ts +11 -0
- package/dist/components/PaginationRender.d.ts.map +1 -0
- package/dist/components/RenderParagraph.d.ts +16 -0
- package/dist/components/RenderParagraph.d.ts.map +1 -0
- package/dist/components/RenderRuns.d.ts +14 -0
- package/dist/components/RenderRuns.d.ts.map +1 -0
- package/dist/components/ScrollSectionWrap.d.ts +2 -0
- package/dist/components/ScrollSectionWrap.d.ts.map +1 -0
- package/dist/components/SectionRendererVirtuoso.d.ts +7 -0
- package/dist/components/SectionRendererVirtuoso.d.ts.map +1 -0
- package/dist/components/btns/MoveSectionBtns.d.ts +18 -0
- package/dist/components/btns/MoveSectionBtns.d.ts.map +1 -0
- package/dist/components/btns/SolveQuizBtn.d.ts +2 -0
- package/dist/components/btns/SolveQuizBtn.d.ts.map +1 -0
- package/dist/components/dom.util.d.ts +40 -0
- package/dist/components/dom.util.d.ts.map +1 -0
- package/dist/components/quiz/QuizRenderer.d.ts +3 -0
- package/dist/components/quiz/QuizRenderer.d.ts.map +1 -0
- package/dist/components/scroll/CustomScroller.d.ts +4 -0
- package/dist/components/scroll/CustomScroller.d.ts.map +1 -0
- package/dist/components/spinner/SectionLoadingSpinner.d.ts +2 -0
- package/dist/components/spinner/SectionLoadingSpinner.d.ts.map +1 -0
- package/dist/components/spinner/Spinner.d.ts +10 -0
- package/dist/components/spinner/Spinner.d.ts.map +1 -0
- package/dist/hooks/useDebounce.d.ts +16 -0
- package/dist/hooks/useDebounce.d.ts.map +1 -0
- package/dist/hooks/useLongPressSpan.d.ts +10 -0
- package/dist/hooks/useLongPressSpan.d.ts.map +1 -0
- package/dist/hooks/useResizeObserver.d.ts +2 -0
- package/dist/hooks/useResizeObserver.d.ts.map +1 -0
- package/dist/hooks/useSingleDoubleClick.d.ts +16 -0
- package/dist/hooks/useSingleDoubleClick.d.ts.map +1 -0
- package/dist/hooks/useSwipePageClicks.d.ts +24 -0
- package/dist/hooks/useSwipePageClicks.d.ts.map +1 -0
- package/dist/index.cjs +33 -0
- package/dist/index.css +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8723 -0
- package/dist/overlay-bars/OverlayLayer.d.ts +3 -0
- package/dist/overlay-bars/OverlayLayer.d.ts.map +1 -0
- package/dist/overlay-bars/ViewerSettingsSheet.d.ts +6 -0
- package/dist/overlay-bars/ViewerSettingsSheet.d.ts.map +1 -0
- package/dist/overlay-bars/bottomBar/AudioControlsMini.d.ts +2 -0
- package/dist/overlay-bars/bottomBar/AudioControlsMini.d.ts.map +1 -0
- package/dist/overlay-bars/bottomBar/FakeAudioControlsMini.d.ts +3 -0
- package/dist/overlay-bars/bottomBar/FakeAudioControlsMini.d.ts.map +1 -0
- package/dist/overlay-bars/bottomBar/OverlayBottomBar.d.ts +5 -0
- package/dist/overlay-bars/bottomBar/OverlayBottomBar.d.ts.map +1 -0
- package/dist/overlay-bars/bottomBar/PlayButton.d.ts +13 -0
- package/dist/overlay-bars/bottomBar/PlayButton.d.ts.map +1 -0
- package/dist/overlay-bars/bottomBar/ProgressScrubber.d.ts +5 -0
- package/dist/overlay-bars/bottomBar/ProgressScrubber.d.ts.map +1 -0
- package/dist/overlay-bars/bottomBar/StepBtn.d.ts +6 -0
- package/dist/overlay-bars/bottomBar/StepBtn.d.ts.map +1 -0
- package/dist/overlay-bars/bottomBar/WPMSpeedButtons.d.ts +2 -0
- package/dist/overlay-bars/bottomBar/WPMSpeedButtons.d.ts.map +1 -0
- package/dist/overlay-bars/topBar/OverlayTopBar.d.ts +5 -0
- package/dist/overlay-bars/topBar/OverlayTopBar.d.ts.map +1 -0
- package/dist/playback/CR_ViewerPlayback.d.ts +27 -0
- package/dist/playback/CR_ViewerPlayback.d.ts.map +1 -0
- package/dist/playback/PlaybackBar.d.ts +28 -0
- package/dist/playback/PlaybackBar.d.ts.map +1 -0
- package/dist/playback/PlaybackToggleButton.d.ts +10 -0
- package/dist/playback/PlaybackToggleButton.d.ts.map +1 -0
- package/dist/playback/PlaybackViewport.d.ts +30 -0
- package/dist/playback/PlaybackViewport.d.ts.map +1 -0
- package/dist/playback/index.d.ts +5 -0
- package/dist/playback/index.d.ts.map +1 -0
- package/dist/playback/types.d.ts +20 -0
- package/dist/playback/types.d.ts.map +1 -0
- package/dist/recording/PlaybackHandler.d.ts +6 -0
- package/dist/recording/PlaybackHandler.d.ts.map +1 -0
- package/dist/recording/SettingsChangeEmitter.d.ts +3 -0
- package/dist/recording/SettingsChangeEmitter.d.ts.map +1 -0
- package/dist/recording/SnapshotRegistrar.d.ts +7 -0
- package/dist/recording/SnapshotRegistrar.d.ts.map +1 -0
- package/dist/recording/ViewportResizeEmitter.d.ts +7 -0
- package/dist/recording/ViewportResizeEmitter.d.ts.map +1 -0
- package/dist/stores/audio/crViewer_audio.context.d.ts +10 -0
- package/dist/stores/audio/crViewer_audio.context.d.ts.map +1 -0
- package/dist/stores/audio/crViewer_audio.hooks.d.ts +6 -0
- package/dist/stores/audio/crViewer_audio.hooks.d.ts.map +1 -0
- package/dist/stores/audio/crViewer_audio.provider.d.ts +14 -0
- package/dist/stores/audio/crViewer_audio.provider.d.ts.map +1 -0
- package/dist/stores/audio/crViewer_audio.store.d.ts +65 -0
- package/dist/stores/audio/crViewer_audio.store.d.ts.map +1 -0
- package/dist/stores/player/index.d.ts +5 -0
- package/dist/stores/player/index.d.ts.map +1 -0
- package/dist/stores/player/viewerPlayer.context.d.ts +7 -0
- package/dist/stores/player/viewerPlayer.context.d.ts.map +1 -0
- package/dist/stores/player/viewerPlayer.hooks.d.ts +13 -0
- package/dist/stores/player/viewerPlayer.hooks.d.ts.map +1 -0
- package/dist/stores/player/viewerPlayer.provider.d.ts +18 -0
- package/dist/stores/player/viewerPlayer.provider.d.ts.map +1 -0
- package/dist/stores/player/viewerPlayer.store.d.ts +52 -0
- package/dist/stores/player/viewerPlayer.store.d.ts.map +1 -0
- package/dist/stores/progress/crViewer_progress.context.d.ts +3 -0
- package/dist/stores/progress/crViewer_progress.context.d.ts.map +1 -0
- package/dist/stores/progress/crViewer_progress.hooks.d.ts +6 -0
- package/dist/stores/progress/crViewer_progress.hooks.d.ts.map +1 -0
- package/dist/stores/progress/crViewer_progress.provider.d.ts +15 -0
- package/dist/stores/progress/crViewer_progress.provider.d.ts.map +1 -0
- package/dist/stores/progress/crViewer_progress.store.d.ts +98 -0
- package/dist/stores/progress/crViewer_progress.store.d.ts.map +1 -0
- package/dist/stores/quizprogress/quiz_progress.context.d.ts +3 -0
- package/dist/stores/quizprogress/quiz_progress.context.d.ts.map +1 -0
- package/dist/stores/quizprogress/quiz_progress.hooks.d.ts +10 -0
- package/dist/stores/quizprogress/quiz_progress.hooks.d.ts.map +1 -0
- package/dist/stores/quizprogress/quiz_progress.provider.d.ts +17 -0
- package/dist/stores/quizprogress/quiz_progress.provider.d.ts.map +1 -0
- package/dist/stores/quizprogress/quiz_progress.store.d.ts +63 -0
- package/dist/stores/quizprogress/quiz_progress.store.d.ts.map +1 -0
- package/dist/stores/recorder/viewerRecorder.context.d.ts +7 -0
- package/dist/stores/recorder/viewerRecorder.context.d.ts.map +1 -0
- package/dist/stores/recorder/viewerRecorder.hooks.d.ts +13 -0
- package/dist/stores/recorder/viewerRecorder.hooks.d.ts.map +1 -0
- package/dist/stores/recorder/viewerRecorder.provider.d.ts +24 -0
- package/dist/stores/recorder/viewerRecorder.provider.d.ts.map +1 -0
- package/dist/stores/recorder/viewerRecorder.store.d.ts +50 -0
- package/dist/stores/recorder/viewerRecorder.store.d.ts.map +1 -0
- package/dist/stores/test/tempRecordingStore.d.ts +13 -0
- package/dist/stores/test/tempRecordingStore.d.ts.map +1 -0
- package/dist/stores/viewer/CRViewer.provider.d.ts +10 -0
- package/dist/stores/viewer/CRViewer.provider.d.ts.map +1 -0
- package/dist/stores/viewer/crViewer.context.d.ts +7 -0
- package/dist/stores/viewer/crViewer.context.d.ts.map +1 -0
- package/dist/stores/viewer/crViewer.hooks.d.ts +26 -0
- package/dist/stores/viewer/crViewer.hooks.d.ts.map +1 -0
- package/dist/stores/viewer/crViewer.store.d.ts +130 -0
- package/dist/stores/viewer/crViewer.store.d.ts.map +1 -0
- package/dist/types/viewerEvent.types.d.ts +149 -0
- package/dist/types/viewerEvent.types.d.ts.map +1 -0
- package/dist/utils/audioSrc.d.ts +4 -0
- package/dist/utils/audioSrc.d.ts.map +1 -0
- package/dist/utils/buildAudioTextMap.d.ts +15 -0
- package/dist/utils/buildAudioTextMap.d.ts.map +1 -0
- package/dist/utils/calcPage.util.d.ts +42 -0
- package/dist/utils/calcPage.util.d.ts.map +1 -0
- package/dist/utils/calcPage.util_BACKV3_2399_sf.d.ts +40 -0
- package/dist/utils/calcPage.util_BACKV3_2399_sf.d.ts.map +1 -0
- package/dist/utils/calcPage.util_BACKclaude.d.ts +40 -0
- package/dist/utils/calcPage.util_BACKclaude.d.ts.map +1 -0
- package/dist/utils/calcPage.util_BACKclaude_gptagain.d.ts +40 -0
- package/dist/utils/calcPage.util_BACKclaude_gptagain.d.ts.map +1 -0
- package/dist/utils/calcPage.util_BACKrecent.d.ts +40 -0
- package/dist/utils/calcPage.util_BACKrecent.d.ts.map +1 -0
- package/dist/utils/calcPage.util_BACKv6_fast_Sf.d.ts +40 -0
- package/dist/utils/calcPage.util_BACKv6_fast_Sf.d.ts.map +1 -0
- package/dist/utils/doubleRaf.d.ts +3 -0
- package/dist/utils/doubleRaf.d.ts.map +1 -0
- package/dist/utils/quizSrc.d.ts +3 -0
- package/dist/utils/quizSrc.d.ts.map +1 -0
- package/dist/utils/sectionRender.util.d.ts +21 -0
- package/dist/utils/sectionRender.util.d.ts.map +1 -0
- package/dist/utils/text.util.d.ts +3 -0
- package/dist/utils/text.util.d.ts.map +1 -0
- package/package.json +59 -0
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { StoreApi } from 'zustand/vanilla';
|
|
2
|
+
import { SectionData, SectionSummary, SectionId } from '@readerseye2/cr_type';
|
|
3
|
+
import { ViewerRecorderStore } from '../recorder/viewerRecorder.store';
|
|
4
|
+
/** 진행 상태를 갱신한 주체 */
|
|
5
|
+
export type UpdateSource = 'program' | 'scroll' | 'audio' | 'scrubber-live' | 'scrubber-commit' | 'scrubber-step' | 'playback';
|
|
6
|
+
export type SectionScrollApi = {
|
|
7
|
+
ensureVisibleGI: (gi: number) => Promise<boolean>;
|
|
8
|
+
scrollToGI: (gi: number) => Promise<boolean>;
|
|
9
|
+
getVisibleRange: () => {
|
|
10
|
+
first: number;
|
|
11
|
+
last: number;
|
|
12
|
+
} | null;
|
|
13
|
+
getScrollTop: () => number;
|
|
14
|
+
setScrollTop: (scrollTop: number) => void;
|
|
15
|
+
/** gi 요소가 뷰포트 상단에서 떨어진 비율 (0~1) */
|
|
16
|
+
getAnchorOffsetRatio: (gi: number) => number;
|
|
17
|
+
/** 정확한 위치로 스크롤 (gi를 뷰포트의 특정 비율 위치에 배치) */
|
|
18
|
+
scrollToGIAtOffset: (gi: number, offsetRatio: number) => Promise<void>;
|
|
19
|
+
/** 페이지 모드 전용: 페이지 단위 이동 (-1: 이전, +1: 다음) */
|
|
20
|
+
stepPage?: (dir: -1 | 1) => void;
|
|
21
|
+
};
|
|
22
|
+
export type FlatGroup = {
|
|
23
|
+
startG: number;
|
|
24
|
+
endG: number;
|
|
25
|
+
r0: number;
|
|
26
|
+
len: number;
|
|
27
|
+
firstReadableGI: number;
|
|
28
|
+
splitIndex?: number | null;
|
|
29
|
+
};
|
|
30
|
+
export type DerivedNav = {
|
|
31
|
+
groups: FlatGroup[];
|
|
32
|
+
giToGroupIdx: Int32Array;
|
|
33
|
+
readableGi: Uint8Array;
|
|
34
|
+
splitGroupsPerBlock: (FlatGroup[] | null)[];
|
|
35
|
+
};
|
|
36
|
+
export type DerivedLayout = {
|
|
37
|
+
prefix: number[];
|
|
38
|
+
totalRuns: number;
|
|
39
|
+
};
|
|
40
|
+
export type SectionProgress = {
|
|
41
|
+
/** 현재 섹션 전체 데이터 (AST 포함) */
|
|
42
|
+
section: SectionData;
|
|
43
|
+
/** 섹션 리스트 (이전/다음 섹션 이동용 메타) */
|
|
44
|
+
sectionList?: SectionSummary[];
|
|
45
|
+
/** 섹션 변경 함수 (이벤트 emit 포함) */
|
|
46
|
+
onSectionChange?: (nextId: SectionId) => void;
|
|
47
|
+
/** 원본 섹션 변경 콜백 (내부용) */
|
|
48
|
+
_onSectionChangeCallback?: (nextId: SectionId) => void;
|
|
49
|
+
/** 섹션 식별자 */
|
|
50
|
+
sectionId: string;
|
|
51
|
+
/** 현재 마크(전역 run 인덱스). 없으면 -1 */
|
|
52
|
+
currentGlobalRunIndex: number;
|
|
53
|
+
/** 마지막 갱신 주체 */
|
|
54
|
+
lastUpdateBy: UpdateSource;
|
|
55
|
+
/** 섹션 전체 전역 runs 수 */
|
|
56
|
+
totalRuns: number;
|
|
57
|
+
/** 파생 레이아웃/네비 데이터 */
|
|
58
|
+
derivedNav?: DerivedNav;
|
|
59
|
+
layout?: DerivedLayout;
|
|
60
|
+
/** 섹션 로딩 상태 */
|
|
61
|
+
sectionLoading: boolean;
|
|
62
|
+
/** 로딩 시작 시간 (duration 계산용, 내부용) */
|
|
63
|
+
_loadingStartTime: number | null;
|
|
64
|
+
/** 섹션 스크롤 API(등록/조회) */
|
|
65
|
+
_scrollApi?: SectionScrollApi;
|
|
66
|
+
registerSectionScrollApi: (api: SectionScrollApi | undefined) => void;
|
|
67
|
+
getSectionScrollApi: () => SectionScrollApi | undefined;
|
|
68
|
+
/** actions */
|
|
69
|
+
setTotalRuns: (n: number) => void;
|
|
70
|
+
setCurrentGlobalRunIndex: (globalIdx: number, by?: UpdateSource) => void;
|
|
71
|
+
/** 부팅 제어 */
|
|
72
|
+
setSectionLoading: (l: boolean) => void;
|
|
73
|
+
snapToReadable: (gi: number) => number;
|
|
74
|
+
nextReadableFrom: (gi: number, dir: -1 | 1) => number | null;
|
|
75
|
+
edgeReadable: (dir: -1 | 1) => number | null;
|
|
76
|
+
hasReadableInDir: (gi: number, dir: -1 | 1) => boolean;
|
|
77
|
+
computeStepTarget: (gi: number, dir: -1 | 1) => number;
|
|
78
|
+
giToPercentTotal: (gi: number) => number;
|
|
79
|
+
percentToGITotal: (pct: number) => number;
|
|
80
|
+
};
|
|
81
|
+
export type CRViewerProgressState = {
|
|
82
|
+
/** 단일 섹션 전용 진행 상태 */
|
|
83
|
+
progress: SectionProgress;
|
|
84
|
+
};
|
|
85
|
+
export type CRViewerProgressStore = StoreApi<CRViewerProgressState>;
|
|
86
|
+
/** Provider에서 사용하는 초기 상태 타입과 구조적으로 동일해야 함 */
|
|
87
|
+
export type CRViewerProgressInitialState = {
|
|
88
|
+
/** 섹션 식별자(옵션). 바뀌면 switchSection 트리거에만 사용 */
|
|
89
|
+
section: SectionData;
|
|
90
|
+
/** 초기 GI. 명시 안 하면 totalRuns>0일 때 0, 아니면 -1 */
|
|
91
|
+
initialIndex?: number;
|
|
92
|
+
sectionList?: SectionSummary[];
|
|
93
|
+
onSectionChange?: (nextId: SectionId) => void;
|
|
94
|
+
/** 뷰어 레코더 스토어 (이벤트 emit용) */
|
|
95
|
+
recorderStore?: ViewerRecorderStore;
|
|
96
|
+
};
|
|
97
|
+
export declare function createCRViewerProgressStore(init: CRViewerProgressInitialState): CRViewerProgressStore;
|
|
98
|
+
//# sourceMappingURL=crViewer_progress.store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crViewer_progress.store.d.ts","sourceRoot":"","sources":["../../../src/stores/progress/crViewer_progress.store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"quiz_progress.context.d.ts","sourceRoot":"","sources":["../../../src/stores/quizprogress/quiz_progress.context.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAE/D,eAAO,MAAM,mBAAmB,mDAAgD,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { QuizProgressStore, StoreSnapshot } from './quiz_progress.store';
|
|
2
|
+
/** 구독 없는 StoreApi 접근 (imperative) */
|
|
3
|
+
export declare function useQuizStoreApi(): QuizProgressStore;
|
|
4
|
+
/**
|
|
5
|
+
* 타입 세이프 셀렉터 훅 (any 전파 방지)
|
|
6
|
+
* - 예: const phase = useQuizStore(s => s.phase)
|
|
7
|
+
* - equalityFn 미지정 시 shallow 사용
|
|
8
|
+
*/
|
|
9
|
+
export declare function useQuizStore<T>(selector: (s: StoreSnapshot) => T, equalityFn?: (a: T, b: T) => boolean): T;
|
|
10
|
+
//# sourceMappingURL=quiz_progress.hooks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"quiz_progress.hooks.d.ts","sourceRoot":"","sources":["../../../src/stores/quizprogress/quiz_progress.hooks.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAE9E,qCAAqC;AACrC,wBAAgB,eAAe,IAAI,iBAAiB,CAMnD;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAC5B,QAAQ,EAAE,CAAC,CAAC,EAAE,aAAa,KAAK,CAAC,EACjC,UAAU,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,OAAO,GACnC,CAAC,CAMH"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { PropsWithChildren } from 'react';
|
|
2
|
+
import { SectionData } from '@readerseye2/cr_type';
|
|
3
|
+
type Props = PropsWithChildren<{
|
|
4
|
+
/** 초기에 특정 섹션을 미리 적재하고 싶을 때 */
|
|
5
|
+
initialState: {
|
|
6
|
+
section: SectionData;
|
|
7
|
+
};
|
|
8
|
+
}>;
|
|
9
|
+
/**
|
|
10
|
+
* CR-Viewer 내부에서 퀴즈 진행 스토어를 공급하는 Provider
|
|
11
|
+
* - 최초 마운트 시 store 생성 (vanilla Zustand)
|
|
12
|
+
* - initialState.section이 바뀌면 해당 섹션 퀴즈 배열만 미리 적재
|
|
13
|
+
* - phase(doing/finished)는 유지
|
|
14
|
+
*/
|
|
15
|
+
export default function QuizProgressProvider({ children, initialState }: Props): import("react/jsx-runtime").JSX.Element;
|
|
16
|
+
export {};
|
|
17
|
+
//# sourceMappingURL=quiz_progress.provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"quiz_progress.provider.d.ts","sourceRoot":"","sources":["../../../src/stores/quizprogress/quiz_progress.provider.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,iBAAiB,EAA8B,MAAM,OAAO,CAAC;AAG3E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAExD,KAAK,KAAK,GAAG,iBAAiB,CAAC;IAC7B,8BAA8B;IAC9B,YAAY,EAAE;QAAE,OAAO,EAAE,WAAW,CAAA;KAAE,CAAC;CACxC,CAAC,CAAC;AAEH;;;;;GAKG;AACH,MAAM,CAAC,OAAO,UAAU,oBAAoB,CAAC,EAAE,QAAQ,EAAE,YAAY,EAAE,EAAE,KAAK,2CAgB7E"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { StoreApi } from 'zustand/vanilla';
|
|
2
|
+
import { SectionData, SectionQuiz } from '@readerseye2/cr_type';
|
|
3
|
+
export type UserAnswer = number[];
|
|
4
|
+
type Phase = 'idle' | 'doing' | 'finished';
|
|
5
|
+
export type PerQuestionResult = {
|
|
6
|
+
qid: string;
|
|
7
|
+
index: number;
|
|
8
|
+
question?: string;
|
|
9
|
+
score: number;
|
|
10
|
+
multi: boolean;
|
|
11
|
+
selected: number[];
|
|
12
|
+
correctIdxes: number[];
|
|
13
|
+
isCorrect: boolean;
|
|
14
|
+
ms: number;
|
|
15
|
+
revealed: boolean;
|
|
16
|
+
timedOut: boolean;
|
|
17
|
+
};
|
|
18
|
+
export type QuizProgressState = {
|
|
19
|
+
phase: Phase;
|
|
20
|
+
sectionId?: string;
|
|
21
|
+
quizzes: SectionQuiz[];
|
|
22
|
+
order: number[];
|
|
23
|
+
currentIndex: number;
|
|
24
|
+
answers: Record<string, UserAnswer>;
|
|
25
|
+
correctCount: number;
|
|
26
|
+
startedAt?: number;
|
|
27
|
+
finishedAt?: number;
|
|
28
|
+
questionStartedAt?: number;
|
|
29
|
+
remainingSec?: number;
|
|
30
|
+
uiReveal: boolean;
|
|
31
|
+
perQ: Record<string, PerQuestionResult>;
|
|
32
|
+
};
|
|
33
|
+
export type QuizProgressActions = {
|
|
34
|
+
/** 섹션이 바뀔 때(또는 초기 마운트 시) 퀴즈 배열만 미리 적재 */
|
|
35
|
+
hydrateFromSection: (section?: SectionData) => void;
|
|
36
|
+
/** 퀴즈 진행 시작 (section을 안 주면, hydrate된 상태를 사용) */
|
|
37
|
+
openFromSection: (section?: SectionData) => void;
|
|
38
|
+
close: () => void;
|
|
39
|
+
selectToggle: (optIndex: number) => void;
|
|
40
|
+
selectSingle: (optIndex: number) => void;
|
|
41
|
+
/** 현재 문항을 채점하고 다음으로 이동(마지막이면 finish) */
|
|
42
|
+
submitCurrent: () => void;
|
|
43
|
+
/** 공개 단계 트리거 */
|
|
44
|
+
setReveal: (v: boolean) => void;
|
|
45
|
+
/** 공개 이후 실제 다음으로(=submitCurrent 래핑) */
|
|
46
|
+
afterRevealNext: () => void;
|
|
47
|
+
next: () => void;
|
|
48
|
+
prev: () => void;
|
|
49
|
+
finish: () => void;
|
|
50
|
+
/** 타이머 tick: 0이 되면 공개만 켬(자동 제출 X) */
|
|
51
|
+
tick: () => void;
|
|
52
|
+
};
|
|
53
|
+
export type StoreSnapshot = QuizProgressState & QuizProgressActions;
|
|
54
|
+
/** zustand가 요구하는 표준 Store 타입 */
|
|
55
|
+
export type QuizProgressStore = StoreApi<StoreSnapshot>;
|
|
56
|
+
/**
|
|
57
|
+
* 초기 섹션을 인자로 받아, 스토어 생성 시점에 즉시 hydrate합니다.
|
|
58
|
+
* - phase는 'idle'로 시작
|
|
59
|
+
* - open은 명시적으로 호출해야 'doing'으로 전환
|
|
60
|
+
*/
|
|
61
|
+
export declare function createQuizProgressVanillaStore(initialSection?: SectionData): QuizProgressStore;
|
|
62
|
+
export {};
|
|
63
|
+
//# sourceMappingURL=quiz_progress.store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"quiz_progress.store.d.ts","sourceRoot":"","sources":["../../../src/stores/quizprogress/quiz_progress.store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,KAAK,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAC7D,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAMrE,MAAM,MAAM,UAAU,GAAG,MAAM,EAAE,CAAC;AAClC,KAAK,KAAK,GAAG,MAAM,GAAG,OAAO,GAAG,UAAU,CAAC;AAE3C,MAAM,MAAM,iBAAiB,GAAG;IAC9B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IAEd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,OAAO,CAAC;IACf,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,SAAS,EAAE,OAAO,CAAC;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,OAAO,CAAC;IAClB,QAAQ,EAAE,OAAO,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,KAAK,EAAE,KAAK,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IACpC,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,OAAO,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;CACzC,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,yCAAyC;IACzC,kBAAkB,EAAE,CAAC,OAAO,CAAC,EAAE,WAAW,KAAK,IAAI,CAAC;IACpD,gDAAgD;IAChD,eAAe,EAAE,CAAC,OAAO,CAAC,EAAE,WAAW,KAAK,IAAI,CAAC;IACjD,KAAK,EAAE,MAAM,IAAI,CAAC;IAElB,YAAY,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IACzC,YAAY,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IAEzC,wCAAwC;IACxC,aAAa,EAAE,MAAM,IAAI,CAAC;IAE1B,gBAAgB;IAChB,SAAS,EAAE,CAAC,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;IAEhC,uCAAuC;IACvC,eAAe,EAAE,MAAM,IAAI,CAAC;IAE5B,IAAI,EAAE,MAAM,IAAI,CAAC;IACjB,IAAI,EAAE,MAAM,IAAI,CAAC;IACjB,MAAM,EAAE,MAAM,IAAI,CAAC;IAEnB,qCAAqC;IACrC,IAAI,EAAE,MAAM,IAAI,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG,iBAAiB,GAAG,mBAAmB,CAAC;AAEpE,gCAAgC;AAChC,MAAM,MAAM,iBAAiB,GAAG,QAAQ,CAAC,aAAa,CAAC,CAAC;AAmDxD;;;;GAIG;AACH,wBAAgB,8BAA8B,CAAC,cAAc,CAAC,EAAE,WAAW,GAAG,iBAAiB,CA8O9F"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { ViewerRecorderStore } from './viewerRecorder.store';
|
|
2
|
+
/**
|
|
3
|
+
* ViewerRecorder 전용 컨텍스트.
|
|
4
|
+
* 값은 zustand의 StoreApi 인스턴스입니다.
|
|
5
|
+
*/
|
|
6
|
+
export declare const ViewerRecorderContext: import('react').Context<ViewerRecorderStore | undefined>;
|
|
7
|
+
//# sourceMappingURL=viewerRecorder.context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"viewerRecorder.context.d.ts","sourceRoot":"","sources":["../../../src/stores/recorder/viewerRecorder.context.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAElE;;;GAGG;AACH,eAAO,MAAM,qBAAqB,0DAA4D,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { StoreApi } from 'zustand';
|
|
2
|
+
import { ViewerRecorderState, ViewerRecorderActions } from './viewerRecorder.store';
|
|
3
|
+
/**
|
|
4
|
+
* 구독 기반 selector 훅.
|
|
5
|
+
* 상태 변화에 반응해야 할 컴포넌트에서 사용하세요.
|
|
6
|
+
*/
|
|
7
|
+
export declare function useViewerRecorderStore<T>(selector: (s: ViewerRecorderState & ViewerRecorderActions) => T, equalityFn?: (a: T, b: T) => boolean): T;
|
|
8
|
+
/**
|
|
9
|
+
* 구독 없는 store API 훅.
|
|
10
|
+
* 이벤트 시점에 상태를 읽거나 변경할 때 사용.
|
|
11
|
+
*/
|
|
12
|
+
export declare function useViewerRecorderStoreApi(): StoreApi<ViewerRecorderState & ViewerRecorderActions>;
|
|
13
|
+
//# sourceMappingURL=viewerRecorder.hooks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"viewerRecorder.hooks.d.ts","sourceRoot":"","sources":["../../../src/stores/recorder/viewerRecorder.hooks.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAGxC,OAAO,KAAK,EACV,mBAAmB,EACnB,qBAAqB,EAEtB,MAAM,wBAAwB,CAAC;AAEhC;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,CAAC,EACtC,QAAQ,EAAE,CAAC,CAAC,EAAE,mBAAmB,GAAG,qBAAqB,KAAK,CAAC,EAC/D,UAAU,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,OAAO,GACnC,CAAC,CAMH;AAED;;;GAGG;AACH,wBAAgB,yBAAyB,IAAI,QAAQ,CAAC,mBAAmB,GAAG,qBAAqB,CAAC,CAMjG"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { ViewerEventCallback, StoredEvent, RecordingSnapshot } from '../../types/viewerEvent.types';
|
|
2
|
+
/** CR_Viewer 외부 제어용 핸들 */
|
|
3
|
+
export type CRViewerHandle = {
|
|
4
|
+
dispatch: (event: StoredEvent) => void;
|
|
5
|
+
applySnapshot: (snapshot: RecordingSnapshot) => void;
|
|
6
|
+
};
|
|
7
|
+
type ViewerRecorderProviderProps = {
|
|
8
|
+
children: React.ReactNode;
|
|
9
|
+
/** 뷰어 이벤트 콜백 (외부에서 이벤트 수집) */
|
|
10
|
+
onViewerEvent?: ViewerEventCallback;
|
|
11
|
+
/** 재생 모드 여부 */
|
|
12
|
+
isPlaybackMode?: boolean;
|
|
13
|
+
/** 재생 모드에서 적용된 scale (페이지네이션 측정 보정용) */
|
|
14
|
+
playbackScale?: number;
|
|
15
|
+
/** 외부 제어용 ref */
|
|
16
|
+
viewerRef?: React.MutableRefObject<CRViewerHandle | null>;
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Provider: 뷰어 인스턴스별로 독립적인 recorder store를 생성해 제공합니다.
|
|
20
|
+
* CR_Viewer의 가장 바깥쪽에 위치해야 합니다.
|
|
21
|
+
*/
|
|
22
|
+
export declare function ViewerRecorderProvider({ children, onViewerEvent, isPlaybackMode, playbackScale, viewerRef, }: ViewerRecorderProviderProps): import("react/jsx-runtime").JSX.Element;
|
|
23
|
+
export {};
|
|
24
|
+
//# sourceMappingURL=viewerRecorder.provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"viewerRecorder.provider.d.ts","sourceRoot":"","sources":["../../../src/stores/recorder/viewerRecorder.provider.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,mBAAmB,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAEzG,0BAA0B;AAC1B,MAAM,MAAM,cAAc,GAAG;IAC3B,QAAQ,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,CAAC;IACvC,aAAa,EAAE,CAAC,QAAQ,EAAE,iBAAiB,KAAK,IAAI,CAAC;CACtD,CAAC;AAEF,KAAK,2BAA2B,GAAG;IACjC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,8BAA8B;IAC9B,aAAa,CAAC,EAAE,mBAAmB,CAAC;IACpC,eAAe;IACf,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,wCAAwC;IACxC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,iBAAiB;IACjB,SAAS,CAAC,EAAE,KAAK,CAAC,gBAAgB,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;CAC3D,CAAC;AAEF;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,EACrC,QAAQ,EACR,aAAa,EACb,cAAsB,EACtB,aAAiB,EACjB,SAAS,GACV,EAAE,2BAA2B,2CA6C7B"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { StoreApi } from 'zustand/vanilla';
|
|
2
|
+
import { ViewerEvent, ViewerEventCallback, ViewerEventType, StoredEvent, RecordingSnapshot } from '../../types/viewerEvent.types';
|
|
3
|
+
type EmitParams<T extends ViewerEventType> = Extract<ViewerEvent, {
|
|
4
|
+
type: T;
|
|
5
|
+
}> extends {
|
|
6
|
+
payload: infer P;
|
|
7
|
+
} ? {
|
|
8
|
+
type: T;
|
|
9
|
+
payload: P;
|
|
10
|
+
} : {
|
|
11
|
+
type: T;
|
|
12
|
+
};
|
|
13
|
+
/** dispatch 핸들러 타입 (PlaybackHandler에서 등록) */
|
|
14
|
+
export type DispatchHandler = (event: StoredEvent) => void;
|
|
15
|
+
/** applySnapshot 핸들러 타입 (PlaybackHandler에서 등록) */
|
|
16
|
+
export type ApplySnapshotHandler = (snapshot: RecordingSnapshot) => void;
|
|
17
|
+
export type ViewerRecorderState = {
|
|
18
|
+
/** 외부에서 등록한 이벤트 콜백 */
|
|
19
|
+
emitCallback: ViewerEventCallback | null;
|
|
20
|
+
/** 재생 모드 여부 */
|
|
21
|
+
isPlaybackMode: boolean;
|
|
22
|
+
/** 재생 모드에서 적용된 scale (페이지네이션 측정 보정용) */
|
|
23
|
+
playbackScale: number;
|
|
24
|
+
/** dispatch 핸들러 (PlaybackHandler에서 등록) */
|
|
25
|
+
dispatchHandler: DispatchHandler | null;
|
|
26
|
+
/** applySnapshot 핸들러 (PlaybackHandler에서 등록) */
|
|
27
|
+
applySnapshotHandler: ApplySnapshotHandler | null;
|
|
28
|
+
};
|
|
29
|
+
export type ViewerRecorderActions = {
|
|
30
|
+
/** 콜백 등록 (외부에서 호출) */
|
|
31
|
+
setEmitCallback: (cb: ViewerEventCallback | null) => void;
|
|
32
|
+
/** 이벤트 발생 (내부 컴포넌트에서 호출) - timestamp 직접 전달 가능 */
|
|
33
|
+
emit: <T extends ViewerEventType>(params: EmitParams<T>, timestamp?: number) => void;
|
|
34
|
+
/** 재생 모드 설정 */
|
|
35
|
+
setPlaybackMode: (mode: boolean) => void;
|
|
36
|
+
/** 재생 모드 scale 설정 */
|
|
37
|
+
setPlaybackScale: (scale: number) => void;
|
|
38
|
+
/** dispatch 핸들러 등록 (PlaybackHandler에서 호출) */
|
|
39
|
+
setDispatchHandler: (handler: DispatchHandler | null) => void;
|
|
40
|
+
/** 외부에서 이벤트를 받아 뷰어 상태 변경 (재생 시 사용) */
|
|
41
|
+
dispatch: (event: StoredEvent) => void;
|
|
42
|
+
/** applySnapshot 핸들러 등록 (PlaybackHandler에서 호출) */
|
|
43
|
+
setApplySnapshotHandler: (handler: ApplySnapshotHandler | null) => void;
|
|
44
|
+
/** 스냅샷 적용 (재생 시작 시 초기 상태 복원) */
|
|
45
|
+
applySnapshot: (snapshot: RecordingSnapshot) => void;
|
|
46
|
+
};
|
|
47
|
+
export type ViewerRecorderStore = StoreApi<ViewerRecorderState & ViewerRecorderActions>;
|
|
48
|
+
export declare function createViewerRecorderStore(): ViewerRecorderStore;
|
|
49
|
+
export {};
|
|
50
|
+
//# sourceMappingURL=viewerRecorder.store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"viewerRecorder.store.d.ts","sourceRoot":"","sources":["../../../src/stores/recorder/viewerRecorder.store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,KAAK,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAC7D,OAAO,KAAK,EACV,WAAW,EACX,mBAAmB,EACnB,eAAe,EACf,WAAW,EACX,iBAAiB,EAClB,MAAM,+BAA+B,CAAC;AAEvC,KAAK,UAAU,CAAC,CAAC,SAAS,eAAe,IAAI,OAAO,CAAC,WAAW,EAAE;IAAE,IAAI,EAAE,CAAC,CAAA;CAAE,CAAC,SAAS;IAAE,OAAO,EAAE,MAAM,CAAC,CAAA;CAAE,GACvG;IAAE,IAAI,EAAE,CAAC,CAAC;IAAC,OAAO,EAAE,CAAC,CAAA;CAAE,GACvB;IAAE,IAAI,EAAE,CAAC,CAAA;CAAE,CAAC;AAEhB,6CAA6C;AAC7C,MAAM,MAAM,eAAe,GAAG,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,CAAC;AAE3D,kDAAkD;AAClD,MAAM,MAAM,oBAAoB,GAAG,CAAC,QAAQ,EAAE,iBAAiB,KAAK,IAAI,CAAC;AAEzE,MAAM,MAAM,mBAAmB,GAAG;IAChC,sBAAsB;IACtB,YAAY,EAAE,mBAAmB,GAAG,IAAI,CAAC;IACzC,eAAe;IACf,cAAc,EAAE,OAAO,CAAC;IACxB,wCAAwC;IACxC,aAAa,EAAE,MAAM,CAAC;IACtB,0CAA0C;IAC1C,eAAe,EAAE,eAAe,GAAG,IAAI,CAAC;IACxC,+CAA+C;IAC/C,oBAAoB,EAAE,oBAAoB,GAAG,IAAI,CAAC;CACnD,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAClC,sBAAsB;IACtB,eAAe,EAAE,CAAC,EAAE,EAAE,mBAAmB,GAAG,IAAI,KAAK,IAAI,CAAC;IAC1D,iDAAiD;IACjD,IAAI,EAAE,CAAC,CAAC,SAAS,eAAe,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IACrF,eAAe;IACf,eAAe,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACzC,qBAAqB;IACrB,gBAAgB,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1C,6CAA6C;IAC7C,kBAAkB,EAAE,CAAC,OAAO,EAAE,eAAe,GAAG,IAAI,KAAK,IAAI,CAAC;IAC9D,sCAAsC;IACtC,QAAQ,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,CAAC;IACvC,kDAAkD;IAClD,uBAAuB,EAAE,CAAC,OAAO,EAAE,oBAAoB,GAAG,IAAI,KAAK,IAAI,CAAC;IACxE,gCAAgC;IAChC,aAAa,EAAE,CAAC,QAAQ,EAAE,iBAAiB,KAAK,IAAI,CAAC;CACtD,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG,QAAQ,CAAC,mBAAmB,GAAG,qBAAqB,CAAC,CAAC;AAExF,wBAAgB,yBAAyB,IAAI,mBAAmB,CA0D/D"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { RecordingSnapshot } from '../../types/viewerEvent.types';
|
|
2
|
+
/**
|
|
3
|
+
* Stub recording store for CR_viewer library.
|
|
4
|
+
* CR_creator uses its own full implementation.
|
|
5
|
+
*/
|
|
6
|
+
type RecordingState = {
|
|
7
|
+
_snapshotGetter: (() => RecordingSnapshot) | null;
|
|
8
|
+
registerSnapshotGetter: (getter: () => RecordingSnapshot) => void;
|
|
9
|
+
unregisterSnapshotGetter: () => void;
|
|
10
|
+
};
|
|
11
|
+
export declare const useTempRecordingStore: import('zustand').UseBoundStore<import('zustand').StoreApi<RecordingState>>;
|
|
12
|
+
export {};
|
|
13
|
+
//# sourceMappingURL=tempRecordingStore.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tempRecordingStore.d.ts","sourceRoot":"","sources":["../../../src/stores/test/tempRecordingStore.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAEnE;;;GAGG;AACH,KAAK,cAAc,GAAG;IACpB,eAAe,EAAE,CAAC,MAAM,iBAAiB,CAAC,GAAG,IAAI,CAAC;IAClD,sBAAsB,EAAE,CAAC,MAAM,EAAE,MAAM,iBAAiB,KAAK,IAAI,CAAC;IAClE,wBAAwB,EAAE,MAAM,IAAI,CAAC;CACtC,CAAC;AAEF,eAAO,MAAM,qBAAqB,6EAU/B,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { CRViewerState } from './crViewer.store';
|
|
2
|
+
/**
|
|
3
|
+
* Provider: 뷰어 인스턴스별로 독립적인 store를 1회 생성해 제공합니다.
|
|
4
|
+
* initialState는 최초 마운트 시에만 적용됩니다.
|
|
5
|
+
*/
|
|
6
|
+
export declare function InternalCRViewerProvider({ children, initialState, }: {
|
|
7
|
+
children: React.ReactNode;
|
|
8
|
+
initialState?: Partial<CRViewerState>;
|
|
9
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
10
|
+
//# sourceMappingURL=CRViewer.provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CRViewer.provider.d.ts","sourceRoot":"","sources":["../../../src/stores/viewer/CRViewer.provider.tsx"],"names":[],"mappings":"AAEA,OAAO,EAEL,KAAK,aAAa,EACnB,MAAM,gCAAgC,CAAC;AAGxC;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,EACvC,QAAQ,EACR,YAAY,GACb,EAAE;IACD,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,YAAY,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,CAAC;CACvC,2CAQA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crViewer.context.d.ts","sourceRoot":"","sources":["../../../src/stores/viewer/crViewer.context.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEtD;;;GAGG;AACH,eAAO,MAAM,eAAe,oDAAsD,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { CRViewerActions, CRViewerState, CRViewerStore } from './crViewer.store';
|
|
2
|
+
import { StoreApi } from 'zustand';
|
|
3
|
+
/**
|
|
4
|
+
* 구독 기반 selector 훅.
|
|
5
|
+
* - equalityFn을 넘기면 useStoreWithEqualityFn 사용
|
|
6
|
+
* - 넘기지 않으면 기본 useStore
|
|
7
|
+
*
|
|
8
|
+
* 본문 렌더 등 "상태 변화에 반응"해야 할 컴포넌트에서 사용하세요.
|
|
9
|
+
*/
|
|
10
|
+
export declare function useCRViewerScopedStore<T>(selector: (s: CRViewerState & CRViewerActions) => T, equalityFn?: (a: T, b: T) => boolean): T;
|
|
11
|
+
/**
|
|
12
|
+
* ⚡ 구독 없는 store API 훅.
|
|
13
|
+
* - getState/setState/subscribe 등 StoreApi에 접근
|
|
14
|
+
* - 컴포넌트 리렌더를 유발하지 않으면서 "이벤트 시점"에 상태를 읽거나 변경할 때 사용
|
|
15
|
+
*
|
|
16
|
+
* 예) 클릭 핸들러에서:
|
|
17
|
+
* const storeApi = useCRViewerStoreApi();
|
|
18
|
+
* const { isSettingsOpen, setSettingsOpen, toggleOverlays } = storeApi.getState();
|
|
19
|
+
*/
|
|
20
|
+
export declare function useCRViewerStoreApi(): StoreApi<CRViewerState & CRViewerActions>;
|
|
21
|
+
/**
|
|
22
|
+
* (선택) 컨텍스트 자체가 필요한 경우를 위한 getter.
|
|
23
|
+
* 가급적 훅(useCRViewerStoreApi/useCRViewerScopedStore)을 사용하세요.
|
|
24
|
+
*/
|
|
25
|
+
export declare function useCRViewerContextUnsafe(): CRViewerStore;
|
|
26
|
+
//# sourceMappingURL=crViewer.hooks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crViewer.hooks.d.ts","sourceRoot":"","sources":["../../../src/stores/viewer/crViewer.hooks.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,eAAe,EACf,aAAa,EACb,aAAa,EACd,MAAM,gCAAgC,CAAC;AAExC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAExC;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,CAAC,EACtC,QAAQ,EAAE,CAAC,CAAC,EAAE,aAAa,GAAG,eAAe,KAAK,CAAC,EACnD,UAAU,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,OAAO,GACnC,CAAC,CAWH;AAED;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,IAAI,QAAQ,CAAC,aAAa,GAAG,eAAe,CAAC,CAM/E;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,IAAI,aAAa,CAMxD"}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { StoreApi } from 'zustand/vanilla';
|
|
2
|
+
import { ViewerRecorderStore } from '../recorder/viewerRecorder.store';
|
|
3
|
+
export type ViewerMode = 'scroll' | 'page';
|
|
4
|
+
export declare const THEME_PALETTES: {
|
|
5
|
+
light: {
|
|
6
|
+
bg: string;
|
|
7
|
+
fg: string;
|
|
8
|
+
overlayBg: string;
|
|
9
|
+
overlayFg: string;
|
|
10
|
+
borderColor: string;
|
|
11
|
+
};
|
|
12
|
+
dark: {
|
|
13
|
+
bg: string;
|
|
14
|
+
fg: string;
|
|
15
|
+
overlayBg: string;
|
|
16
|
+
overlayFg: string;
|
|
17
|
+
borderColor: string;
|
|
18
|
+
};
|
|
19
|
+
sepia: {
|
|
20
|
+
bg: string;
|
|
21
|
+
fg: string;
|
|
22
|
+
overlayBg: string;
|
|
23
|
+
overlayFg: string;
|
|
24
|
+
borderColor: string;
|
|
25
|
+
};
|
|
26
|
+
green: {
|
|
27
|
+
bg: string;
|
|
28
|
+
fg: string;
|
|
29
|
+
overlayBg: string;
|
|
30
|
+
overlayFg: string;
|
|
31
|
+
borderColor: string;
|
|
32
|
+
};
|
|
33
|
+
};
|
|
34
|
+
export type ViewerTheme = keyof typeof THEME_PALETTES;
|
|
35
|
+
export type OverlayPalette = (typeof THEME_PALETTES)[ViewerTheme];
|
|
36
|
+
export type PointerStyle = 'highlight' | 'underline';
|
|
37
|
+
export type BreakMarkKind = 'slash';
|
|
38
|
+
export type CRViewerState = {
|
|
39
|
+
mode: ViewerMode;
|
|
40
|
+
theme: ViewerTheme;
|
|
41
|
+
fontFamily: string;
|
|
42
|
+
fontSizePx: number;
|
|
43
|
+
lineHeight: number;
|
|
44
|
+
marginX: number;
|
|
45
|
+
marginY: number;
|
|
46
|
+
showOverlays: boolean;
|
|
47
|
+
/** ✅ 설정 시트 오픈 여부 */
|
|
48
|
+
isSettingsOpen: boolean;
|
|
49
|
+
pointerStyle: PointerStyle;
|
|
50
|
+
pointerColor: string;
|
|
51
|
+
breakMarks: {
|
|
52
|
+
slash: boolean;
|
|
53
|
+
};
|
|
54
|
+
breakGapPx: number;
|
|
55
|
+
/** 🔇 오디오 기본 음소거 */
|
|
56
|
+
muteAudio: boolean;
|
|
57
|
+
audioTargetWpm: number;
|
|
58
|
+
audioSpeed: number;
|
|
59
|
+
/** 🖊️ 포인터(형광펜/밑줄/커스텀) 표시 여부 */
|
|
60
|
+
showPointer: boolean;
|
|
61
|
+
/** 🪓 끊기표시(간격/슬래쉬) 표시 여부 */
|
|
62
|
+
showSplit: boolean;
|
|
63
|
+
/** 📐 뷰포트 크기 (이미지 maxHeight 계산 등에 사용) */
|
|
64
|
+
viewportWidth: number;
|
|
65
|
+
viewportHeight: number;
|
|
66
|
+
/** 📐 재생용 뷰포트 크기 (녹화 당시 viewport, 재생 시 recalc/이미지 높이에 사용) */
|
|
67
|
+
playbackViewportWidth: number;
|
|
68
|
+
playbackViewportHeight: number;
|
|
69
|
+
};
|
|
70
|
+
export type CRViewerActions = {
|
|
71
|
+
setMode: (m: ViewerMode) => void;
|
|
72
|
+
setTheme: (t: ViewerTheme) => void;
|
|
73
|
+
setFontFamily: (ff: string) => void;
|
|
74
|
+
setFontSizePx: (px: number) => void;
|
|
75
|
+
setLineHeight: (lh: number) => void;
|
|
76
|
+
setMarginX: (mx: number) => void;
|
|
77
|
+
setMarginY: (my: number) => void;
|
|
78
|
+
setShowOverlays: (v: boolean) => void;
|
|
79
|
+
toggleOverlays: () => void;
|
|
80
|
+
/** ✅ 바텀 시트 토글 */
|
|
81
|
+
setSettingsOpen: (open: boolean) => void;
|
|
82
|
+
/** ✅ 보기 설정 초기화 */
|
|
83
|
+
resetToDefaults: () => void;
|
|
84
|
+
maps: {
|
|
85
|
+
MARGIN_MAP: readonly number[];
|
|
86
|
+
LINEHEIGHT_MAP: readonly number[];
|
|
87
|
+
BREAK_GAP_MAP: readonly number[];
|
|
88
|
+
fontSizeFromLevel: (lv: number) => number;
|
|
89
|
+
};
|
|
90
|
+
getBreakGapLevel: () => number;
|
|
91
|
+
setBreakGapLevel: (lv: number) => void;
|
|
92
|
+
getFontLevel: () => number;
|
|
93
|
+
getLineLevel: () => number;
|
|
94
|
+
getMarginLevel: () => number;
|
|
95
|
+
setFontLevel: (lv: number) => void;
|
|
96
|
+
setLineLevel: (lv: number) => void;
|
|
97
|
+
setMarginLevel: (lv: number) => void;
|
|
98
|
+
setPointerStyle: (s: PointerStyle) => void;
|
|
99
|
+
setPointerColor: (hex: string) => void;
|
|
100
|
+
toggleBreakMark: (k: BreakMarkKind) => void;
|
|
101
|
+
setBreakMarks: (next: Partial<{
|
|
102
|
+
gap: boolean;
|
|
103
|
+
slash: boolean;
|
|
104
|
+
}>) => void;
|
|
105
|
+
setBreakGapPx: (px: number) => void;
|
|
106
|
+
setMuteAudio: (v: boolean) => void;
|
|
107
|
+
toggleMuteAudio: () => void;
|
|
108
|
+
setAudioSpeed: (speed: number) => void;
|
|
109
|
+
setAudioTargetWpm: (wpm: number) => void;
|
|
110
|
+
setShowPointer: (v: boolean) => void;
|
|
111
|
+
toggleShowPointer: () => void;
|
|
112
|
+
setShowSplit: (v: boolean) => void;
|
|
113
|
+
toggleShowSplit: () => void;
|
|
114
|
+
/** 📐 뷰포트 크기 설정 */
|
|
115
|
+
setViewportSize: (width: number, height: number) => void;
|
|
116
|
+
/** 📐 재생용 뷰포트 크기 설정 */
|
|
117
|
+
setPlaybackViewportSize: (width: number, height: number) => void;
|
|
118
|
+
clearPlaybackViewport: () => void;
|
|
119
|
+
};
|
|
120
|
+
export type CRViewerStore = StoreApi<CRViewerState & CRViewerActions>;
|
|
121
|
+
export declare const FONT_PRESETS: {
|
|
122
|
+
label: string;
|
|
123
|
+
value: string;
|
|
124
|
+
}[];
|
|
125
|
+
export type CRViewerStoreOptions = {
|
|
126
|
+
init?: Partial<CRViewerState>;
|
|
127
|
+
recorderStore?: ViewerRecorderStore;
|
|
128
|
+
};
|
|
129
|
+
export declare function createCRViewerStore(options?: CRViewerStoreOptions): CRViewerStore;
|
|
130
|
+
//# sourceMappingURL=crViewer.store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crViewer.store.d.ts","sourceRoot":"","sources":["../../../src/stores/viewer/crViewer.store.ts"],"names":[],"mappings":"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"}
|