@sutrata/editor 0.3.0 → 0.4.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 (39) hide show
  1. package/dist/ai/VoiceConfirmDialog.js +3 -1
  2. package/dist/ai/VoiceToolbar.js +8 -8
  3. package/dist/context/DocumentContext.js +30 -24
  4. package/dist/editor/SelectionMenu.js +3 -1
  5. package/dist/file/builtin-exporters.js +20 -24
  6. package/dist/findreplace/FindReplace.js +31 -22
  7. package/dist/findreplace/scroll-to-match.d.ts +1 -1
  8. package/dist/findreplace/scroll-to-match.js +12 -2
  9. package/dist/i18n/useTranslation.js +1 -1
  10. package/dist/import/AIImportDialog.js +20 -18
  11. package/dist/locales/bn.json +195 -13
  12. package/dist/locales/en.json +194 -12
  13. package/dist/locales/gu.json +195 -13
  14. package/dist/locales/hi.json +195 -13
  15. package/dist/locales/kn.json +195 -13
  16. package/dist/locales/ml.json +195 -13
  17. package/dist/locales/mr.json +195 -13
  18. package/dist/locales/or.json +195 -13
  19. package/dist/locales/pa.json +194 -12
  20. package/dist/locales/si.json +195 -13
  21. package/dist/locales/ta.json +195 -13
  22. package/dist/locales/te.json +195 -13
  23. package/dist/navigator/SceneNavigator.js +118 -62
  24. package/dist/navigator/StatisticsDialog.js +4 -2
  25. package/dist/navigator/scene-list.d.ts +7 -0
  26. package/dist/navigator/scene-list.js +14 -0
  27. package/dist/shell/AppBar.js +2 -2
  28. package/dist/shell/AppShell.js +1 -1
  29. package/dist/shell/ConfirmDialog.js +4 -2
  30. package/dist/shell/ElementToolbar.js +4 -2
  31. package/dist/shell/LanguageStatus.js +3 -1
  32. package/dist/shell/StatusBar.js +1 -1
  33. package/dist/shell/VersionHistory.js +4 -2
  34. package/dist/source/find-highlight-source.d.ts +1 -1
  35. package/dist/source/find-highlight-source.js +3 -2
  36. package/dist/styles/screenplay.css +12 -0
  37. package/dist/titlepage/ExportDialog.js +6 -6
  38. package/dist/titlepage/TitlePageDialog.js +2 -2
  39. package/package.json +1 -1
@@ -1,22 +1,23 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  import { useMemo, useRef, useState } from 'react';
3
3
  import { useDocument } from '../context/DocumentContext';
4
+ import { useTranslation } from '../i18n/useTranslation';
4
5
  import { useAI } from '../extensions/ai-provider';
5
6
  import { readImportFile, IMPORT_ACCEPT } from './extract';
6
7
  import { runAiImport, splitBlocks, blockKind, retypeBlock } from './ai-import';
7
8
  import { applyImport } from './apply-import';
8
- const KIND_LABELS = {
9
- scene_heading: 'Scene heading',
10
- action: 'Action',
11
- character: 'Character + dialogue',
12
- transition: 'Transition',
13
- centered: 'Centered',
14
- lyrics: 'Lyrics',
15
- note: 'Note',
16
- section: 'Section',
17
- other: 'Other',
9
+ const KIND_LABEL_KEYS = {
10
+ scene_heading: 'toolbar.scene',
11
+ action: 'toolbar.action',
12
+ character: 'aiimport.kind.character',
13
+ transition: 'toolbar.transition',
14
+ centered: 'toolbar.centered',
15
+ lyrics: 'toolbar.lyrics',
16
+ note: 'toolbar.note',
17
+ section: 'toolbar.section',
18
+ other: 'aiimport.kind.other',
18
19
  };
19
- const KIND_OPTIONS = Object.keys(KIND_LABELS).filter(k => k !== 'other');
20
+ const KIND_OPTIONS = Object.keys(KIND_LABEL_KEYS).filter(k => k !== 'other');
20
21
  /**
21
22
  * AI-assisted import (OSS spec §5.5): pick a Word/text/Markdown file (or paste
22
23
  * text), confirm the provider's data policy, let the AI format it as Sutra in
@@ -26,6 +27,7 @@ const KIND_OPTIONS = Object.keys(KIND_LABELS).filter(k => k !== 'other');
26
27
  */
27
28
  export function AIImportDialog({ onClose }) {
28
29
  const ai = useAI();
30
+ const { t } = useTranslation();
29
31
  const { text, setText, showToast } = useDocument();
30
32
  const [step, setStep] = useState({ name: 'source' });
31
33
  const [pasted, setPasted] = useState('');
@@ -78,7 +80,7 @@ export function AIImportDialog({ onClose }) {
78
80
  signal: controller.signal,
79
81
  onProgress: (done, total) => setStep({ name: 'running', done, total }),
80
82
  });
81
- const warnings = result.chunks.flatMap(c => c.problems.map(p => `Part ${c.index + 1}: ${p}`));
83
+ const warnings = result.chunks.flatMap(c => c.problems.map(p => t('aiimport.part').replace('{n}', String(c.index + 1)).replace('{problem}', p)));
82
84
  setStep({ name: 'review', fileName, source, blocks: splitBlocks(result.sutra), chunks: result.chunks, warnings });
83
85
  }
