@bendyline/squisq-editor-react 2.11.17 → 2.11.18
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/{chunk-HTO5MTTJ.js → chunk-45NQUR62.js} +1104 -129
- package/dist/{chunk-XZVMKR5Q.js → chunk-CGENKHWY.js} +14 -93
- package/dist/chunk-DNEVUOBZ.js +14 -0
- package/dist/chunk-DNJ6HOES.js +93 -0
- package/dist/{chunk-US5DALTZ.js → chunk-GIXXD2O3.js} +2117 -1941
- package/dist/{chunk-QZWFSSDE.js → chunk-H7YTL6SL.js} +1 -1
- package/dist/chunk-LRZJD5YD.js +107 -0
- package/dist/{chunk-C6QVA6TO.js → chunk-U6NVT3BY.js} +17 -112
- package/dist/{chunk-EJKGXWNK.js → chunk-WKZLBGPX.js} +1 -1
- package/dist/dictationSession-PN3OT5LJ.js +521 -0
- package/dist/index.d.ts +27 -4
- package/dist/index.js +50 -18
- package/dist/recorder/index.js +17 -13
- package/dist/review/index.js +2 -1
- package/dist/shell/index.d.ts +2 -1
- package/dist/shell/index.js +8 -5
- package/dist/{shell-X0EoQbbN.d.ts → shell-Cb0P_ln8.d.ts} +170 -5
- package/dist/speech/index.d.ts +126 -0
- package/dist/speech/index.js +10 -0
- package/dist/styles/index.css +125 -0
- package/dist/teleprompter/index.d.ts +11 -3
- package/dist/teleprompter/index.js +3 -2
- package/package.json +10 -6
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The speech-input (dictation) capability contract between an editor host and
|
|
3
|
+
* the shell.
|
|
4
|
+
*
|
|
5
|
+
* A host that can turn speech into text passes a {@link SpeechInputProvider}
|
|
6
|
+
* (or a factory) to `EditorShell`'s `speechInput` prop — the same
|
|
7
|
+
* capability-injection semantics as `proofing`: absent means the feature is
|
|
8
|
+
* off, no dictation code loads, and no microphone button renders.
|
|
9
|
+
*
|
|
10
|
+
* The editor owns everything up to the recognizer: microphone capture, phrase
|
|
11
|
+
* segmentation, WAV encoding, the toolbar button, the caret indicator and the
|
|
12
|
+
* literal-text insertion. The provider owns only recognition. Audio crosses
|
|
13
|
+
* the boundary as one self-contained mono 16-bit PCM WAV at 16 kHz per take,
|
|
14
|
+
* which every whisper.cpp build accepts and which keeps IPC payloads small.
|
|
15
|
+
* The surface is plain data end to end, so a provider can be a local engine
|
|
16
|
+
* behind IPC, a call to a service, or a test fake.
|
|
17
|
+
*/
|
|
18
|
+
/** Sample rate (Hz) of every WAV take handed to {@link SpeechInputProvider.transcribe}. */
|
|
19
|
+
declare const SPEECH_INPUT_SAMPLE_RATE = 16000;
|
|
20
|
+
/** Coarse readiness of a provider, as the editor's button presents it. */
|
|
21
|
+
type SpeechInputReadinessState =
|
|
22
|
+
/** Dictation can start now. */
|
|
23
|
+
'ready'
|
|
24
|
+
/**
|
|
25
|
+
* The host needs a one-time setup (typically a model download) first.
|
|
26
|
+
* Clicking the microphone calls {@link SpeechInputProvider.requestSetup}
|
|
27
|
+
* instead of starting.
|
|
28
|
+
*/
|
|
29
|
+
| 'download-required'
|
|
30
|
+
/** Dictation can never work in this host/session. The button is hidden. */
|
|
31
|
+
| 'unavailable'
|
|
32
|
+
/**
|
|
33
|
+
* The host still needs a permission (e.g. the OS microphone grant).
|
|
34
|
+
* Starting proceeds — the microphone request is what prompts for it.
|
|
35
|
+
*/
|
|
36
|
+
| 'permission-required';
|
|
37
|
+
interface SpeechInputReadiness {
|
|
38
|
+
readonly state: SpeechInputReadinessState;
|
|
39
|
+
/** Optional human-readable detail, shown in the button's tooltip/errors. */
|
|
40
|
+
readonly reason?: string;
|
|
41
|
+
}
|
|
42
|
+
interface SpeechInputTranscribeOptions {
|
|
43
|
+
/**
|
|
44
|
+
* The recent dictated text of this session (a word-aligned tail of at most
|
|
45
|
+
* 1,000 characters), for engines that accept a priming prompt — Whisper's
|
|
46
|
+
* `prompt`. Absent on the first take.
|
|
47
|
+
*/
|
|
48
|
+
readonly prompt?: string;
|
|
49
|
+
/** BCP-47-ish language hint. The editor does not currently set it. */
|
|
50
|
+
readonly language?: string;
|
|
51
|
+
/**
|
|
52
|
+
* Aborted when the user cancels dictation or the editor unmounts. A
|
|
53
|
+
* provider should stop promptly; a rejection after abort is ignored.
|
|
54
|
+
*/
|
|
55
|
+
readonly signal: AbortSignal;
|
|
56
|
+
}
|
|
57
|
+
interface SpeechInputTranscript {
|
|
58
|
+
/** Recognized text. Blank (or Whisper's `[BLANK_AUDIO]`) means silence. */
|
|
59
|
+
readonly text: string;
|
|
60
|
+
}
|
|
61
|
+
interface SpeechInputProvider {
|
|
62
|
+
/** Stable identifier, e.g. `whisper-local`. */
|
|
63
|
+
readonly id: string;
|
|
64
|
+
/** Human-readable name, e.g. `On-device speech recognition`. */
|
|
65
|
+
readonly label: string;
|
|
66
|
+
/**
|
|
67
|
+
* Current readiness. Called once when the editor mounts with the
|
|
68
|
+
* capability (to decide whether to render the microphone at all) and again
|
|
69
|
+
* each time the user starts dictation. Must be cheap.
|
|
70
|
+
*/
|
|
71
|
+
status(): Promise<SpeechInputReadiness>;
|
|
72
|
+
/** Optional readiness push (e.g. a model finished downloading). Returns unsubscribe. */
|
|
73
|
+
onStatus?(listener: (readiness: SpeechInputReadiness) => void): () => void;
|
|
74
|
+
/** Called when the user starts dictation so the host can warm its engine; may reject. */
|
|
75
|
+
prepare?(signal: AbortSignal): Promise<void>;
|
|
76
|
+
/** Called when the user clicks the mic while readiness is 'download-required'; the host shows its own setup UI. */
|
|
77
|
+
requestSetup?(): void;
|
|
78
|
+
/** Transcribe one self-contained take: mono 16-bit PCM WAV at 16 kHz. */
|
|
79
|
+
transcribe(wav: ArrayBuffer, options: SpeechInputTranscribeOptions): Promise<SpeechInputTranscript>;
|
|
80
|
+
/** Release resources. Called by the editor only for a provider it created from a factory. */
|
|
81
|
+
dispose?(): void;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Deferred construction. The shell creates the provider when it mounts with
|
|
85
|
+
* the capability (it needs `status()` to decide whether to render the
|
|
86
|
+
* microphone) and disposes it on unmount or when the capability changes. A
|
|
87
|
+
* host that passes an instance owns its lifetime — which is what lets one warm
|
|
88
|
+
* engine survive shell remounts.
|
|
89
|
+
*/
|
|
90
|
+
type SpeechInputProviderFactory = () => SpeechInputProvider;
|
|
91
|
+
/** What the `speechInput` shell prop accepts. */
|
|
92
|
+
type SpeechInputCapability = SpeechInputProvider | SpeechInputProviderFactory;
|
|
93
|
+
/**
|
|
94
|
+
* Resolve a capability to a provider instance. A factory is invoked (and the
|
|
95
|
+
* caller then owns — must dispose — what it returns); an instance is returned
|
|
96
|
+
* as-is and stays host-owned.
|
|
97
|
+
*/
|
|
98
|
+
declare function resolveSpeechInputProvider(capability: SpeechInputCapability): SpeechInputProvider;
|
|
99
|
+
/**
|
|
100
|
+
* Whether a capability is a factory, i.e. whether the provider resolved from
|
|
101
|
+
* it is owned (and must be disposed) by the resolver's caller.
|
|
102
|
+
*/
|
|
103
|
+
declare function isSpeechInputProviderFactory(capability: SpeechInputCapability): capability is SpeechInputProviderFactory;
|
|
104
|
+
/**
|
|
105
|
+
* Imperative dictation control on the editor context
|
|
106
|
+
* (`useEditorContext().dictation`), for a host component rendered inside the
|
|
107
|
+
* shell's slots — e.g. to drive dictation from a native menu command. `null`
|
|
108
|
+
* when the host injected no `speechInput` capability.
|
|
109
|
+
*/
|
|
110
|
+
interface DictationControl {
|
|
111
|
+
/** True from the moment dictation starts until its last take is inserted. */
|
|
112
|
+
readonly active: boolean;
|
|
113
|
+
/**
|
|
114
|
+
* True when `toggle()` would do something: the provider is not
|
|
115
|
+
* `unavailable` and a text-editing view (Write or Source) is showing.
|
|
116
|
+
*/
|
|
117
|
+
readonly available: boolean;
|
|
118
|
+
/**
|
|
119
|
+
* Start dictation when idle (or ask the host to set up when readiness is
|
|
120
|
+
* `download-required`); finish and stop when listening; cancel while the
|
|
121
|
+
* microphone is still starting.
|
|
122
|
+
*/
|
|
123
|
+
toggle(): void;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
export { type DictationControl, SPEECH_INPUT_SAMPLE_RATE, type SpeechInputCapability, type SpeechInputProvider, type SpeechInputProviderFactory, type SpeechInputReadiness, type SpeechInputReadinessState, type SpeechInputTranscribeOptions, type SpeechInputTranscript, isSpeechInputProviderFactory, resolveSpeechInputProvider };
|
package/dist/styles/index.css
CHANGED
|
@@ -8145,6 +8145,131 @@
|
|
|
8145
8145
|
text-overflow: ellipsis;
|
|
8146
8146
|
white-space: nowrap;
|
|
8147
8147
|
}
|
|
8148
|
+
.squisq-dictation {
|
|
8149
|
+
position: relative;
|
|
8150
|
+
display: inline-flex;
|
|
8151
|
+
align-items: center;
|
|
8152
|
+
flex-shrink: 0;
|
|
8153
|
+
}
|
|
8154
|
+
.squisq-dictation-button--active,
|
|
8155
|
+
.squisq-dictation-button--active:hover {
|
|
8156
|
+
background: var(--squisq-danger-soft);
|
|
8157
|
+
color: var(--squisq-danger-strong);
|
|
8158
|
+
}
|
|
8159
|
+
.squisq-dictation-button--listening {
|
|
8160
|
+
width: auto;
|
|
8161
|
+
gap: 6px;
|
|
8162
|
+
padding: 2px 8px 0;
|
|
8163
|
+
}
|
|
8164
|
+
.squisq-dictation-button[aria-busy=true] > i {
|
|
8165
|
+
animation: squisq-dictation-pulse 1.2s ease-in-out infinite;
|
|
8166
|
+
}
|
|
8167
|
+
.squisq-dictation-meter {
|
|
8168
|
+
display: inline-flex;
|
|
8169
|
+
align-items: center;
|
|
8170
|
+
gap: 1px;
|
|
8171
|
+
height: 16px;
|
|
8172
|
+
}
|
|
8173
|
+
.squisq-dictation-meter-bar {
|
|
8174
|
+
width: 2px;
|
|
8175
|
+
min-height: 2px;
|
|
8176
|
+
border-radius: 1px;
|
|
8177
|
+
background: currentColor;
|
|
8178
|
+
transition: height 0.05s linear;
|
|
8179
|
+
}
|
|
8180
|
+
.squisq-dictation-error {
|
|
8181
|
+
position: absolute;
|
|
8182
|
+
top: calc(100% + 6px);
|
|
8183
|
+
right: 0;
|
|
8184
|
+
z-index: 110;
|
|
8185
|
+
display: flex;
|
|
8186
|
+
align-items: flex-start;
|
|
8187
|
+
gap: 8px;
|
|
8188
|
+
width: max-content;
|
|
8189
|
+
max-width: min(320px, calc(100vw - 24px));
|
|
8190
|
+
padding: 8px 8px 8px 12px;
|
|
8191
|
+
border: 1px solid var(--squisq-danger-border);
|
|
8192
|
+
border-radius: 8px;
|
|
8193
|
+
background: var(--squisq-surface);
|
|
8194
|
+
box-shadow: var(--squisq-shadow-md);
|
|
8195
|
+
color: var(--squisq-danger-text);
|
|
8196
|
+
font-size: 12px;
|
|
8197
|
+
font-weight: 500;
|
|
8198
|
+
line-height: 1.4;
|
|
8199
|
+
white-space: normal;
|
|
8200
|
+
}
|
|
8201
|
+
.squisq-dictation-error-text {
|
|
8202
|
+
flex: 1;
|
|
8203
|
+
}
|
|
8204
|
+
.squisq-dictation-error-dismiss {
|
|
8205
|
+
flex-shrink: 0;
|
|
8206
|
+
padding: 0 2px;
|
|
8207
|
+
border: 0;
|
|
8208
|
+
background: transparent;
|
|
8209
|
+
color: var(--squisq-text-muted);
|
|
8210
|
+
cursor: pointer;
|
|
8211
|
+
font-size: 12px;
|
|
8212
|
+
line-height: 1.4;
|
|
8213
|
+
}
|
|
8214
|
+
.squisq-dictation-error-dismiss:hover {
|
|
8215
|
+
color: var(--squisq-text-strong);
|
|
8216
|
+
}
|
|
8217
|
+
.squisq-dictation-interim {
|
|
8218
|
+
display: inline-block;
|
|
8219
|
+
margin-left: 2px;
|
|
8220
|
+
padding: 0 6px;
|
|
8221
|
+
border-radius: 999px;
|
|
8222
|
+
background: var(--squisq-danger-soft);
|
|
8223
|
+
color: var(--squisq-text-muted);
|
|
8224
|
+
font-size: 0.78em;
|
|
8225
|
+
font-style: italic;
|
|
8226
|
+
font-weight: 400;
|
|
8227
|
+
line-height: 1.5;
|
|
8228
|
+
vertical-align: baseline;
|
|
8229
|
+
white-space: nowrap;
|
|
8230
|
+
user-select: none;
|
|
8231
|
+
pointer-events: none;
|
|
8232
|
+
}
|
|
8233
|
+
.squisq-dictation-interim::before {
|
|
8234
|
+
content: "";
|
|
8235
|
+
display: inline-block;
|
|
8236
|
+
width: 6px;
|
|
8237
|
+
height: 6px;
|
|
8238
|
+
margin-right: 5px;
|
|
8239
|
+
border-radius: 50%;
|
|
8240
|
+
background: var(--squisq-danger);
|
|
8241
|
+
vertical-align: 0.1em;
|
|
8242
|
+
animation: squisq-dictation-pulse 1.2s ease-in-out infinite;
|
|
8243
|
+
}
|
|
8244
|
+
.squisq-dictation-interim--source {
|
|
8245
|
+
display: inline;
|
|
8246
|
+
margin-left: 0.5ch;
|
|
8247
|
+
padding: 0;
|
|
8248
|
+
background: transparent;
|
|
8249
|
+
font-size: inherit;
|
|
8250
|
+
line-height: inherit;
|
|
8251
|
+
opacity: 0.8;
|
|
8252
|
+
}
|
|
8253
|
+
.squisq-dictation-interim--source::before {
|
|
8254
|
+
content: none;
|
|
8255
|
+
}
|
|
8256
|
+
@keyframes squisq-dictation-pulse {
|
|
8257
|
+
0%, 100% {
|
|
8258
|
+
opacity: 1;
|
|
8259
|
+
}
|
|
8260
|
+
50% {
|
|
8261
|
+
opacity: 0.35;
|
|
8262
|
+
}
|
|
8263
|
+
}
|
|
8264
|
+
@media (prefers-reduced-motion: reduce) {
|
|
8265
|
+
.squisq-dictation-interim::before,
|
|
8266
|
+
.squisq-dictation-button[aria-busy=true] > i {
|
|
8267
|
+
animation: none;
|
|
8268
|
+
}
|
|
8269
|
+
.squisq-dictation-meter-bar {
|
|
8270
|
+
transition: none;
|
|
8271
|
+
}
|
|
8272
|
+
}
|
|
8148
8273
|
|
|
8149
8274
|
/* src/styles/template-picker.css */
|
|
8150
8275
|
.squisq-mermaid-type-menu {
|
|
@@ -3,7 +3,7 @@ import { Doc, Theme, MediaProvider } from '@bendyline/squisq/schemas';
|
|
|
3
3
|
import { ContentContainer } from '@bendyline/squisq/storage';
|
|
4
4
|
import { o as TeleprompterRecordingDeps, g as NarrationStageHandle, T as TeleprompterController, c as FloatingWindowHandle } from '../useNarrationStage-vKtk6H-V.js';
|
|
5
5
|
export { C as CanvasSink, D as DEFAULT_TELEPROMPTER_PREFS, F as FloatOpenOptions, b as FloatTier, d as FloatingWindowManager, M as MicAnalysisHandle, e as MicAnalysisStatus, N as NarrationRecorderController, f as NarrationRecorderState, h as NarrationTake, P as PrompterTransport, J as TELEPROMPTER_PREF_LIMITS, n as TeleprompterPrefs, q as UseNarrationStageOptions, s as createFloatingWindowManager, t as detectFloatTiers, K as normalizeTeleprompterPrefs, z as useFloatingWindow, B as useMicAnalysis, E as useNarrationRecorder, G as useNarrationStage, H as useTeleprompter, I as vadConfigForSensitivity } from '../useNarrationStage-vKtk6H-V.js';
|
|
6
|
-
import { NarrationTimingJsonV3, NarrationScript, NarrationAlignment } from '@bendyline/squisq/narration';
|
|
6
|
+
import { NarrationTimingJsonV3, NarrationScript, NarrationAlignment, NarrationTimingGenerator } from '@bendyline/squisq/narration';
|
|
7
7
|
import { ReactNode } from 'react';
|
|
8
8
|
|
|
9
9
|
interface TeleprompterViewProps {
|
|
@@ -88,10 +88,18 @@ interface NarrationSavePlanArgs {
|
|
|
88
88
|
durationSec: number;
|
|
89
89
|
audioExt: string;
|
|
90
90
|
cameraExt: string | null;
|
|
91
|
-
baseWpm
|
|
91
|
+
/** Speaking rate the take was paced at; recorded as `generator.baseWpm`. */
|
|
92
|
+
baseWpm?: number;
|
|
92
93
|
cameraOffsetSec?: number;
|
|
93
94
|
/** User-chosen filename base for the audio file; default timestamped `narration-…`. */
|
|
94
95
|
audioBasename?: string;
|
|
96
|
+
/**
|
|
97
|
+
* Provenance written to the sidecar's `generator`. Defaults to the
|
|
98
|
+
* teleprompter aligner (`squisq-teleprompter` / `dsp-align`); a host that
|
|
99
|
+
* produced the timings itself names itself here — e.g.
|
|
100
|
+
* `{ name: 'my-tts', method: 'tts' }` for generated narration.
|
|
101
|
+
*/
|
|
102
|
+
generator?: NarrationTimingGenerator;
|
|
95
103
|
}
|
|
96
104
|
interface NarrationSavePlan {
|
|
97
105
|
audioRelativeName: string;
|
|
@@ -305,4 +313,4 @@ declare function prompterVarsFromTheme(theme: Theme): Record<string, string>;
|
|
|
305
313
|
declare function ensureTeleprompterStyles(doc: Document): void;
|
|
306
314
|
declare const TELEPROMPTER_CSS = "\n.squisq-teleprompter-root {\n display: flex;\n flex-direction: column;\n width: 100%;\n height: 100%;\n min-height: 0;\n background: var(--squisq-bg, #f5f5f5);\n outline: none;\n}\n.squisq-teleprompter-stage {\n position: relative;\n flex: 1;\n min-height: 0;\n display: flex;\n}\n\n.squisq-teleprompter-surface {\n position: relative;\n flex: 1;\n min-height: 0;\n overflow: hidden;\n background: var(--squisq-prompter-bg, #101014);\n color: var(--squisq-prompter-text, #f5f5f2);\n font-family: var(--squisq-prompter-font, system-ui, sans-serif);\n user-select: none;\n}\n.squisq-teleprompter-flip {\n position: absolute;\n inset: 0;\n}\n.squisq-teleprompter-surface--mirrored .squisq-teleprompter-flip {\n transform: scaleX(-1);\n}\n.squisq-teleprompter-scroll {\n position: absolute;\n left: 0;\n right: 0;\n top: 0;\n will-change: transform;\n padding: 40vh 8% 60vh;\n box-sizing: border-box;\n}\n.squisq-teleprompter-line-guide {\n position: absolute;\n left: 0;\n right: 0;\n pointer-events: none;\n z-index: 2;\n}\n.squisq-teleprompter-line-guide::before,\n.squisq-teleprompter-line-guide::after {\n content: '';\n position: absolute;\n top: 50%;\n border: 9px solid transparent;\n transform: translateY(-50%);\n}\n.squisq-teleprompter-line-guide::before {\n left: 6px;\n border-left-color: var(--squisq-prompter-accent, #e8b64c);\n}\n.squisq-teleprompter-line-guide::after {\n right: 6px;\n border-right-color: var(--squisq-prompter-accent, #e8b64c);\n}\n.squisq-teleprompter-guide-band {\n position: absolute;\n left: 0;\n right: 0;\n background: color-mix(in srgb, var(--squisq-prompter-accent, #e8b64c) 9%, transparent);\n pointer-events: none;\n z-index: 1;\n}\n\n.squisq-teleprompter-block-marker {\n display: block;\n margin: 1.1em 0 0.35em;\n font-size: 0.38em;\n font-weight: 600;\n letter-spacing: 0.14em;\n text-transform: uppercase;\n color: var(--squisq-prompter-muted, #9a9aa0);\n border-top: 1px solid color-mix(in srgb, var(--squisq-prompter-muted, #9a9aa0) 35%, transparent);\n padding-top: 0.6em;\n}\n.squisq-teleprompter-para {\n margin: 0 0 0.55em;\n line-height: 1.4;\n font-weight: 500;\n}\n.squisq-teleprompter-word {\n opacity: 0.45;\n transition: color 0.1s linear, opacity 0.1s linear;\n}\n.squisq-teleprompter-word--read {\n opacity: 0.9;\n}\n.squisq-teleprompter-word--active {\n opacity: 1;\n font-weight: 800;\n color: var(--squisq-prompter-accent, #e8b64c);\n}\n\n.squisq-teleprompter-countdown {\n position: absolute;\n inset: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 3;\n background: color-mix(in srgb, var(--squisq-prompter-bg, #101014) 72%, transparent);\n}\n.squisq-teleprompter-countdown-digit {\n font-size: 18vmin;\n font-weight: 800;\n color: var(--squisq-prompter-accent, #e8b64c);\n animation: squisq-prompter-pulse 1s ease-in-out infinite;\n}\n.squisq-teleprompter-recdot {\n position: absolute;\n top: 14px;\n right: 16px;\n z-index: 4;\n width: 14px;\n height: 14px;\n border-radius: 50%;\n background: #e5484d;\n box-shadow: 0 0 0 3px color-mix(in srgb, #e5484d 30%, transparent);\n animation: squisq-prompter-pulse 1.4s ease-in-out infinite;\n}\n/* Counter-flip overlays so they stay readable in mirror mode. */\n.squisq-teleprompter-surface--mirrored .squisq-teleprompter-countdown,\n.squisq-teleprompter-surface--mirrored .squisq-teleprompter-recdot {\n transform: scaleX(-1);\n}\n\n.squisq-teleprompter-selfview {\n position: absolute;\n right: 14px;\n bottom: 14px;\n width: 160px;\n border-radius: 8px;\n border: 2px solid color-mix(in srgb, #e5484d 60%, transparent);\n z-index: 5;\n background: #000;\n}\n\n.squisq-teleprompter-review {\n display: flex;\n align-items: center;\n flex-wrap: wrap;\n gap: 10px;\n padding: 8px 12px;\n border-top: 1px solid var(--squisq-border, #e5e7eb);\n background: var(--squisq-surface, var(--squisq-bg, #fff));\n color: var(--squisq-text, #111827);\n font-size: 12.5px;\n}\n.squisq-teleprompter-review audio {\n height: 28px;\n max-width: 260px;\n}\n.squisq-teleprompter-review button {\n font: inherit;\n color: inherit;\n background: var(--squisq-input-bg, #fff);\n border: 1px solid var(--squisq-border, #d1d5db);\n border-radius: 6px;\n padding: 4px 10px;\n cursor: pointer;\n}\n\n.squisq-teleprompter-float-note {\n flex: 1;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 12px;\n color: var(--squisq-text-muted, #4b5563);\n font-size: 14px;\n}\n\n.squisq-teleprompter-controls {\n display: flex;\n align-items: center;\n flex-wrap: wrap;\n gap: 10px;\n padding: 8px 12px;\n border-top: 1px solid var(--squisq-border, #e5e7eb);\n background: var(--squisq-surface, var(--squisq-bg, #fff));\n color: var(--squisq-text, #111827);\n font-size: 12.5px;\n}\n.squisq-teleprompter-controls .squisq-teleprompter-group {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n white-space: nowrap;\n}\n.squisq-teleprompter-controls button {\n font: inherit;\n color: inherit;\n background: var(--squisq-input-bg, #fff);\n border: 1px solid var(--squisq-border, #d1d5db);\n border-radius: 6px;\n padding: 4px 10px;\n cursor: pointer;\n}\n.squisq-teleprompter-controls button:hover {\n background: var(--squisq-surface-hover, #f3f4f6);\n}\n.squisq-teleprompter-controls button[aria-pressed='true'] {\n background: var(--squisq-text, #111827);\n color: var(--squisq-bg, #fff);\n border-color: var(--squisq-text, #111827);\n}\n.squisq-teleprompter-controls select,\n.squisq-teleprompter-controls input[type='range'] {\n font: inherit;\n color: inherit;\n background: var(--squisq-input-bg, #fff);\n border: 1px solid var(--squisq-border, #d1d5db);\n border-radius: 6px;\n max-width: 170px;\n}\n.squisq-teleprompter-controls input[type='range'] {\n border: none;\n background: transparent;\n width: 110px;\n}\n.squisq-teleprompter-meter {\n position: relative;\n width: 64px;\n height: 8px;\n border-radius: 4px;\n overflow: hidden;\n background: var(--squisq-border, #e5e7eb);\n}\n.squisq-teleprompter-meter-fill {\n position: absolute;\n inset: 0 auto 0 0;\n background: #9ca3af;\n transition: width 0.08s linear;\n}\n.squisq-teleprompter-meter--voice .squisq-teleprompter-meter-fill {\n background: #30a46c;\n}\n\n@keyframes squisq-prompter-pulse {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0.45; }\n}\n@media (prefers-reduced-motion: reduce) {\n .squisq-teleprompter-countdown-digit,\n .squisq-teleprompter-recdot {\n animation: none;\n }\n .squisq-teleprompter-word {\n transition: none;\n }\n}\n";
|
|
307
315
|
|
|
308
|
-
export { EYE_LINE_FRACTION, FloatingWindowHandle, type NarrationSavePlan, type NarrationSaveResult, NarrationStage, NarrationStageHandle, type NarrationStageProps, PCM_WORKLET_NAME, PCM_WORKLET_SOURCE, TELEPROMPTER_CSS, TeleprompterController, TeleprompterControls, type TeleprompterControlsProps, TeleprompterRecordingDeps, TeleprompterSurface, type TeleprompterSurfaceProps, TeleprompterView, type TeleprompterViewProps, type TokenLineMap, buildNarrationSavePlan, cameraVideoLine, ensureTeleprompterStyles, executeNarrationSave, insertNarrationPreamble, measureTokenLines, narrationAnnotationLine, prompterVarsFromTheme, registerPcmWorklet, stepScroll, targetOffsetFor };
|
|
316
|
+
export { EYE_LINE_FRACTION, type ExecuteNarrationSaveDeps, FloatingWindowHandle, type NarrationSavePlan, type NarrationSavePlanArgs, type NarrationSaveProgress, type NarrationSaveResult, NarrationStage, NarrationStageHandle, type NarrationStageProps, PCM_WORKLET_NAME, PCM_WORKLET_SOURCE, TELEPROMPTER_CSS, TeleprompterController, TeleprompterControls, type TeleprompterControlsProps, TeleprompterRecordingDeps, TeleprompterSurface, type TeleprompterSurfaceProps, TeleprompterView, type TeleprompterViewProps, type TokenLineMap, buildNarrationSavePlan, cameraVideoLine, ensureTeleprompterStyles, executeNarrationSave, insertNarrationPreamble, measureTokenLines, narrationAnnotationLine, prompterVarsFromTheme, registerPcmWorklet, stepScroll, targetOffsetFor };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
TeleprompterView
|
|
3
|
-
} from "../chunk-
|
|
3
|
+
} from "../chunk-H7YTL6SL.js";
|
|
4
4
|
import {
|
|
5
5
|
DEFAULT_TELEPROMPTER_PREFS,
|
|
6
6
|
EYE_LINE_FRACTION,
|
|
@@ -31,7 +31,8 @@ import {
|
|
|
31
31
|
useNarrationStage,
|
|
32
32
|
useTeleprompter,
|
|
33
33
|
vadConfigForSensitivity
|
|
34
|
-
} from "../chunk-
|
|
34
|
+
} from "../chunk-CGENKHWY.js";
|
|
35
|
+
import "../chunk-DNJ6HOES.js";
|
|
35
36
|
export {
|
|
36
37
|
DEFAULT_TELEPROMPTER_PREFS,
|
|
37
38
|
EYE_LINE_FRACTION,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bendyline/squisq-editor-react",
|
|
3
|
-
"version": "2.11.
|
|
3
|
+
"version": "2.11.18",
|
|
4
4
|
"description": "React editor shell with raw/WYSIWYG/preview modes for Squisq documents",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Bendyline",
|
|
@@ -76,6 +76,10 @@
|
|
|
76
76
|
"types": "./dist/review/index.d.ts",
|
|
77
77
|
"import": "./dist/review/index.js"
|
|
78
78
|
},
|
|
79
|
+
"./speech": {
|
|
80
|
+
"types": "./dist/speech/index.d.ts",
|
|
81
|
+
"import": "./dist/speech/index.js"
|
|
82
|
+
},
|
|
79
83
|
"./styles": {
|
|
80
84
|
"types": "./dist/styles/index.d.ts",
|
|
81
85
|
"default": "./dist/styles/index.css"
|
|
@@ -98,12 +102,12 @@
|
|
|
98
102
|
}
|
|
99
103
|
},
|
|
100
104
|
"dependencies": {
|
|
101
|
-
"@bendyline/squisq": "2.11.
|
|
105
|
+
"@bendyline/squisq": "2.11.15",
|
|
102
106
|
"@bendyline/squisq-calc": "2.11.1",
|
|
103
|
-
"@bendyline/squisq-formats": "2.6.
|
|
104
|
-
"@bendyline/squisq-grid-react": "2.11.
|
|
105
|
-
"@bendyline/squisq-react": "2.11.
|
|
106
|
-
"@bendyline/squisq-video-react": "2.4.
|
|
107
|
+
"@bendyline/squisq-formats": "2.6.15",
|
|
108
|
+
"@bendyline/squisq-grid-react": "2.11.16",
|
|
109
|
+
"@bendyline/squisq-react": "2.11.17",
|
|
110
|
+
"@bendyline/squisq-video-react": "2.4.21",
|
|
107
111
|
"@fortawesome/fontawesome-free": "7.2.0",
|
|
108
112
|
"@tiptap/core": "2.27.3",
|
|
109
113
|
"@tiptap/extension-heading": "2.27.3",
|