@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.
Files changed (162) hide show
  1. package/dist/CR_Viewer.d.ts +24 -0
  2. package/dist/CR_Viewer.d.ts.map +1 -0
  3. package/dist/components/PageSectionWrap.d.ts +15 -0
  4. package/dist/components/PageSectionWrap.d.ts.map +1 -0
  5. package/dist/components/PaginationRender.d.ts +11 -0
  6. package/dist/components/PaginationRender.d.ts.map +1 -0
  7. package/dist/components/RenderParagraph.d.ts +16 -0
  8. package/dist/components/RenderParagraph.d.ts.map +1 -0
  9. package/dist/components/RenderRuns.d.ts +14 -0
  10. package/dist/components/RenderRuns.d.ts.map +1 -0
  11. package/dist/components/ScrollSectionWrap.d.ts +2 -0
  12. package/dist/components/ScrollSectionWrap.d.ts.map +1 -0
  13. package/dist/components/SectionRendererVirtuoso.d.ts +7 -0
  14. package/dist/components/SectionRendererVirtuoso.d.ts.map +1 -0
  15. package/dist/components/btns/MoveSectionBtns.d.ts +18 -0
  16. package/dist/components/btns/MoveSectionBtns.d.ts.map +1 -0
  17. package/dist/components/btns/SolveQuizBtn.d.ts +2 -0
  18. package/dist/components/btns/SolveQuizBtn.d.ts.map +1 -0
  19. package/dist/components/dom.util.d.ts +40 -0
  20. package/dist/components/dom.util.d.ts.map +1 -0
  21. package/dist/components/quiz/QuizRenderer.d.ts +3 -0
  22. package/dist/components/quiz/QuizRenderer.d.ts.map +1 -0
  23. package/dist/components/scroll/CustomScroller.d.ts +4 -0
  24. package/dist/components/scroll/CustomScroller.d.ts.map +1 -0
  25. package/dist/components/spinner/SectionLoadingSpinner.d.ts +2 -0
  26. package/dist/components/spinner/SectionLoadingSpinner.d.ts.map +1 -0
  27. package/dist/components/spinner/Spinner.d.ts +10 -0
  28. package/dist/components/spinner/Spinner.d.ts.map +1 -0
  29. package/dist/hooks/useDebounce.d.ts +16 -0
  30. package/dist/hooks/useDebounce.d.ts.map +1 -0
  31. package/dist/hooks/useLongPressSpan.d.ts +10 -0
  32. package/dist/hooks/useLongPressSpan.d.ts.map +1 -0
  33. package/dist/hooks/useResizeObserver.d.ts +2 -0
  34. package/dist/hooks/useResizeObserver.d.ts.map +1 -0
  35. package/dist/hooks/useSingleDoubleClick.d.ts +16 -0
  36. package/dist/hooks/useSingleDoubleClick.d.ts.map +1 -0
  37. package/dist/hooks/useSwipePageClicks.d.ts +24 -0
  38. package/dist/hooks/useSwipePageClicks.d.ts.map +1 -0
  39. package/dist/index.cjs +33 -0
  40. package/dist/index.css +1 -0
  41. package/dist/index.d.ts +10 -0
  42. package/dist/index.d.ts.map +1 -0
  43. package/dist/index.js +8723 -0
  44. package/dist/overlay-bars/OverlayLayer.d.ts +3 -0
  45. package/dist/overlay-bars/OverlayLayer.d.ts.map +1 -0
  46. package/dist/overlay-bars/ViewerSettingsSheet.d.ts +6 -0
  47. package/dist/overlay-bars/ViewerSettingsSheet.d.ts.map +1 -0
  48. package/dist/overlay-bars/bottomBar/AudioControlsMini.d.ts +2 -0
  49. package/dist/overlay-bars/bottomBar/AudioControlsMini.d.ts.map +1 -0
  50. package/dist/overlay-bars/bottomBar/FakeAudioControlsMini.d.ts +3 -0
  51. package/dist/overlay-bars/bottomBar/FakeAudioControlsMini.d.ts.map +1 -0
  52. package/dist/overlay-bars/bottomBar/OverlayBottomBar.d.ts +5 -0
  53. package/dist/overlay-bars/bottomBar/OverlayBottomBar.d.ts.map +1 -0
  54. package/dist/overlay-bars/bottomBar/PlayButton.d.ts +13 -0
  55. package/dist/overlay-bars/bottomBar/PlayButton.d.ts.map +1 -0
  56. package/dist/overlay-bars/bottomBar/ProgressScrubber.d.ts +5 -0
  57. package/dist/overlay-bars/bottomBar/ProgressScrubber.d.ts.map +1 -0
  58. package/dist/overlay-bars/bottomBar/StepBtn.d.ts +6 -0
  59. package/dist/overlay-bars/bottomBar/StepBtn.d.ts.map +1 -0
  60. package/dist/overlay-bars/bottomBar/WPMSpeedButtons.d.ts +2 -0
  61. package/dist/overlay-bars/bottomBar/WPMSpeedButtons.d.ts.map +1 -0
  62. package/dist/overlay-bars/topBar/OverlayTopBar.d.ts +5 -0
  63. package/dist/overlay-bars/topBar/OverlayTopBar.d.ts.map +1 -0
  64. package/dist/playback/CR_ViewerPlayback.d.ts +27 -0
  65. package/dist/playback/CR_ViewerPlayback.d.ts.map +1 -0
  66. package/dist/playback/PlaybackBar.d.ts +28 -0
  67. package/dist/playback/PlaybackBar.d.ts.map +1 -0
  68. package/dist/playback/PlaybackToggleButton.d.ts +10 -0
  69. package/dist/playback/PlaybackToggleButton.d.ts.map +1 -0
  70. package/dist/playback/PlaybackViewport.d.ts +30 -0
  71. package/dist/playback/PlaybackViewport.d.ts.map +1 -0
  72. package/dist/playback/index.d.ts +5 -0
  73. package/dist/playback/index.d.ts.map +1 -0
  74. package/dist/playback/types.d.ts +20 -0
  75. package/dist/playback/types.d.ts.map +1 -0
  76. package/dist/recording/PlaybackHandler.d.ts +6 -0
  77. package/dist/recording/PlaybackHandler.d.ts.map +1 -0
  78. package/dist/recording/SettingsChangeEmitter.d.ts +3 -0
  79. package/dist/recording/SettingsChangeEmitter.d.ts.map +1 -0
  80. package/dist/recording/SnapshotRegistrar.d.ts +7 -0
  81. package/dist/recording/SnapshotRegistrar.d.ts.map +1 -0
  82. package/dist/recording/ViewportResizeEmitter.d.ts +7 -0
  83. package/dist/recording/ViewportResizeEmitter.d.ts.map +1 -0
  84. package/dist/stores/audio/crViewer_audio.context.d.ts +10 -0
  85. package/dist/stores/audio/crViewer_audio.context.d.ts.map +1 -0
  86. package/dist/stores/audio/crViewer_audio.hooks.d.ts +6 -0
  87. package/dist/stores/audio/crViewer_audio.hooks.d.ts.map +1 -0
  88. package/dist/stores/audio/crViewer_audio.provider.d.ts +14 -0
  89. package/dist/stores/audio/crViewer_audio.provider.d.ts.map +1 -0
  90. package/dist/stores/audio/crViewer_audio.store.d.ts +65 -0
  91. package/dist/stores/audio/crViewer_audio.store.d.ts.map +1 -0
  92. package/dist/stores/player/index.d.ts +5 -0
  93. package/dist/stores/player/index.d.ts.map +1 -0
  94. package/dist/stores/player/viewerPlayer.context.d.ts +7 -0
  95. package/dist/stores/player/viewerPlayer.context.d.ts.map +1 -0
  96. package/dist/stores/player/viewerPlayer.hooks.d.ts +13 -0
  97. package/dist/stores/player/viewerPlayer.hooks.d.ts.map +1 -0
  98. package/dist/stores/player/viewerPlayer.provider.d.ts +18 -0
  99. package/dist/stores/player/viewerPlayer.provider.d.ts.map +1 -0
  100. package/dist/stores/player/viewerPlayer.store.d.ts +52 -0
  101. package/dist/stores/player/viewerPlayer.store.d.ts.map +1 -0
  102. package/dist/stores/progress/crViewer_progress.context.d.ts +3 -0
  103. package/dist/stores/progress/crViewer_progress.context.d.ts.map +1 -0
  104. package/dist/stores/progress/crViewer_progress.hooks.d.ts +6 -0
  105. package/dist/stores/progress/crViewer_progress.hooks.d.ts.map +1 -0
  106. package/dist/stores/progress/crViewer_progress.provider.d.ts +15 -0
  107. package/dist/stores/progress/crViewer_progress.provider.d.ts.map +1 -0
  108. package/dist/stores/progress/crViewer_progress.store.d.ts +98 -0
  109. package/dist/stores/progress/crViewer_progress.store.d.ts.map +1 -0
  110. package/dist/stores/quizprogress/quiz_progress.context.d.ts +3 -0
  111. package/dist/stores/quizprogress/quiz_progress.context.d.ts.map +1 -0
  112. package/dist/stores/quizprogress/quiz_progress.hooks.d.ts +10 -0
  113. package/dist/stores/quizprogress/quiz_progress.hooks.d.ts.map +1 -0
  114. package/dist/stores/quizprogress/quiz_progress.provider.d.ts +17 -0
  115. package/dist/stores/quizprogress/quiz_progress.provider.d.ts.map +1 -0
  116. package/dist/stores/quizprogress/quiz_progress.store.d.ts +63 -0
  117. package/dist/stores/quizprogress/quiz_progress.store.d.ts.map +1 -0
  118. package/dist/stores/recorder/viewerRecorder.context.d.ts +7 -0
  119. package/dist/stores/recorder/viewerRecorder.context.d.ts.map +1 -0
  120. package/dist/stores/recorder/viewerRecorder.hooks.d.ts +13 -0
  121. package/dist/stores/recorder/viewerRecorder.hooks.d.ts.map +1 -0
  122. package/dist/stores/recorder/viewerRecorder.provider.d.ts +24 -0
  123. package/dist/stores/recorder/viewerRecorder.provider.d.ts.map +1 -0
  124. package/dist/stores/recorder/viewerRecorder.store.d.ts +50 -0
  125. package/dist/stores/recorder/viewerRecorder.store.d.ts.map +1 -0
  126. package/dist/stores/test/tempRecordingStore.d.ts +13 -0
  127. package/dist/stores/test/tempRecordingStore.d.ts.map +1 -0
  128. package/dist/stores/viewer/CRViewer.provider.d.ts +10 -0
  129. package/dist/stores/viewer/CRViewer.provider.d.ts.map +1 -0
  130. package/dist/stores/viewer/crViewer.context.d.ts +7 -0
  131. package/dist/stores/viewer/crViewer.context.d.ts.map +1 -0
  132. package/dist/stores/viewer/crViewer.hooks.d.ts +26 -0
  133. package/dist/stores/viewer/crViewer.hooks.d.ts.map +1 -0
  134. package/dist/stores/viewer/crViewer.store.d.ts +130 -0
  135. package/dist/stores/viewer/crViewer.store.d.ts.map +1 -0
  136. package/dist/types/viewerEvent.types.d.ts +149 -0
  137. package/dist/types/viewerEvent.types.d.ts.map +1 -0
  138. package/dist/utils/audioSrc.d.ts +4 -0
  139. package/dist/utils/audioSrc.d.ts.map +1 -0
  140. package/dist/utils/buildAudioTextMap.d.ts +15 -0
  141. package/dist/utils/buildAudioTextMap.d.ts.map +1 -0
  142. package/dist/utils/calcPage.util.d.ts +42 -0
  143. package/dist/utils/calcPage.util.d.ts.map +1 -0
  144. package/dist/utils/calcPage.util_BACKV3_2399_sf.d.ts +40 -0
  145. package/dist/utils/calcPage.util_BACKV3_2399_sf.d.ts.map +1 -0
  146. package/dist/utils/calcPage.util_BACKclaude.d.ts +40 -0
  147. package/dist/utils/calcPage.util_BACKclaude.d.ts.map +1 -0
  148. package/dist/utils/calcPage.util_BACKclaude_gptagain.d.ts +40 -0
  149. package/dist/utils/calcPage.util_BACKclaude_gptagain.d.ts.map +1 -0
  150. package/dist/utils/calcPage.util_BACKrecent.d.ts +40 -0
  151. package/dist/utils/calcPage.util_BACKrecent.d.ts.map +1 -0
  152. package/dist/utils/calcPage.util_BACKv6_fast_Sf.d.ts +40 -0
  153. package/dist/utils/calcPage.util_BACKv6_fast_Sf.d.ts.map +1 -0
  154. package/dist/utils/doubleRaf.d.ts +3 -0
  155. package/dist/utils/doubleRaf.d.ts.map +1 -0
  156. package/dist/utils/quizSrc.d.ts +3 -0
  157. package/dist/utils/quizSrc.d.ts.map +1 -0
  158. package/dist/utils/sectionRender.util.d.ts +21 -0
  159. package/dist/utils/sectionRender.util.d.ts.map +1 -0
  160. package/dist/utils/text.util.d.ts +3 -0
  161. package/dist/utils/text.util.d.ts.map +1 -0
  162. 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,3 @@
1
+ import { QuizProgressStore } from './quiz_progress.store';
2
+ export declare const QuizProgressContext: import('react').Context<QuizProgressStore | null>;
3
+ //# sourceMappingURL=quiz_progress.context.d.ts.map
@@ -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,7 @@
1
+ import { CRViewerStore } from './crViewer.store';
2
+ /**
3
+ * CRViewer 전용 컨텍스트.
4
+ * 값은 zustand의 StoreApi 인스턴스입니다.
5
+ */
6
+ export declare const CRViewerContext: import('react').Context<CRViewerStore | undefined>;
7
+ //# sourceMappingURL=crViewer.context.d.ts.map
@@ -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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"}