84
86
  catch (e) {
@@ -97,16 +99,16 @@ export function AIImportDialog({ onClose }) {
97
99
  if (step.name !== 'review')
98
100
  return;
99
101
  applyImport(formatted, how, text, setText);
100
- showToast(`Imported ${step.fileName} (${step.blocks.length} blocks).`, 'success');
102
+ showToast(t('aiimport.imported').replace('{file}', step.fileName).replace('{n}', String(step.blocks.length)), 'success');
101
103
  onClose();
102
104
  };
103
- return (_jsx("div", { className: "cs-dialog-overlay", onClick: close, children: _jsxs("div", { className: "cs-dialog cs-ai-import-dialog", role: "dialog", "aria-modal": "true", "aria-label": "Import with AI", onClick: e => e.stopPropagation(), onKeyDown: e => { if (e.key === 'Escape')
104
- close(); }, style: { maxWidth: step.name === 'review' ? '1100px' : '560px', width: '94%' }, children: [_jsxs("div", { className: "cs-dialog-header", children: [_jsx("span", { className: "cs-dialog-title", children: "Import with AI" }), _jsx("button", { className: "cs-fr-close", "aria-label": "Close", onClick: close, children: "\u00D7" })] }), _jsxs("div", { className: "cs-ai-import-body", children: [error && _jsx("div", { className: "cs-ai-import-error", role: "alert", children: error }), step.name === 'source' && (_jsxs(_Fragment, { children: [_jsx("p", { className: "cs-ai-import-hint", children: "Import a screenplay written in Word, a text file or Markdown. The AI formats it as Sutra; you review the result before anything changes. A Word file exported from Sutrata is imported directly, without AI." }), _jsx("input", { ref: fileRef, type: "file", accept: IMPORT_ACCEPT, "aria-label": "Choose a file to import", onChange: e => void pickFile(e.target.files?.[0]) }), _jsx("label", { className: "cs-settings-label", htmlFor: "cs-ai-import-paste", style: { display: 'block', marginTop: 12 }, children: "\u2026or paste the text" }), _jsx("textarea", { id: "cs-ai-import-paste", className: "cs-ai-import-paste", rows: 8, value: pasted, onChange: e => setPasted(e.target.value) }), _jsx("div", { className: "cs-ai-import-actions", children: _jsx("button", { type: "button", className: "cs-confirm-btn-primary", disabled: !pasted.trim(), onClick: () => setStep({ name: 'confirm', fileName: 'pasted text', text: pasted.trim() }), children: "Continue" }) })] })), step.name === 'confirm' && (_jsxs(_Fragment, { children: [_jsxs("p", { className: "cs-ai-import-hint", children: [_jsx("strong", { children: step.fileName }), " (", step.text.length.toLocaleString(), " characters) will be sent to", ' ', _jsx("strong", { children: ai.displayName }), " to be formatted."] }), _jsx("div", { className: "cs-ai-import-policy", "aria-label": "Data policy", children: ai.dataPolicyText }), _jsxs("label", { className: "cs-ai-import-agree", children: [_jsx("input", { type: "checkbox", checked: agreed, onChange: e => setAgreed(e.target.checked) }), "I understand, send this text to ", ai.displayName] }), _jsxs("div", { className: "cs-ai-import-actions", children: [_jsx("button", { type: "button", className: "cs-confirm-btn-cancel", onClick: () => setStep({ name: 'source' }), children: "Back" }), _jsx("button", { type: "button", className: "cs-confirm-btn-primary", disabled: !agreed, onClick: () => void start(step.fileName, step.text), children: "Format with AI" })] })] })), step.name === 'running' && (_jsxs(_Fragment, { children: [_jsxs("p", { className: "cs-ai-import-hint", role: "status", children: [_jsx("span", { className: "cs-spinner", style: { width: 10, height: 10, borderWidth: 1.5, marginRight: 8 } }), "Formatting part ", Math.min(step.done + 1, step.total), " of ", step.total, "\u2026"] }), _jsx("div", { className: "cs-ai-import-actions", children: _jsx("button", { type: "button", className: "cs-confirm-btn-cancel", onClick: () => abortRef.current?.abort(), children: "Cancel" }) })] })), step.name === 'review' && (_jsxs(_Fragment, { children: [step.warnings.length > 0 && (_jsxs("div", { className: "cs-export-warnings cs-ai-import-warnings", role: "alert", children: [_jsx("div", { className: "cs-export-warn-title", children: "Check these parts before importing" }), step.warnings.map((w, i) => _jsxs("div", { className: "cs-export-warn-item", children: ["\u2022 ", w] }, i))] })), _jsxs("div", { className: "cs-ai-import-review", children: [_jsxs("section", { "aria-label": "Source", children: [_jsx("div", { className: "cs-ai-import-col-title", children: "Source" }), _jsx("pre", { className: "cs-ai-import-source", children: step.source })] }), _jsxs("section", { "aria-label": "Formatted", children: [_jsxs("div", { className: "cs-ai-import-col-title", children: ["Formatted (", step.blocks.length, " blocks)"] }), _jsx("ol", { className: "cs-ai-import-blocks", children: step.blocks.map((block, i) => {
105
+ return (_jsx("div", { className: "cs-dialog-overlay", onClick: close, children: _jsxs("div", { className: "cs-dialog cs-ai-import-dialog", role: "dialog", "aria-modal": "true", "aria-label": t('appbar.importAI'), onClick: e => e.stopPropagation(), onKeyDown: e => { if (e.key === 'Escape')
106
+ close(); }, style: { maxWidth: step.name === 'review' ? '1100px' : '560px', width: '94%' }, children: [_jsxs("div", { className: "cs-dialog-header", children: [_jsx("span", { className: "cs-dialog-title", children: t('appbar.importAI') }), _jsx("button", { className: "cs-fr-close", "aria-label": t('common.close'), onClick: close, children: "\u00D7" })] }), _jsxs("div", { className: "cs-ai-import-body", children: [error && _jsx("div", { className: "cs-ai-import-error", role: "alert", children: error }), step.name === 'source' && (_jsxs(_Fragment, { children: [_jsx("p", { className: "cs-ai-import-hint", children: t('aiimport.hint') }), _jsx("input", { ref: fileRef, type: "file", accept: IMPORT_ACCEPT, "aria-label": t('aiimport.choose'), onChange: e => void pickFile(e.target.files?.[0]) }), _jsx("label", { className: "cs-settings-label", htmlFor: "cs-ai-import-paste", style: { display: 'block', marginTop: 12 }, children: t('aiimport.paste') }), _jsx("textarea", { id: "cs-ai-import-paste", className: "cs-ai-import-paste", rows: 8, value: pasted, onChange: e => setPasted(e.target.value) }), _jsx("div", { className: "cs-ai-import-actions", children: _jsx("button", { type: "button", className: "cs-confirm-btn-primary", disabled: !pasted.trim(), onClick: () => setStep({ name: 'confirm', fileName: t('aiimport.pastedText'), text: pasted.trim() }), children: t('aiimport.continue') }) })] })), step.name === 'confirm' && (_jsxs(_Fragment, { children: [_jsx("p", { className: "cs-ai-import-hint", children: t('aiimport.summary').replace('{file}', step.fileName).replace('{chars}', step.text.length.toLocaleString()).replace('{name}', ai.displayName) }), _jsx("div", { className: "cs-ai-import-policy", "aria-label": t('aiimport.policy'), children: ai.dataPolicyText }), _jsxs("label", { className: "cs-ai-import-agree", children: [_jsx("input", { type: "checkbox", checked: agreed, onChange: e => setAgreed(e.target.checked) }), t('aiimport.agree').replace('{name}', ai.displayName)] }), _jsxs("div", { className: "cs-ai-import-actions", children: [_jsx("button", { type: "button", className: "cs-confirm-btn-cancel", onClick: () => setStep({ name: 'source' }), children: t('aiimport.back') }), _jsx("button", { type: "button", className: "cs-confirm-btn-primary", disabled: !agreed, onClick: () => void start(step.fileName, step.text), children: t('aiimport.format') })] })] })), step.name === 'running' && (_jsxs(_Fragment, { children: [_jsxs("p", { className: "cs-ai-import-hint", role: "status", children: [_jsx("span", { className: "cs-spinner", style: { width: 10, height: 10, borderWidth: 1.5, marginRight: 8 } }), t('aiimport.progress').replace('{done}', String(Math.min(step.done + 1, step.total))).replace('{total}', String(step.total))] }), _jsx("div", { className: "cs-ai-import-actions", children: _jsx("button", { type: "button", className: "cs-confirm-btn-cancel", onClick: () => abortRef.current?.abort(), children: t('common.cancel') }) })] })), step.name === 'review' && (_jsxs(_Fragment, { children: [step.warnings.length > 0 && (_jsxs("div", { className: "cs-export-warnings cs-ai-import-warnings", role: "alert", children: [_jsx("div", { className: "cs-export-warn-title", children: t('aiimport.check') }), step.warnings.map((w, i) => _jsxs("div", { className: "cs-export-warn-item", children: ["\u2022 ", w] }, i))] })), _jsxs("div", { className: "cs-ai-import-review", children: [_jsxs("section", { "aria-label": t('aiimport.source'), children: [_jsx("div", { className: "cs-ai-import-col-title", children: t('aiimport.source') }), _jsx("pre", { className: "cs-ai-import-source", children: step.source })] }), _jsxs("section", { "aria-label": t('aiimport.formatted').replace('{n}', String(step.blocks.length)), children: [_jsx("div", { className: "cs-ai-import-col-title", children: t('aiimport.formatted').replace('{n}', String(step.blocks.length)) }), _jsx("ol", { className: "cs-ai-import-blocks", children: step.blocks.map((block, i) => {
105
107
  const kind = blockKind(block);
106
- return (_jsxs("li", { className: "cs-ai-import-block", children: [_jsxs("select", { "aria-label": `Block ${i + 1} type`, className: "cs-settings-select", value: kind, onChange: e => {
108
+ return (_jsxs("li", { className: "cs-ai-import-block", children: [_jsxs("select", { "aria-label": t('aiimport.blockType').replace('{n}', String(i + 1)), className: "cs-settings-select", value: kind, onChange: e => {
107
109
  const blocks = [...step.blocks];
108
110
  blocks[i] = retypeBlock(block, e.target.value);
109
111
  setStep({ ...step, blocks });
110
- }, children: [kind === 'other' && _jsx("option", { value: "other", children: KIND_LABELS.other }), KIND_OPTIONS.map(k => _jsx("option", { value: k, children: KIND_LABELS[k] }, k))] }), _jsx("pre", { children: block })] }, i));
111
- }) })] })] }), _jsxs("div", { className: "cs-ai-import-actions", children: [_jsx("button", { type: "button", className: "cs-confirm-btn-cancel", onClick: close, children: "Cancel" }), _jsx("button", { type: "button", className: "cs-confirm-btn-cancel", onClick: () => finish('append'), disabled: !step.blocks.length, children: "Append to document" }), _jsx("button", { type: "button", className: "cs-confirm-btn-primary", title: "Replaces the script; the title page is kept", onClick: () => finish('replace'), disabled: !step.blocks.length, children: "Replace script" })] })] }))] })] }) }));
112
+ }, children: [kind === 'other' && _jsx("option", { value: "other", children: t(KIND_LABEL_KEYS.other) }), KIND_OPTIONS.map(k => _jsx("option", { value: k, children: t(KIND_LABEL_KEYS[k]) }, k))] }), _jsx("pre", { children: block })] }, i));
113
+ }) })] })] }), _jsxs("div", { className: "cs-ai-import-actions", children: [_jsx("button", { type: "button", className: "cs-confirm-btn-cancel", onClick: close, children: t('common.cancel') }), _jsx("button", { type: "button", className: "cs-confirm-btn-cancel", onClick: () => finish('append'), disabled: !step.blocks.length, children: t('aiimport.append') }), _jsx("button", { type: "button", className: "cs-confirm-btn-primary", title: t('aiimport.replaceTitle'), onClick: () => finish('replace'), disabled: !step.blocks.length, children: t('aiimport.replace') })] })] }))] })] }) }));
112
114
  }
@@ -52,10 +52,8 @@
52
52
  "lang.status.label": "ভাষা",
53
53
  "status.bar.lang": "কার্সারে ভাষা",
54
54
  "export.title": "রপ্তানি",
55
- "export.format": "ফরম্যাট",
56
55
  "export.fountainDesc": "স্ট্যান্ডার্ড Fountain ফরম্যাট — Final Draft, Highland ইত্যাদির সাথে সামঞ্জস্যপূর্ণ।",
57
56
  "export.sutraDesc": "Sutra উৎস — বর্তমান .sutra ফাইলের অনুলিপি।",
58
- "export.pdfNote": "Select a format below to export your screenplay or workflow data.",
59
57
  "export.warnings": "সতর্কবার্তা",
60
58
  "export.cancel": "বাতিল",
61
59
  "export.download": "ডাউনলোড",
@@ -63,16 +61,7 @@
63
61
  "settings.general": "সাধারণ",
64
62
  "settings.uiLanguage": "ইন্টারফেস ভাষা",
65
63
  "settings.close": "বন্ধ করুন",
66
- "export.screenplay": "Screenplay",
67
- "export.docxDesc": "Formatted Microsoft Word document (.docx)",
68
- "export.reports": "Workflow Reports",
69
- "export.onelinerPrint": "One-Liner Schedule (Print/PDF)",
70
- "export.onelinerDocx": "One-Liner Schedule (Word Table)",
71
- "export.onelinerCsv": "One-Liner Schedule (CSV)",
72
- "export.shotlistDocx": "Shot List (Word Table)",
73
- "export.shotlistCsv": "Shot List (CSV)",
74
- "export.castDocx": "Cast Report / Characters (Word Table)",
75
- "export.castCsv": "Cast Report / Characters (CSV)",
64
+ "export.docxDesc": "ফরম্যাট করা মাইক্রোসফট ওয়ার্ড নথি (.docx)",
76
65
  "appbar.style": "স্ক্রিনপ্লে শৈলী",
77
66
  "export.style": "শৈলী",
78
67
  "export.styleDefault": "ডকুমেন্ট ডিফল্ট",
@@ -147,5 +136,198 @@
147
136
  "statusbar.pagesTooltip": "আনুমানিক পৃষ্ঠা সংখ্যা (~1 মিনিট/পৃষ্ঠা)",
148
137
  "statusbar.wordsTooltip": "মোট শব্দ সংখ্যা",
149
138
  "statusbar.statsButton": "পরিসংখ্যান",
150
- "statusbar.statsTooltip": "চিত্রনাট্যের পরিসংখ্যান এবং কুশীলব দেখুন"
139
+ "statusbar.statsTooltip": "চিত্রনাট্যের পরিসংখ্যান এবং কুশীলব দেখুন",
140
+ "common.close": "বন্ধ করুন",
141
+ "export.pdfLabel": "PDF / প্রিন্ট প্রিভিউ",
142
+ "export.pdfDesc": "আপনার নির্বাচিত ভিজ্যুয়াল টেমপ্লেট অনুযায়ী প্রিন্টের জন্য প্রস্তুত, শিল্পমানের চিত্রনাট্য বিন্যাস।",
143
+ "export.docxLabel": "মাইক্রোসফট ওয়ার্ড (.docx)",
144
+ "export.fountainLabel": "Fountain (.fountain)",
145
+ "export.done.pdf": "চিত্রনাট্যের প্রিন্ট প্রিভিউ খোলা হয়েছে",
146
+ "export.done.docx": "ওয়ার্ড নথি (.docx) এক্সপোর্ট হয়েছে",
147
+ "export.done.fountain": "Fountain চিত্রনাট্য এক্সপোর্ট হয়েছে",
148
+ "export.done.oneliner.print": "ওয়ান-লাইনার সময়সূচি খোলা হয়েছে",
149
+ "export.done.oneliner.docx": "ওয়ান-লাইনার DOCX এক্সপোর্ট হয়েছে",
150
+ "export.done.oneliner.csv": "ওয়ান-লাইনার CSV এক্সপোর্ট হয়েছে",
151
+ "export.done.shotlist.docx": "শট লিস্ট DOCX এক্সপোর্ট হয়েছে",
152
+ "export.done.shotlist.csv": "শট লিস্ট CSV এক্সপোর্ট হয়েছে",
153
+ "export.done.cast.docx": "কাস্ট রিপোর্ট DOCX এক্সপোর্ট হয়েছে",
154
+ "export.done.cast.csv": "কাস্ট রিপোর্ট CSV এক্সপোর্ট হয়েছে",
155
+ "export.family.oneliner": "ওয়ান-লাইনার সময়সূচি",
156
+ "export.family.oneliner.desc": "লোকেশন, অভিনেতা ও সময়সহ দৃশ্যভিত্তিক প্রোডাকশন স্ট্রিপবোর্ড বিবরণ।",
157
+ "export.family.shotlist": "শট লিস্ট",
158
+ "export.family.shotlist.desc": "দৃশ্য শিরোনাম ও প্রোডাকশন নোট থেকে নেওয়া ক্যামেরা শটের বিবরণ।",
159
+ "export.family.cast": "কাস্ট ব্রেকডাউন",
160
+ "export.family.cast.desc": "চরিত্রের উপস্থিতি, সংলাপের সংখ্যা এবং নির্ধারিত অভিনেতাদের তালিকা।",
161
+ "export.format.print": "প্রিন্ট ভিউ",
162
+ "export.format.docx": "ওয়ার্ড (.docx)",
163
+ "export.format.csv": "স্প্রেডশিট (.csv)",
164
+ "export.category": "এক্সপোর্টের ধরন",
165
+ "export.tab.screenplay": "চিত্রনাট্য ফরম্যাট",
166
+ "export.tab.reports": "প্রোডাকশন রিপোর্ট",
167
+ "export.skipNotes": "নোট বাদ দিন ([[ ]])",
168
+ "export.romanized": "রোমান কপি (ISO 15919)",
169
+ "export.roman.off": "বন্ধ (মূল লিপি)",
170
+ "export.roman.all": "সমস্ত লেখা",
171
+ "export.roman.dialogue": "শুধু সংলাপ",
172
+ "export.roman.allReports": "সমস্ত লেখা রোমান করুন",
173
+ "export.roman.variant": "রোমানীকরণের ধরন",
174
+ "export.roman.strict": "কঠোর ISO 15919",
175
+ "export.roman.colloquial": "সাধারণ (ডায়াক্রিটিক ছাড়া)",
176
+ "export.roman.note": "আপনার স্ক্রিপ্ট বদলায় না। রোমান কপিতে পৃষ্ঠা সংখ্যা মূলের থেকে আলাদা হয়।",
177
+ "export.exporting": "এক্সপোর্ট হচ্ছে...",
178
+ "version.title": "সংস্করণের ইতিহাস",
179
+ "version.current": "বর্তমান",
180
+ "version.empty": "এখনও কোনো সংস্করণ সংরক্ষিত হয়নি",
181
+ "version.select": "বর্তমান নথির সাথে তুলনা করতে একটি সংস্করণ বেছে নিন",
182
+ "version.isCurrent": "এটি বর্তমান সংস্করণ",
183
+ "version.noDiff": "বর্তমান সংস্করণ থেকে কোনো পার্থক্য নেই",
184
+ "version.jumpAdded": "যোগ করা লেখায় যান",
185
+ "version.jumpRemoved": "মুছে ফেলা লেখায় যান",
186
+ "version.delete": "সংস্করণের ইতিহাস মুছুন",
187
+ "version.restore": "এই সংস্করণ পুনরুদ্ধার করুন",
188
+ "stats.title": "স্ক্রিপ্টের পরিসংখ্যান",
189
+ "stats.scenes": "দৃশ্য",
190
+ "stats.words": "শব্দ",
191
+ "stats.duration": "আনুমানিক সময়কাল",
192
+ "stats.cast": "অভিনেতা তালিকা ও উপস্থিতি",
193
+ "stats.noCharacters": "চিত্রনাট্যে এখনও কোনো চরিত্রের ইঙ্গিত পাওয়া যায়নি।",
194
+ "stats.character": "চরিত্র",
195
+ "stats.actor": "অভিনেতা",
196
+ "stats.assignActor": "অভিনেতা নির্ধারণ করুন...",
197
+ "stats.actorFor": "{name}-এর জন্য অভিনেতা",
198
+ "findreplace.prev": "আগের মিল",
199
+ "findreplace.prevTitle": "আগের মিল (Shift+Enter)",
200
+ "findreplace.next": "পরের মিল",
201
+ "findreplace.nextTitle": "পরের মিল (Enter)",
202
+ "findreplace.countOf": "{total} এর মধ্যে {current}",
203
+ "voice.title": "ফরম্যাটিং পর্যালোচনা করুন",
204
+ "voice.formatting": "সূত্র চিত্রনাট্য ফরম্যাটে রূপান্তর করা হচ্ছে...",
205
+ "voice.notice": "AI ফরম্যাটিং বিজ্ঞপ্তি: {error} (নিচে মূল ইনপুট দেখানো হচ্ছে)",
206
+ "voice.raw": "মূল বিষয়বস্তু",
207
+ "voice.formatted": "ফরম্যাট করা সূত্র",
208
+ "voice.autoInsert": "সবসময় সরাসরি চিত্রনাট্যে যোগ করুন (পর্যালোচনা এড়িয়ে যান)",
209
+ "voice.discard": "বাতিল করুন",
210
+ "voice.insert": "চিত্রনাট্যে যোগ করুন",
211
+ "selection.label": "লেখা নির্বাচনের কাজ",
212
+ "selection.format": "ফরম্যাট",
213
+ "selection.formatTitle": "নির্বাচিত লেখা AI দিয়ে ফরম্যাট করুন",
214
+ "selection.cut": "কাটুন",
215
+ "selection.copy": "কপি করুন",
216
+ "titlePage.placeholder.credit": "রচনা",
217
+ "titlePage.placeholder.draft": "প্রথম খসড়া",
218
+ "export.failed": "এক্সপোর্ট ব্যর্থ হয়েছে। বিস্তারিত জানতে কনসোল দেখুন।",
219
+ "export.exported": "{label} এক্সপোর্ট হয়েছে",
220
+ "common.cancel": "বাতিল",
221
+ "common.confirm": "নিশ্চিত করুন",
222
+ "appbar.voice": "ভয়েস ডিক্টেশন",
223
+ "appbar.hideMetadata": "মেটাডেটা লুকান",
224
+ "appbar.showMetadata": "মেটাডেটা দেখান",
225
+ "appbar.importAI": "AI দিয়ে ইমপোর্ট",
226
+ "appbar.menu": "মেনু",
227
+ "appbar.appMenu": "অ্যাপ্লিকেশন মেনু",
228
+ "appbar.closeMenu": "মেনু বন্ধ করুন",
229
+ "appbar.unsaved": "সংরক্ষণ না করা পরিবর্তন",
230
+ "appbar.viewsTools": "ভিউ ও টুলস",
231
+ "appbar.fileOps": "ফাইল অপারেশন",
232
+ "appbar.preferences": "পছন্দসমূহ",
233
+ "appbar.brandTitle": "সূত্রতা বহুভাষিক চিত্রনাট্য সম্পাদক",
234
+ "appbar.header": "অ্যাপ্লিকেশন হেডার",
235
+ "appbar.importFailed": "ওয়ার্ড নথি ইমপোর্ট করা যায়নি।",
236
+ "shell.sidebar": "সাইডবার",
237
+ "shell.inspector": "ইন্সপেক্টর",
238
+ "statusbar.label": "স্ট্যাটাস বার",
239
+ "tb.editing": "সম্পাদনা টুলবার",
240
+ "tb.more": "আরও",
241
+ "tb.sheetLabel": "চিত্রনাট্যের উপাদান ও ফরম্যাটিং",
242
+ "tb.sheetTitle": "ফরম্যাটিং ও উপাদান",
243
+ "tb.inline": "ইনলাইন ফরম্যাটিং",
244
+ "tb.elements": "চিত্রনাট্যের উপাদান",
245
+ "tb.active": "সক্রিয়",
246
+ "lang.tooltip": "কার্সারে লিপির ভাষা: {name} ({code})",
247
+ "lang.aria": "লিপির ভাষা: {name}",
248
+ "lang.menu": "লিপির ভাষাসমূহ",
249
+ "titlePage.pageLetter": "ইউএস লেটার",
250
+ "titlePage.placeholder.watermark": "গোপনীয়",
251
+ "titlePage.placeholder.key": "কী",
252
+ "navigator.stats": "পরিসংখ্যান",
253
+ "navigator.aria": "দৃশ্য নেভিগেটর",
254
+ "navigator.close": "নেভিগেটর বন্ধ করুন",
255
+ "navigator.jumpSection": "{heading} বিভাগে যান",
256
+ "navigator.jumpScene": "{heading}-এ যান",
257
+ "navigator.genAll": "সব দৃশ্যের সারসংক্ষেপ তৈরি করুন ও সময়কাল অনুমান করুন",
258
+ "navigator.genOne": "সারসংক্ষেপ তৈরি করুন ও সময়কাল অনুমান করুন",
259
+ "navigator.editSynopsis": "সারসংক্ষেপ সম্পাদনা করতে ক্লিক করুন",
260
+ "navigator.addSynopsis": "সারসংক্ষেপ যোগ করুন",
261
+ "navigator.duration": "আনুমানিক পর্দার সময়কাল",
262
+ "ai.unavailable": "{name} এখন উপলব্ধ নয়।",
263
+ "navigator.toast.aiSetup": "সারসংক্ষেপ ও সময়কাল তৈরি করতে AI সেটআপ করতে হবে। সেটআপ খোলা হচ্ছে...",
264
+ "navigator.toast.generatedOne": "দৃশ্য {scene}-এর সারসংক্ষেপ ও সময়কাল তৈরি হয়েছে।",
265
+ "navigator.toast.genFailed": "দৃশ্যের মেটাডেটা তৈরি ব্যর্থ হয়েছে: {error}",
266
+ "navigator.toast.allHave": "সব দৃশ্যে ইতিমধ্যে সারসংক্ষেপ ও সময়কাল আছে।",
267
+ "navigator.toast.generatedMany": "{count}টি দৃশ্যের সারসংক্ষেপ ও সময়কাল তৈরি হয়েছে।",
268
+ "navigator.toast.batchFailed": "ব্যাচ তৈরি ব্যর্থ হয়েছে: {error}",
269
+ "navigator.toast.inOrder": "দৃশ্য নম্বর ইতিমধ্যে ক্রমে আছে।",
270
+ "voice.toolbar.aria": "ভয়েস ডিক্টেশন টুলবার",
271
+ "voice.language": "ভয়েসের ভাষা",
272
+ "voice.wave": "অডিও তরঙ্গরূপ দৃশ্য",
273
+ "voice.stopFormat": "থামান ও ফরম্যাট করুন",
274
+ "voice.formattingBtn": "ফরম্যাট হচ্ছে...",
275
+ "voice.start": "ডিক্টেশন শুরু করুন",
276
+ "voice.reformat": "আবার ফরম্যাট করুন",
277
+ "voice.clear": "মুছুন",
278
+ "voice.speakNow": "এখন বলুন...",
279
+ "voice.editCaptured": "ফরম্যাট করার আগে ধারণ করা লেখা সম্পাদনা করুন...",
280
+ "voice.commands": "কমান্ড:",
281
+ "voice.notSupported": "এই ব্রাউজারে {name} সমর্থিত নয়।",
282
+ "voice.toast.setup": "বলা লেখা ফরম্যাট করতে AI সেটআপ করতে হবে। সেটআপ খোলা হচ্ছে...",
283
+ "voice.toast.inserted": "ভয়েস ডিক্টেশন যোগ হয়েছে।",
284
+ "voice.toast.formatted": "চিত্রনাট্য ফরম্যাট করে যোগ করা হয়েছে।",
285
+ "voice.toast.autoFailed": "অটো-ইনসার্ট ব্যর্থ হয়েছে: {error}। নিশ্চিতকরণ ডায়ালগ খোলা হচ্ছে।",
286
+ "aiimport.hint": "Word, টেক্সট ফাইল বা Markdown-এ লেখা চিত্রনাট্য ইমপোর্ট করুন। AI সেটিকে সূত্র হিসেবে ফরম্যাট করে; কিছু বদলানোর আগে আপনি ফলাফল পর্যালোচনা করেন। সূত্রতা থেকে এক্সপোর্ট করা Word ফাইল AI ছাড়াই সরাসরি ইমপোর্ট হয়।",
287
+ "aiimport.choose": "ইমপোর্টের জন্য ফাইল বেছে নিন",
288
+ "aiimport.paste": "…অথবা লেখা পেস্ট করুন",
289
+ "aiimport.continue": "চালিয়ে যান",
290
+ "aiimport.back": "পিছনে",
291
+ "aiimport.format": "AI দিয়ে ফরম্যাট করুন",
292
+ "aiimport.policy": "ডেটা নীতি",
293
+ "aiimport.summary": "{file} ({chars}টি অক্ষর) ফরম্যাট করার জন্য {name}-কে পাঠানো হবে।",
294
+ "aiimport.agree": "বুঝেছি, এই লেখা {name}-কে পাঠান",
295
+ "aiimport.progress": "অংশ {done}/{total} ফরম্যাট হচ্ছে…",
296
+ "aiimport.check": "ইমপোর্টের আগে এই অংশগুলো দেখে নিন",
297
+ "aiimport.part": "অংশ {n}: {problem}",
298
+ "aiimport.source": "উৎস",
299
+ "aiimport.formatted": "ফরম্যাট করা ({n}টি ব্লক)",
300
+ "aiimport.blockType": "ব্লক {n} এর ধরন",
301
+ "aiimport.append": "নথিতে যুক্ত করুন",
302
+ "aiimport.replace": "স্ক্রিপ্ট প্রতিস্থাপন করুন",
303
+ "aiimport.replaceTitle": "স্ক্রিপ্ট প্রতিস্থাপিত হবে; টাইটেল পেজ থাকবে",
304
+ "aiimport.imported": "{file} ইমপোর্ট হয়েছে ({n}টি ব্লক)।",
305
+ "aiimport.pastedText": "পেস্ট করা লেখা",
306
+ "aiimport.kind.character": "চরিত্র + সংলাপ",
307
+ "aiimport.kind.other": "অন্যান্য",
308
+ "doc.recovered": "আগের সেশনের সংরক্ষণ না করা পরিবর্তন পুনরুদ্ধার করা হয়েছে।",
309
+ "doc.autosaveFailed": "অটোসেভ ব্যর্থ — আপনার ব্রাউজারের স্টোরেজ পূর্ণ বা অনুপলব্ধ হতে পারে।",
310
+ "doc.discardTitle": "সংরক্ষণ না করা পরিবর্তন বাতিল করবেন?",
311
+ "doc.newMsg": "নতুন চিত্রনাট্য শুরু করলে বর্তমান নথির সংরক্ষণ না করা সব পরিবর্তন বাতিল হবে।",
312
+ "doc.newConfirm": "বাতিল করে নতুন তৈরি করুন",
313
+ "doc.openMsg": "অন্য চিত্রনাট্য খুললে বর্তমান নথির সংরক্ষণ না করা পরিবর্তন বাতিল হবে।",
314
+ "doc.openConfirm": "বাতিল করে খুলুন",
315
+ "doc.saved": "{name} সংরক্ষিত হয়েছে",
316
+ "doc.savedAs": "{name} নামে সংরক্ষিত হয়েছে",
317
+ "doc.importTitle": "ওয়ার্ড নথি ইমপোর্ট করুন",
318
+ "doc.importMsg": "বর্তমান চিত্রনাট্যের বিষয়বস্তু ইমপোর্ট করা ওয়ার্ড নথি দিয়ে প্রতিস্থাপন করবেন? এটি ফেরানো যাবে না।",
319
+ "doc.importConfirm": "চিত্রনাট্য প্রতিস্থাপন করুন",
320
+ "doc.imported": "ওয়ার্ড নথি সফলভাবে ইমপোর্ট হয়েছে",
321
+ "doc.versionRestored": "সংস্করণ পুনরুদ্ধার হয়েছে — সংরক্ষণ করতে ভুলবেন না।",
322
+ "doc.clearVersionsTitle": "সংস্করণের ইতিহাস মুছবেন?",
323
+ "doc.clearVersionsMsg": "{file}-এর সংরক্ষিত সব {count}টি সংস্করণ মুছবেন? এটি ফেরানো যাবে না।",
324
+ "doc.versionsCleared": "সংস্করণের ইতিহাস মুছে ফেলা হয়েছে",
325
+ "doc.versionsClearFailed": "সংস্করণের ইতিহাস মুছতে ব্যর্থ",
326
+ "doc.unsavedTitle": "সংরক্ষণ না করা পরিবর্তন",
327
+ "doc.unsavedMsg": "আপনার সংরক্ষণ না করা পরিবর্তন আছে। বন্ধ করার আগে সংরক্ষণ করবেন?",
328
+ "doc.saveClose": "সংরক্ষণ করে বন্ধ করুন",
329
+ "navigator.toast.renumberedOne": "{count}টি দৃশ্য পুনরায় নম্বর করা হয়েছে।",
330
+ "navigator.toast.renumberedMany": "{count}টি দৃশ্য পুনরায় নম্বর করা হয়েছে।",
331
+ "navigator.hideSynopsis": "সারসংক্ষেপ ও সময়কাল লুকান",
332
+ "navigator.showSynopsis": "সারসংক্ষেপ ও সময়কাল দেখান"
151
333
  }
@@ -53,23 +53,12 @@
53
53
  "lang.status.label": "Language",
54
54
  "status.bar.lang": "Language at cursor",
55
55
  "export.title": "Export",
56
- "export.format": "Format",
57
56
  "export.fountainDesc": "Standard Fountain format, compatible with Final Draft, Highland, and others.",
58
57
  "export.sutraDesc": "Sutra source — copy of the current .sutra file.",
59
- "export.pdfNote": "Select a format below to export your screenplay or workflow data.",
60
58
  "export.warnings": "Warnings",
61
59
  "export.cancel": "Cancel",
62
60
  "export.download": "Download",
63
- "export.screenplay": "Screenplay",
64
61
  "export.docxDesc": "Formatted Microsoft Word document (.docx)",
65
- "export.reports": "Workflow Reports",
66
- "export.onelinerPrint": "One-Liner Schedule (Print/PDF)",
67
- "export.onelinerDocx": "One-Liner Schedule (Word Table)",
68
- "export.onelinerCsv": "One-Liner Schedule (CSV)",
69
- "export.shotlistDocx": "Shot List (Word Table)",
70
- "export.shotlistCsv": "Shot List (CSV)",
71
- "export.castDocx": "Cast Report / Characters (Word Table)",
72
- "export.castCsv": "Cast Report / Characters (CSV)",
73
62
  "export.style": "Style",
74
63
  "export.styleDefault": "Document default",
75
64
  "settings.title": "Settings",
@@ -147,5 +136,198 @@
147
136
  "statusbar.pagesTooltip": "Estimated Page Count (~1 min/page)",
148
137
  "statusbar.wordsTooltip": "Total Word Count",
149
138
  "statusbar.statsButton": "Stats",
150
- "statusbar.statsTooltip": "View Screenplay Statistics & Cast"
139
+ "statusbar.statsTooltip": "View Screenplay Statistics & Cast",
140
+ "common.close": "Close",
141
+ "export.pdfLabel": "PDF / Print Preview",
142
+ "export.pdfDesc": "Print-ready industry screenplay layout styled according to your active visual template.",
143
+ "export.docxLabel": "Microsoft Word (.docx)",
144
+ "export.fountainLabel": "Fountain (.fountain)",
145
+ "export.done.pdf": "Opened Screenplay Print Preview",
146
+ "export.done.docx": "Exported Word document (.docx)",
147
+ "export.done.fountain": "Exported Fountain screenplay",
148
+ "export.done.oneliner.print": "Opened One-Liner Schedule",
149
+ "export.done.oneliner.docx": "Exported One-Liner DOCX",
150
+ "export.done.oneliner.csv": "Exported One-Liner CSV",
151
+ "export.done.shotlist.docx": "Exported Shot List DOCX",
152
+ "export.done.shotlist.csv": "Exported Shot List CSV",
153
+ "export.done.cast.docx": "Exported Cast Report DOCX",
154
+ "export.done.cast.csv": "Exported Cast Report CSV",
155
+ "export.family.oneliner": "One-Liner Schedule",
156
+ "export.family.oneliner.desc": "A scene-by-scene production stripboard breakdown with locations, cast, and timings.",
157
+ "export.family.shotlist": "Shot List",
158
+ "export.family.shotlist.desc": "Camera shot specifications extracted from scene headings and production notes.",
159
+ "export.family.cast": "Cast Breakdown",
160
+ "export.family.cast.desc": "Character occurrences, dialogue counts, and assigned actors list.",
161
+ "export.format.print": "Print View",
162
+ "export.format.docx": "Word (.docx)",
163
+ "export.format.csv": "Spreadsheet (.csv)",
164
+ "export.category": "Export category",
165
+ "export.tab.screenplay": "Screenplay Formats",
166
+ "export.tab.reports": "Production Reports",
167
+ "export.skipNotes": "Skip notes ([[ ]])",
168
+ "export.romanized": "Romanized copy (ISO 15919)",
169
+ "export.roman.off": "Off (native script)",
170
+ "export.roman.all": "All text",
171
+ "export.roman.dialogue": "Dialogue only",
172
+ "export.roman.allReports": "Romanize all text",
173
+ "export.roman.variant": "Romanization variant",
174
+ "export.roman.strict": "Strict ISO 15919",
175
+ "export.roman.colloquial": "Casual (no diacritics)",
176
+ "export.roman.note": "Your script is not changed. Page numbers in the romanized copy may differ from the original.",
177
+ "export.exporting": "Exporting...",
178
+ "version.title": "Version History",
179
+ "version.current": "Current",
180
+ "version.empty": "No versions saved yet",
181
+ "version.select": "Select a version to compare against the current document",
182
+ "version.isCurrent": "This is the current version",
183
+ "version.noDiff": "No differences from the current version",
184
+ "version.jumpAdded": "Jump to added text",
185
+ "version.jumpRemoved": "Jump to removed text",
186
+ "version.delete": "Delete Version History",
187
+ "version.restore": "Restore This Version",
188
+ "stats.title": "Script Statistics",
189
+ "stats.scenes": "Scenes",
190
+ "stats.words": "Words",
191
+ "stats.duration": "Est. Duration",
192
+ "stats.cast": "Cast List & Occurrences",
193
+ "stats.noCharacters": "No character cues detected in the screenplay yet.",
194
+ "stats.character": "Character",
195
+ "stats.actor": "Actor",
196
+ "stats.assignActor": "Assign actor...",
197
+ "stats.actorFor": "Actor for {name}",
198
+ "findreplace.prev": "Previous match",
199
+ "findreplace.prevTitle": "Previous match (Shift+Enter)",
200
+ "findreplace.next": "Next match",
201
+ "findreplace.nextTitle": "Next match (Enter)",
202
+ "findreplace.countOf": "{current} of {total}",
203
+ "voice.title": "Review Formatting",
204
+ "voice.formatting": "Formatting into Sutra screenplay format...",
205
+ "voice.notice": "AI formatting notice: {error} (showing raw input below)",
206
+ "voice.raw": "Raw Content",
207
+ "voice.formatted": "Formatted Sutra",
208
+ "voice.autoInsert": "Always auto-insert directly into screenplay (skip review)",
209
+ "voice.discard": "Discard",
210
+ "voice.insert": "Insert Into Screenplay",
211
+ "selection.label": "Text Selection Actions",
212
+ "selection.format": "Format",
213
+ "selection.formatTitle": "Format selected text using AI",
214
+ "selection.cut": "Cut",
215
+ "selection.copy": "Copy",
216
+ "titlePage.placeholder.credit": "Written by",
217
+ "titlePage.placeholder.draft": "First Draft",
218
+ "export.failed": "Export failed. Check console for details.",
219
+ "export.exported": "Exported {label}",
220
+ "common.cancel": "Cancel",
221
+ "common.confirm": "Confirm",
222
+ "appbar.voice": "Voice Dictation",
223
+ "appbar.hideMetadata": "Hide Metadata",
224
+ "appbar.showMetadata": "Show Metadata",
225
+ "appbar.importAI": "Import with AI",
226
+ "appbar.menu": "Menu",
227
+ "appbar.appMenu": "Application Menu",
228
+ "appbar.closeMenu": "Close menu",
229
+ "appbar.unsaved": "Unsaved edits",
230
+ "appbar.viewsTools": "Views & Tools",
231
+ "appbar.fileOps": "File Operations",
232
+ "appbar.preferences": "Preferences",
233
+ "appbar.brandTitle": "Sutrata Multilingual Screenplay Editor",
234
+ "appbar.header": "Application header",
235
+ "appbar.importFailed": "Failed to import the Word document.",
236
+ "shell.sidebar": "Sidebar",
237
+ "shell.inspector": "Inspector",
238
+ "statusbar.label": "Status bar",
239
+ "tb.editing": "Editing toolbar",
240
+ "tb.more": "More",
241
+ "tb.sheetLabel": "Screenplay Elements & Formatting",
242
+ "tb.sheetTitle": "Formatting & Elements",
243
+ "tb.inline": "Inline Formatting",
244
+ "tb.elements": "Screenplay Elements",
245
+ "tb.active": "Active",
246
+ "lang.tooltip": "Script language at caret: {name} ({code})",
247
+ "lang.aria": "Script language: {name}",
248
+ "lang.menu": "Script languages",
249
+ "titlePage.pageLetter": "US Letter",
250
+ "titlePage.placeholder.watermark": "CONFIDENTIAL",
251
+ "titlePage.placeholder.key": "key",
252
+ "navigator.stats": "Statistics",
253
+ "navigator.aria": "Scene Navigator",
254
+ "navigator.close": "Close navigator",
255
+ "navigator.jumpSection": "Jump to section {heading}",
256
+ "navigator.jumpScene": "Jump to {heading}",
257
+ "navigator.genAll": "Generate synopsis & estimate duration (all scenes)",
258
+ "navigator.genOne": "Generate synopsis & estimate duration",
259
+ "navigator.editSynopsis": "Click to edit synopsis",
260
+ "navigator.addSynopsis": "Add synopsis",
261
+ "navigator.duration": "Estimated Onscreen Duration",
262
+ "ai.unavailable": "{name} is not available right now.",
263
+ "navigator.toast.aiSetup": "AI must be set up to generate synopsis & duration. Opening Setup...",
264
+ "navigator.toast.generatedOne": "Generated synopsis & duration for scene {scene}.",
265
+ "navigator.toast.genFailed": "Scene metadata generation failed: {error}",
266
+ "navigator.toast.allHave": "All scenes already have synopsis and duration.",
267
+ "navigator.toast.generatedMany": "Generated synopsis & duration for {count} scenes.",
268
+ "navigator.toast.batchFailed": "Batch generation failed: {error}",
269
+ "navigator.toast.inOrder": "Scene numbers are already in order.",
270
+ "voice.toolbar.aria": "Voice Dictation Toolbar",
271
+ "voice.language": "Voice Language",
272
+ "voice.wave": "Audio waveform visualization",
273
+ "voice.stopFormat": "Stop & Format",
274
+ "voice.formattingBtn": "Formatting...",
275
+ "voice.start": "Start Dictation",
276
+ "voice.reformat": "Re-format",
277
+ "voice.clear": "Clear",
278
+ "voice.speakNow": "Speak now to dictate...",
279
+ "voice.editCaptured": "Edit captured text before formatting...",
280
+ "voice.commands": "Commands:",
281
+ "voice.notSupported": "{name} is not supported in this browser.",
282
+ "voice.toast.setup": "AI must be set up to format dictated text. Opening Setup...",
283
+ "voice.toast.inserted": "Voice dictation inserted.",
284
+ "voice.toast.formatted": "Screenplay formatted and inserted.",
285
+ "voice.toast.autoFailed": "Auto-insert failed: {error}. Opening confirmation dialog.",
286
+ "aiimport.hint": "Import a screenplay written in Word, a text file or Markdown. The AI formats it as Sutra; you review the result before anything changes. A Word file exported from Sutrata is imported directly, without AI.",
287
+ "aiimport.choose": "Choose a file to import",
288
+ "aiimport.paste": "…or paste the text",
289
+ "aiimport.continue": "Continue",
290
+ "aiimport.back": "Back",
291
+ "aiimport.format": "Format with AI",
292
+ "aiimport.policy": "Data policy",
293
+ "aiimport.summary": "{file} ({chars} characters) will be sent to {name} to be formatted.",
294
+ "aiimport.agree": "I understand, send this text to {name}",
295
+ "aiimport.progress": "Formatting part {done} of {total}…",
296
+ "aiimport.check": "Check these parts before importing",
297
+ "aiimport.part": "Part {n}: {problem}",
298
+ "aiimport.source": "Source",
299
+ "aiimport.formatted": "Formatted ({n} blocks)",
300
+ "aiimport.blockType": "Block {n} type",
301
+ "aiimport.append": "Append to document",
302
+ "aiimport.replace": "Replace script",
303
+ "aiimport.replaceTitle": "Replaces the script; the title page is kept",
304
+ "aiimport.imported": "Imported {file} ({n} blocks).",
305
+ "aiimport.pastedText": "pasted text",
306
+ "aiimport.kind.character": "Character + dialogue",
307
+ "aiimport.kind.other": "Other",
308
+ "doc.recovered": "Recovered unsaved changes from your last session.",
309
+ "doc.autosaveFailed": "Autosave failed — your browser storage may be full or unavailable.",
310
+ "doc.discardTitle": "Discard Unsaved Changes?",
311
+ "doc.newMsg": "Starting a new screenplay will discard all unsaved edits to your current document.",
312
+ "doc.newConfirm": "Discard & Create New",
313
+ "doc.openMsg": "Opening a different screenplay will discard any unsaved edits to your current document.",
314
+ "doc.openConfirm": "Discard & Open",
315
+ "doc.saved": "Saved {name}",
316
+ "doc.savedAs": "Saved as {name}",
317
+ "doc.importTitle": "Import Word Document",
318
+ "doc.importMsg": "Replace the current screenplay content with the imported Word document? This cannot be undone.",
319
+ "doc.importConfirm": "Replace Screenplay",
320
+ "doc.imported": "Word document imported successfully",
321
+ "doc.versionRestored": "Version restored — remember to save.",
322
+ "doc.clearVersionsTitle": "Delete Version History?",
323
+ "doc.clearVersionsMsg": "Delete all {count} saved versions of {file}? This cannot be undone.",
324
+ "doc.versionsCleared": "Version history cleared",
325
+ "doc.versionsClearFailed": "Failed to clear version history",
326
+ "doc.unsavedTitle": "Unsaved Changes",
327
+ "doc.unsavedMsg": "You have unsaved changes. Save them before closing?",
328
+ "doc.saveClose": "Save & Close",
329
+ "navigator.toast.renumberedOne": "Renumbered {count} scene.",
330
+ "navigator.toast.renumberedMany": "Renumbered {count} scenes.",
331
+ "navigator.hideSynopsis": "Hide Synopsis & Duration",
332
+ "navigator.showSynopsis": "Show Synopsis & Duration"
151
333
  }