@bendyline/docblocks-react 2.7.1 → 2.7.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/README.md +1 -1
  2. package/THIRD_PARTY_NOTICES.txt +98 -48
  3. package/dist/{ExportDialog-IMBVGRYG.js → ExportDialog-JRVZCG3J.js} +2 -2
  4. package/dist/{ExportToolbarControls-MUM6HM3K.js → ExportToolbarControls-2FEIHNMW.js} +15 -7
  5. package/dist/KeyboardShortcutsDialog-NOD4P25G.js +145 -0
  6. package/dist/{PresentationMaker-W2JIBHRN.js → PresentationMaker-ITNP5SDO.js} +1 -1
  7. package/dist/{Settings-DuXk6baH.d.ts → Settings-RDYvDDI0.d.ts} +13 -11
  8. package/dist/{SpeechToolbarControl-OSQS7NVY.js → SpeechToolbarControl-CLU7RB2G.js} +1 -1
  9. package/dist/{TextFromNarration-XYRAB6O2.js → TextFromNarration-NITJQ4IB.js} +1 -1
  10. package/dist/{WorkspaceSearchPanel-BKZJRPMY.js → WorkspaceSearchPanel-J6BKEZQJ.js} +1 -1
  11. package/dist/{chunk-UG4G7PJ4.js → chunk-5O5YTOXG.js} +1 -1
  12. package/dist/{chunk-VO2JYYQZ.js → chunk-6JJOGV6M.js} +5 -13
  13. package/dist/{chunk-X437UAF7.js → chunk-6MSHXQNB.js} +7 -2
  14. package/dist/{chunk-W55E6TE2.js → chunk-BLUEZG7T.js} +27 -22
  15. package/dist/chunk-DICE7VBJ.js +77 -0
  16. package/dist/{chunk-BCQZTWE5.js → chunk-HRWEGPTY.js} +18 -4
  17. package/dist/chunk-K7XJDJUJ.js +126 -0
  18. package/dist/{chunk-EPOLZNFD.js → chunk-SSB43524.js} +164 -69
  19. package/dist/{chunk-G4MFB3IO.js → chunk-VG434562.js} +2 -70
  20. package/dist/{chunk-BD54Z5XP.js → chunk-Y5OE3HJC.js} +4 -3
  21. package/dist/editor.js +6 -4
  22. package/dist/export/index.d.ts +17 -6
  23. package/dist/export/index.js +4 -4
  24. package/dist/index.d.ts +24 -6
  25. package/dist/index.js +395 -196
  26. package/dist/run-export-CS3HRNAZ.js +13 -0
  27. package/dist/settings/index.d.ts +1 -1
  28. package/dist/settings/index.js +1 -1
  29. package/package.json +9 -8
  30. package/src/styles/docblocks.css +465 -266
  31. package/dist/chunk-EA4BO6E4.js +0 -73
  32. package/dist/run-export-47X5FTYZ.js +0 -11
package/dist/index.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import {
2
+ BackupIcon,
2
3
  FolderIcon,
3
4
  MoreIcon,
4
5
  NewFileIcon,
@@ -10,7 +11,7 @@ import {
10
11
  SortByNameIcon,
11
12
  SplitViewIcon,
12
13
  WorkspaceIcon
13
- } from "./chunk-EA4BO6E4.js";
14
+ } from "./chunk-DICE7VBJ.js";
14
15
  import {
15
16
  useConfirmDialog
16
17
  } from "./chunk-6B7G33D5.js";
@@ -50,13 +51,13 @@ import {
50
51
  } from "./chunk-KWG6UP5O.js";
51
52
  import {
52
53
  runExport
53
- } from "./chunk-BCQZTWE5.js";
54
+ } from "./chunk-HRWEGPTY.js";
54
55
  import {
55
56
  createImageSaveOutput
56
57
  } from "./chunk-UONFWKJ7.js";
57
58
  import {
58
59
  buildExportFilename
59
- } from "./chunk-UG4G7PJ4.js";
60
+ } from "./chunk-5O5YTOXG.js";
60
61
  import {
61
62
  createLocalProofingIgnoreStore
62
63
  } from "./chunk-DUKTAKB4.js";
@@ -86,28 +87,30 @@ import {
86
87
  saveProofingPreferences,
87
88
  saveThemePreference,
88
89
  saveWriteCanvasPreferences
89
- } from "./chunk-W55E6TE2.js";
90
+ } from "./chunk-BLUEZG7T.js";
90
91
  import {
91
92
  FindButton,
92
- findShortcutLabel,
93
93
  focusFindInput,
94
- isApplePlatform,
95
- matchShortcut,
96
94
  pickEmptyDocumentPrompt,
97
- shortcutLabel,
98
95
  useResponsivePreviewViewportPreset
99
- } from "./chunk-G4MFB3IO.js";
100
- import "./chunk-EPOLZNFD.js";
96
+ } from "./chunk-VG434562.js";
97
+ import {
98
+ findShortcutLabel,
99
+ isApplePlatform,
100
+ matchShortcut,
101
+ shortcutLabel
102
+ } from "./chunk-K7XJDJUJ.js";
103
+ import "./chunk-SSB43524.js";
101
104
  import "./chunk-NAH52736.js";
102
105
  import "./chunk-K4I3NJFL.js";
103
106
  import {
104
107
  ExportDialog
105
- } from "./chunk-BD54Z5XP.js";
108
+ } from "./chunk-Y5OE3HJC.js";
106
109
  import "./chunk-YBEYTVU2.js";
107
110
  import {
108
111
  DEFAULT_OPTIONS,
109
112
  loadLastExportOptions
110
- } from "./chunk-X437UAF7.js";
113
+ } from "./chunk-6MSHXQNB.js";
111
114
  import {
112
115
  Dialog,
113
116
  dismissTopmostDialog
@@ -1765,8 +1768,19 @@ import {
1765
1768
  } from "@bendyline/docblocks/workspace-settings";
1766
1769
  var UPDATE_FROM_MARKDOWN_KEY = "squisq-updatefrommarkdown";
1767
1770
  var HTML_OUTPUT_KEY = "squisq-html-output";
1771
+ var pdfWorkerSrc = null;
1772
+ var configuredPdfWorkerSrc = null;
1773
+ function setOutsideInPdfWorker(src) {
1774
+ pdfWorkerSrc = src ?? null;
1775
+ }
1768
1776
  async function loadOutsideInModule() {
1769
- return await import("@bendyline/squisq-formats/outside-in");
1777
+ const outsideIn = await import("@bendyline/squisq-formats/outside-in");
1778
+ if (pdfWorkerSrc && pdfWorkerSrc !== configuredPdfWorkerSrc) {
1779
+ const { configurePdfWorker } = await import("@bendyline/squisq-formats/pdf");
1780
+ configurePdfWorker(pdfWorkerSrc);
1781
+ configuredPdfWorkerSrc = pdfWorkerSrc;
1782
+ }
1783
+ return outsideIn;
1770
1784
  }
1771
1785
  async function readOutsideInMetadata(source) {
1772
1786
  const { readOutsideInMetadata: readMetadata } = await loadOutsideInModule();
@@ -2357,6 +2371,17 @@ function newFileName(name, format) {
2357
2371
  const stem = name.trim().replace(SELECTABLE_FILE_EXTENSION, "");
2358
2372
  return stem ? `${stem}${NEW_FILE_EXTENSIONS[format]}` : null;
2359
2373
  }
2374
+ var SAVED_AS = {
2375
+ docx: "Word document",
2376
+ xlsx: "Excel workbook",
2377
+ pdf: "PDF",
2378
+ "web-interactive": "web page",
2379
+ "web-static": "web page"
2380
+ };
2381
+ function newFileFormatHint(format) {
2382
+ if (format === "markdown") return null;
2383
+ return `You write in Markdown; each save updates the ${SAVED_AS[format]}.`;
2384
+ }
2360
2385
  function newFileHtmlOutput(format) {
2361
2386
  if (format === "web-static") return "static";
2362
2387
  if (format === "web-interactive") return "interactive";
@@ -2367,13 +2392,11 @@ function newFileHtmlOutput(format) {
2367
2392
  import { Fragment as Fragment2, jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
2368
2393
  function NewFileFormatOptions() {
2369
2394
  return /* @__PURE__ */ jsxs3(Fragment2, { children: [
2370
- /* @__PURE__ */ jsxs3("optgroup", { label: "Document", children: [
2371
- /* @__PURE__ */ jsx4("option", { value: "markdown", children: "Markdown (.md)" }),
2395
+ /* @__PURE__ */ jsx4("option", { value: "markdown", children: "Markdown (.md)" }),
2396
+ /* @__PURE__ */ jsxs3("optgroup", { label: "Written in Markdown, saved as", children: [
2372
2397
  /* @__PURE__ */ jsx4("option", { value: "docx", children: "Word document (.docx)" }),
2373
2398
  /* @__PURE__ */ jsx4("option", { value: "xlsx", children: "Excel workbook (.xlsx)" }),
2374
- /* @__PURE__ */ jsx4("option", { value: "pdf", children: "PDF document (.pdf)" })
2375
- ] }),
2376
- /* @__PURE__ */ jsxs3("optgroup", { label: "Web page", children: [
2399
+ /* @__PURE__ */ jsx4("option", { value: "pdf", children: "PDF (.pdf)" }),
2377
2400
  /* @__PURE__ */ jsx4("option", { value: "web-interactive", children: "Web page \u2014 Interactive (.html)" }),
2378
2401
  /* @__PURE__ */ jsx4("option", { value: "web-static", children: "Web page \u2014 Static (.html)" })
2379
2402
  ] })
@@ -2384,6 +2407,7 @@ function NewFileFormatOptions() {
2384
2407
  import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
2385
2408
  var INTERNAL_DRAG_TYPE = "application/x-docblocks-entry";
2386
2409
  var NEW_ITEM_ERROR_ID = "db-new-item-error";
2410
+ var NEW_ITEM_HINT_ID = "db-new-item-hint";
2387
2411
  function normalisePath2(path) {
2388
2412
  return parseWorkspacePath4(path);
2389
2413
  }
@@ -3105,6 +3129,7 @@ function FileExplorer({
3105
3129
  {
3106
3130
  className: "db-new-item-format",
3107
3131
  "aria-label": "New file type",
3132
+ "aria-describedby": newFileFormatHint(newFileFormat) ? NEW_ITEM_HINT_ID : void 0,
3108
3133
  value: newFileFormat,
3109
3134
  disabled: newItemCreationPending,
3110
3135
  onChange: (event) => {
@@ -3119,6 +3144,7 @@ function FileExplorer({
3119
3144
  ]
3120
3145
  }
3121
3146
  ),
3147
+ newItemType === "file" && newFileFormatHint(newFileFormat) && /* @__PURE__ */ jsx5("p", { id: NEW_ITEM_HINT_ID, className: "db-new-item-hint", children: newFileFormatHint(newFileFormat) }),
3122
3148
  newItemError && /* @__PURE__ */ jsx5("div", { id: NEW_ITEM_ERROR_ID, className: "db-tree-error", role: "alert", children: newItemError })
3123
3149
  ] }),
3124
3150
  moveError && /* @__PURE__ */ jsx5("div", { className: "db-tree-error", role: "alert", children: moveError }),
@@ -3636,7 +3662,16 @@ async function prepareHostLifecycle(session, request) {
3636
3662
  }
3637
3663
 
3638
3664
  // src/DocBlocksShell/DocBlocksShell.tsx
3639
- import { useState as useState23, useCallback as useCallback18, useEffect as useEffect29, useRef as useRef19, useMemo as useMemo6, lazy as lazy2, Suspense as Suspense2 } from "react";
3665
+ import {
3666
+ useState as useState23,
3667
+ useCallback as useCallback18,
3668
+ useEffect as useEffect29,
3669
+ useLayoutEffect as useLayoutEffect4,
3670
+ useRef as useRef19,
3671
+ useMemo as useMemo6,
3672
+ lazy as lazy2,
3673
+ Suspense as Suspense2
3674
+ } from "react";
3640
3675
  import {
3641
3676
  DocumentVersionManager
3642
3677
  } from "@bendyline/squisq/versions";
@@ -3703,6 +3738,14 @@ function readinessSentence(readiness, ready) {
3703
3738
  return readiness.state === "ready" ? ready : readiness.reason ?? "";
3704
3739
  }
3705
3740
  var PREVIEW_TEXT = "This is how I sound when I read your documents aloud.";
3741
+ function unreachable(cause) {
3742
+ const detail = cause instanceof Error ? cause.message : void 0;
3743
+ return {
3744
+ code: "unknown",
3745
+ message: "DocBlocks could not check speech on this computer.",
3746
+ ...detail ? { detail } : {}
3747
+ };
3748
+ }
3706
3749
  function SpeechSettingsControls({ speech }) {
3707
3750
  const [status, setStatus] = useState6(null);
3708
3751
  const [catalog, setCatalog] = useState6(null);
@@ -3717,11 +3760,15 @@ function SpeechSettingsControls({ speech }) {
3717
3760
  const voiceId = useId2();
3718
3761
  const speedId = useId2();
3719
3762
  const refresh = useCallback7(async () => {
3720
- const [nextStatus, nextCatalog] = await Promise.all([speech.status(), speech.catalog()]);
3721
- if (!mounted.current) return;
3722
- setStatus(nextStatus);
3723
- if (nextCatalog.ok) setCatalog(nextCatalog.value);
3724
- else setFailure(nextCatalog.error);
3763
+ try {
3764
+ const [nextStatus, nextCatalog] = await Promise.all([speech.status(), speech.catalog()]);
3765
+ if (!mounted.current) return;
3766
+ setStatus(nextStatus);
3767
+ if (nextCatalog.ok) setCatalog(nextCatalog.value);
3768
+ else setFailure(nextCatalog.error);
3769
+ } catch (cause) {
3770
+ if (mounted.current) setFailure(unreachable(cause));
3771
+ }
3725
3772
  }, [speech]);
3726
3773
  const stopPreview = useCallback7(() => {
3727
3774
  preview.current?.handle.cancel();
@@ -3739,9 +3786,14 @@ function SpeechSettingsControls({ speech }) {
3739
3786
  });
3740
3787
  });
3741
3788
  void refresh();
3742
- void speech.getPreferences().then((initial) => {
3743
- if (mounted.current) setPreferences(initial);
3744
- });
3789
+ void speech.getPreferences().then(
3790
+ (initial) => {
3791
+ if (mounted.current) setPreferences(initial);
3792
+ },
3793
+ (cause) => {
3794
+ if (mounted.current) setFailure(unreachable(cause));
3795
+ }
3796
+ );
3745
3797
  return () => {
3746
3798
  mounted.current = false;
3747
3799
  installHandle.current?.cancel();
@@ -3813,7 +3865,13 @@ function SpeechSettingsControls({ speech }) {
3813
3865
  setPreviewing(false);
3814
3866
  });
3815
3867
  }, [speech, stopPreview]);
3816
- if (!status || !catalog || !preferences) return null;
3868
+ if (!status || !catalog || !preferences) {
3869
+ if (!failure) return null;
3870
+ return /* @__PURE__ */ jsxs6("fieldset", { className: "db-settings-fieldset", children: [
3871
+ /* @__PURE__ */ jsx7("legend", { className: "db-settings-legend", children: "Speech" }),
3872
+ /* @__PURE__ */ jsx7("p", { className: "db-settings-hint db-settings-ai-error", role: "alert", children: failure.message })
3873
+ ] });
3874
+ }
3817
3875
  const sttModels = catalog.models.filter((model) => model.kind === "stt");
3818
3876
  const ttsModel = catalog.models.find((model) => model.kind === "tts") ?? null;
3819
3877
  const installedStt = sttModels.filter((model) => model.installed);
@@ -3976,6 +4034,17 @@ function SpeechSettingsControls({ speech }) {
3976
4034
  ] });
3977
4035
  }
3978
4036
 
4037
+ // src/local-date.ts
4038
+ function localDateStamp(date) {
4039
+ const pad = (value) => String(value).padStart(2, "0");
4040
+ return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}`;
4041
+ }
4042
+ function displayBuildDate(value) {
4043
+ if (/^\d{4}-\d{2}-\d{2}$/.test(value)) return value;
4044
+ const instant = new Date(value);
4045
+ return Number.isNaN(instant.getTime()) ? value : localDateStamp(instant);
4046
+ }
4047
+
3979
4048
  // src/AppMenu/AppMenu.tsx
3980
4049
  import { Fragment as Fragment5, jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
3981
4050
  function formatBytes(bytes) {
@@ -3989,6 +4058,7 @@ function formatBytes(bytes) {
3989
4058
  }
3990
4059
  return `${value >= 100 || unit === "B" ? Math.round(value) : value.toFixed(1)} ${unit}`;
3991
4060
  }
4061
+ var DOCUMENTATION_URL = "https://docblocks.com/docs/";
3992
4062
  var MORE_INFORMATION_URLS = Object.freeze({
3993
4063
  electron: "https://docblocks.com/desktop/",
3994
4064
  capacitor: "https://docblocks.com/web/",
@@ -3996,9 +4066,10 @@ var MORE_INFORMATION_URLS = Object.freeze({
3996
4066
  });
3997
4067
  function AppMenu({
3998
4068
  logoUrl,
4069
+ logoDarkUrl,
3999
4070
  themePreference = "auto",
4000
4071
  onThemeChange,
4001
- accentColor = "brown",
4072
+ accentColor = "rust",
4002
4073
  onAccentColorChange,
4003
4074
  interfaceFont = "system",
4004
4075
  onInterfaceFontChange,
@@ -4010,6 +4081,7 @@ function AppMenu({
4010
4081
  onVersioningPreferenceChange,
4011
4082
  onOpenWorkspaceSettings,
4012
4083
  onDownloadAllWorkspaces,
4084
+ onShowKeyboardShortcuts,
4013
4085
  onKeepBrowserData,
4014
4086
  onInstallApp,
4015
4087
  getStorageEstimate,
@@ -4082,16 +4154,28 @@ function AppMenu({
4082
4154
  "aria-expanded": isOpen,
4083
4155
  "aria-haspopup": "menu",
4084
4156
  children: [
4085
- logoUrl ? /* @__PURE__ */ jsx8(
4086
- "img",
4087
- {
4088
- src: logoUrl,
4089
- alt: "DocBlocks",
4090
- className: "db-app-menu-logo",
4091
- width: 1266,
4092
- height: 544
4093
- }
4094
- ) : /* @__PURE__ */ jsx8("span", { className: "db-app-menu-label", children: "docblocks" }),
4157
+ logoUrl ? /* @__PURE__ */ jsxs7(Fragment5, { children: [
4158
+ /* @__PURE__ */ jsx8(
4159
+ "img",
4160
+ {
4161
+ src: logoUrl,
4162
+ alt: "DocBlocks",
4163
+ className: `db-app-menu-logo ${logoDarkUrl ? "db-app-menu-logo--light" : "db-app-menu-logo--invert"}`,
4164
+ width: 557,
4165
+ height: 242
4166
+ }
4167
+ ),
4168
+ logoDarkUrl && /* @__PURE__ */ jsx8(
4169
+ "img",
4170
+ {
4171
+ src: logoDarkUrl,
4172
+ alt: "DocBlocks",
4173
+ className: "db-app-menu-logo db-app-menu-logo--dark",
4174
+ width: 557,
4175
+ height: 242
4176
+ }
4177
+ )
4178
+ ] }) : /* @__PURE__ */ jsx8("span", { className: "db-app-menu-label", children: "docblocks" }),
4095
4179
  /* @__PURE__ */ jsx8(
4096
4180
  "span",
4097
4181
  {
@@ -4130,6 +4214,17 @@ function AppMenu({
4130
4214
  children: "Install DocBlocks\u2026"
4131
4215
  }
4132
4216
  ),
4217
+ (onDownloadAllWorkspaces || onKeepBrowserData) && /* @__PURE__ */ jsx8("div", { className: "db-app-menu-divider" }),
4218
+ onDownloadAllWorkspaces && /* @__PURE__ */ jsx8(
4219
+ "button",
4220
+ {
4221
+ className: "db-app-menu-item",
4222
+ role: "menuitem",
4223
+ tabIndex: -1,
4224
+ onClick: () => handleAction(() => void onDownloadAllWorkspaces()),
4225
+ children: "Back up all workspaces"
4226
+ }
4227
+ ),
4133
4228
  onKeepBrowserData && /* @__PURE__ */ jsx8(
4134
4229
  "button",
4135
4230
  {
@@ -4140,17 +4235,34 @@ function AppMenu({
4140
4235
  children: "Protect data from browser cleanup"
4141
4236
  }
4142
4237
  ),
4143
- onDownloadAllWorkspaces && /* @__PURE__ */ jsx8(
4238
+ /* @__PURE__ */ jsx8("div", { className: "db-app-menu-divider" }),
4239
+ onShowKeyboardShortcuts && /* @__PURE__ */ jsxs7(
4144
4240
  "button",
4241
+ {
4242
+ className: "db-app-menu-item db-app-menu-item--with-shortcut",
4243
+ role: "menuitem",
4244
+ tabIndex: -1,
4245
+ "aria-keyshortcuts": "F1",
4246
+ onClick: () => handleAction(onShowKeyboardShortcuts),
4247
+ children: [
4248
+ "Keyboard shortcuts",
4249
+ /* @__PURE__ */ jsx8("span", { className: "db-app-menu-shortcut", "aria-hidden": "true", children: "F1" })
4250
+ ]
4251
+ }
4252
+ ),
4253
+ /* @__PURE__ */ jsx8(
4254
+ "a",
4145
4255
  {
4146
4256
  className: "db-app-menu-item",
4147
4257
  role: "menuitem",
4148
4258
  tabIndex: -1,
4149
- onClick: () => handleAction(() => void onDownloadAllWorkspaces()),
4150
- children: "Download all workspaces"
4259
+ href: DOCUMENTATION_URL,
4260
+ target: "_blank",
4261
+ rel: "noopener noreferrer",
4262
+ onClick: () => closeMenu(false),
4263
+ children: "Documentation"
4151
4264
  }
4152
4265
  ),
4153
- /* @__PURE__ */ jsx8("div", { className: "db-app-menu-divider" }),
4154
4266
  /* @__PURE__ */ jsx8(
4155
4267
  "button",
4156
4268
  {
@@ -4310,7 +4422,7 @@ function AppMenu({
4310
4422
  ] }),
4311
4423
  appBuildDate && /* @__PURE__ */ jsxs7("p", { className: "db-about-version", children: [
4312
4424
  /* @__PURE__ */ jsx8("span", { children: "Build" }),
4313
- /* @__PURE__ */ jsx8("time", { dateTime: appBuildDate, children: appBuildDate })
4425
+ /* @__PURE__ */ jsx8("time", { dateTime: appBuildDate, children: displayBuildDate(appBuildDate) })
4314
4426
  ] }),
4315
4427
  /* @__PURE__ */ jsxs7("p", { children: [
4316
4428
  "Built with",
@@ -4453,7 +4565,7 @@ function WorkspaceSettingsButton({
4453
4565
  role: "menuitem",
4454
4566
  tabIndex: -1,
4455
4567
  onClick: () => handleAction(onDownload),
4456
- children: "Download workspace"
4568
+ children: "Back up this workspace"
4457
4569
  }
4458
4570
  ),
4459
4571
  /* @__PURE__ */ jsx9("div", { className: "db-ws-settings-divider" }),
@@ -4896,7 +5008,7 @@ function useDocumentSession(autoSaveDelayMs = 500) {
4896
5008
  import { lazy, Suspense } from "react";
4897
5009
  import { jsx as jsx12 } from "react/jsx-runtime";
4898
5010
  var ExportToolbarControlsImplementation = lazy(
4899
- () => import("./ExportToolbarControls-MUM6HM3K.js").then((module) => ({
5011
+ () => import("./ExportToolbarControls-2FEIHNMW.js").then((module) => ({
4900
5012
  default: module.ExportToolbarControls
4901
5013
  }))
4902
5014
  );
@@ -5547,14 +5659,34 @@ async function claimOutsideInTarget(provider, desiredPath) {
5547
5659
  }
5548
5660
  throw new Error(`Too many documents are already named like \u201C${desiredPath}\u201D.`);
5549
5661
  }
5662
+ function directoriesUnder(files, root) {
5663
+ const directories = /* @__PURE__ */ new Set();
5664
+ for (const file of files) {
5665
+ if (!file.startsWith(`${root}/`)) continue;
5666
+ for (let dir = file.slice(0, file.lastIndexOf("/")); dir.length >= root.length; ) {
5667
+ directories.add(dir);
5668
+ const slash = dir.lastIndexOf("/");
5669
+ if (slash < 0) break;
5670
+ dir = dir.slice(0, slash);
5671
+ }
5672
+ }
5673
+ return [...directories].sort((a, b) => b.split("/").length - a.split("/").length);
5674
+ }
5675
+ async function removeIfEmptyDirectory(provider, path) {
5676
+ const providerV2 = getFileSystemProviderV27(provider);
5677
+ if (!providerV2) return;
5678
+ await providerV2.remove(parseWorkspacePath6(path), { recursive: false, missing: "ignore" }).catch(() => void 0);
5679
+ }
5550
5680
  async function importOutsideInFile(file, provider) {
5551
5681
  const claim = await claimOutsideInTarget(provider, file.name);
5552
5682
  const created = [claim.path];
5683
+ const companionDirectory = resolveOutsideInLayout2(claim.path)?.companionDirectory ?? null;
5553
5684
  try {
5554
5685
  const sourceBytes = await file.arrayBuffer();
5555
5686
  const layout = resolveOutsideInLayout2(claim.path);
5556
5687
  if (!layout) throw new Error(`Outside-in editing does not support \u201C${claim.path}\u201D.`);
5557
- const imported = await (isOutsideInDataFormat(layout.format) ? importOutsideInDataSidecar({ data: sourceBytes, targetPath: claim.path }) : importOutsideInDocument({ data: sourceBytes, targetPath: claim.path }));
5688
+ const conversionBytes = sourceBytes.slice(0);
5689
+ const imported = await (isOutsideInDataFormat(layout.format) ? importOutsideInDataSidecar({ data: conversionBytes, targetPath: claim.path }) : importOutsideInDocument({ data: conversionBytes, targetPath: claim.path }));
5558
5690
  for (const entry of await imported.container.listFiles()) {
5559
5691
  if (/\.md$/i.test(entry.path)) continue;
5560
5692
  const data = await imported.container.readFile(entry.path);
@@ -5568,9 +5700,14 @@ async function importOutsideInFile(file, provider) {
5568
5700
  await writeProviderBytes(provider, claim.path, sourceBytes, "upsert");
5569
5701
  return claim;
5570
5702
  } catch (error) {
5571
- for (const path of created.reverse()) {
5703
+ for (const path of [...created].reverse()) {
5572
5704
  await removeProviderEntry(provider, path).catch(() => void 0);
5573
5705
  }
5706
+ if (companionDirectory) {
5707
+ for (const directory of directoriesUnder(created, companionDirectory)) {
5708
+ await removeIfEmptyDirectory(provider, directory);
5709
+ }
5710
+ }
5574
5711
  throw error;
5575
5712
  }
5576
5713
  }
@@ -5762,6 +5899,8 @@ function NewDocumentDialog({
5762
5899
  const inputRef = useRef15(null);
5763
5900
  const nameId = useId4();
5764
5901
  const formatId = useId4();
5902
+ const hintId = useId4();
5903
+ const hint = newFileFormatHint(format);
5765
5904
  const filename = newFileName(name, format);
5766
5905
  const cancel = useCallback15(() => onSettle(null), [onSettle]);
5767
5906
  const submit = useCallback15(() => {
@@ -5814,16 +5953,44 @@ function NewDocumentDialog({
5814
5953
  {
5815
5954
  id: formatId,
5816
5955
  className: "db-git-form-input",
5956
+ "aria-describedby": hint ? hintId : void 0,
5817
5957
  value: format,
5818
5958
  onChange: (e) => setFormat(e.target.value),
5819
5959
  children: /* @__PURE__ */ jsx14(NewFileFormatOptions, {})
5820
5960
  }
5821
- )
5961
+ ),
5962
+ hint && /* @__PURE__ */ jsx14("p", { id: hintId, className: "db-new-document-hint", children: hint })
5822
5963
  ] })
5823
5964
  }
5824
5965
  );
5825
5966
  }
5826
5967
 
5968
+ // src/DocBlocksShell/EditorErrorBoundary.tsx
5969
+ import { Component } from "react";
5970
+ import { jsx as jsx15, jsxs as jsxs13 } from "react/jsx-runtime";
5971
+ var EditorErrorBoundary = class extends Component {
5972
+ constructor() {
5973
+ super(...arguments);
5974
+ this.state = { error: null, resetKey: this.props.resetKey };
5975
+ }
5976
+ static getDerivedStateFromError(error) {
5977
+ return { error };
5978
+ }
5979
+ static getDerivedStateFromProps(props, state) {
5980
+ return props.resetKey === state.resetKey ? null : { error: null, resetKey: props.resetKey };
5981
+ }
5982
+ render() {
5983
+ const { error } = this.state;
5984
+ if (!error) return this.props.children;
5985
+ return /* @__PURE__ */ jsx15("div", { className: "db-shell-empty db-shell-empty--workspace", role: "alert", children: /* @__PURE__ */ jsxs13("div", { className: "db-workspace-empty-content", children: [
5986
+ /* @__PURE__ */ jsx15("h1", { children: "This document couldn\u2019t be displayed" }),
5987
+ /* @__PURE__ */ jsx15("p", { children: "The editor ran into a problem drawing it. The document itself is unaffected." }),
5988
+ /* @__PURE__ */ jsx15("div", { className: "db-workspace-empty-actions", children: /* @__PURE__ */ jsx15("button", { type: "button", onClick: () => this.setState({ error: null }), children: "Try again" }) }),
5989
+ /* @__PURE__ */ jsx15("p", { className: "db-workspace-empty-hint", children: error.message })
5990
+ ] }) });
5991
+ }
5992
+ };
5993
+
5827
5994
  // src/preferences/new-file-format.ts
5828
5995
  var STORAGE_KEY2 = "docblocks:lastNewFileFormat";
5829
5996
  var MAX_REMEMBERED_WORKSPACES = 200;
@@ -5899,7 +6066,7 @@ function buildIssueReportUrl(environment) {
5899
6066
  "",
5900
6067
  "## Environment",
5901
6068
  "",
5902
- `- Date: ${environment.reportedAt.toISOString().slice(0, 10)}`,
6069
+ `- Date: ${localDateStamp(environment.reportedAt)}`,
5903
6070
  `- DocBlocks: ${normalizeEnvironmentValue(environment.version, "unknown", VERSION_VALUE_LIMIT)}`,
5904
6071
  `- User agent: ${normalizeEnvironmentValue(
5905
6072
  environment.userAgent,
@@ -6317,11 +6484,11 @@ function useInterfaceFontAttribute(preference) {
6317
6484
  useEffect24(() => {
6318
6485
  if (typeof document === "undefined") return;
6319
6486
  const root = document.documentElement;
6320
- if (preference !== "fixed") {
6487
+ if (preference !== "system") {
6321
6488
  root.removeAttribute(INTERFACE_FONT_ATTRIBUTE);
6322
6489
  return;
6323
6490
  }
6324
- root.setAttribute(INTERFACE_FONT_ATTRIBUTE, "fixed");
6491
+ root.setAttribute(INTERFACE_FONT_ATTRIBUTE, "system");
6325
6492
  return () => root.removeAttribute(INTERFACE_FONT_ATTRIBUTE);
6326
6493
  }, [preference]);
6327
6494
  }
@@ -6510,7 +6677,7 @@ function useShellShortcuts(handlers, layoutMode) {
6510
6677
 
6511
6678
  // src/DocBlocksShell/UpdateAvailableNotice.tsx
6512
6679
  import { useState as useState21 } from "react";
6513
- import { Fragment as Fragment10, jsx as jsx15, jsxs as jsxs13 } from "react/jsx-runtime";
6680
+ import { Fragment as Fragment10, jsx as jsx16, jsxs as jsxs14 } from "react/jsx-runtime";
6514
6681
  var UPDATE_PROMPT_ID = "db-update-available-prompt";
6515
6682
  function UpdateAvailableNotice({
6516
6683
  available,
@@ -6522,8 +6689,8 @@ function UpdateAvailableNotice({
6522
6689
  const [applying, setApplying] = useState21(false);
6523
6690
  if (!available || !onApplyUpdate) return null;
6524
6691
  const promptVisible = promptOpen && !blocked;
6525
- return /* @__PURE__ */ jsxs13(Fragment10, { children: [
6526
- /* @__PURE__ */ jsx15(
6692
+ return /* @__PURE__ */ jsxs14(Fragment10, { children: [
6693
+ /* @__PURE__ */ jsx16(
6527
6694
  "button",
6528
6695
  {
6529
6696
  type: "button",
@@ -6537,16 +6704,16 @@ function UpdateAvailableNotice({
6537
6704
  children: "Update available"
6538
6705
  }
6539
6706
  ),
6540
- promptVisible && /* @__PURE__ */ jsxs13(
6707
+ promptVisible && /* @__PURE__ */ jsxs14(
6541
6708
  "div",
6542
6709
  {
6543
6710
  id: UPDATE_PROMPT_ID,
6544
6711
  className: `db-update-banner${statusBarVisible ? "" : " db-update-banner--floating"}`,
6545
6712
  role: "alert",
6546
6713
  children: [
6547
- /* @__PURE__ */ jsx15("span", { children: "A new version of DocBlocks is available. Reload to update the editor and site pages." }),
6548
- /* @__PURE__ */ jsxs13("div", { className: "db-update-banner-actions", children: [
6549
- /* @__PURE__ */ jsx15(
6714
+ /* @__PURE__ */ jsx16("span", { children: "A new version of DocBlocks is available. Reload to update the editor and site pages." }),
6715
+ /* @__PURE__ */ jsxs14("div", { className: "db-update-banner-actions", children: [
6716
+ /* @__PURE__ */ jsx16(
6550
6717
  "button",
6551
6718
  {
6552
6719
  type: "button",
@@ -6558,7 +6725,7 @@ function UpdateAvailableNotice({
6558
6725
  children: applying ? "Updating\u2026" : "Reload"
6559
6726
  }
6560
6727
  ),
6561
- /* @__PURE__ */ jsx15("button", { type: "button", onClick: () => setPromptOpen(false), disabled: applying, children: "Later" })
6728
+ /* @__PURE__ */ jsx16("button", { type: "button", onClick: () => setPromptOpen(false), disabled: applying, children: "Later" })
6562
6729
  ] })
6563
6730
  ]
6564
6731
  }
@@ -6980,7 +7147,7 @@ var WELCOME_DOCUMENT_CONTENT = [
6980
7147
  "- Open DocBlocks in your browser and start in a browser workspace. In supported browsers, you can also open a local folder.",
6981
7148
  "- Choose **Install DocBlocks\u2026** in the app menu when offered. The installed web app keeps using the same browser storage.",
6982
7149
  "- Once the app has finished downloading for offline use, you can keep editing without a connection.",
6983
- "- Use **Download all workspaces** in the app menu to keep a backup before clearing browser data or moving to a new device.",
7150
+ "- Use **Back up all workspaces** in the app menu to keep a backup before clearing browser data or moving to a new device.",
6984
7151
  "",
6985
7152
  "## Work inside VS Code {[content]}",
6986
7153
  "",
@@ -7069,7 +7236,7 @@ var WELCOME_DOCUMENT_CONTENT = [
7069
7236
  ].join("\n");
7070
7237
 
7071
7238
  // src/DocBlocksShell/DocBlocksShell.tsx
7072
- import { Fragment as Fragment11, jsx as jsx16, jsxs as jsxs14 } from "react/jsx-runtime";
7239
+ import { Fragment as Fragment11, jsx as jsx17, jsxs as jsxs15 } from "react/jsx-runtime";
7073
7240
  var editorShellModulePromise = null;
7074
7241
  function loadEditorShell() {
7075
7242
  editorShellModulePromise ?? (editorShellModulePromise = (async () => {
@@ -7086,8 +7253,11 @@ var GitUI = lazy2(() => import("./GitUI-RCWUZVS6.js").then((m) => ({ default: m.
7086
7253
  var QuickOpenDialog = lazy2(
7087
7254
  () => import("./QuickOpenDialog-2KK4SEBU.js").then((m) => ({ default: m.QuickOpenDialog }))
7088
7255
  );
7256
+ var KeyboardShortcutsDialog = lazy2(
7257
+ () => import("./KeyboardShortcutsDialog-NOD4P25G.js").then((m) => ({ default: m.KeyboardShortcutsDialog }))
7258
+ );
7089
7259
  var WorkspaceSearchPanel = lazy2(
7090
- () => import("./WorkspaceSearchPanel-BKZJRPMY.js").then((m) => ({
7260
+ () => import("./WorkspaceSearchPanel-J6BKEZQJ.js").then((m) => ({
7091
7261
  default: m.WorkspaceSearchPanel
7092
7262
  }))
7093
7263
  );
@@ -7103,7 +7273,7 @@ var AiToolbarControl = lazy2(
7103
7273
  }))
7104
7274
  );
7105
7275
  var PresentationMaker = lazy2(
7106
- () => import("./PresentationMaker-W2JIBHRN.js").then((module) => ({
7276
+ () => import("./PresentationMaker-ITNP5SDO.js").then((module) => ({
7107
7277
  default: module.PresentationMaker
7108
7278
  }))
7109
7279
  );
@@ -7118,23 +7288,24 @@ var AiIllustratePanel = lazy2(
7118
7288
  }))
7119
7289
  );
7120
7290
  var TextFromNarration = lazy2(
7121
- () => import("./TextFromNarration-XYRAB6O2.js").then((module) => ({
7291
+ () => import("./TextFromNarration-NITJQ4IB.js").then((module) => ({
7122
7292
  default: module.TextFromNarration
7123
7293
  }))
7124
7294
  );
7125
7295
  var SpeechToolbarControl = lazy2(
7126
- () => import("./SpeechToolbarControl-OSQS7NVY.js").then((module) => ({
7296
+ () => import("./SpeechToolbarControl-CLU7RB2G.js").then((module) => ({
7127
7297
  default: module.SpeechToolbarControl
7128
7298
  }))
7129
7299
  );
7130
7300
  var SpeechMenuBridge = lazy2(
7131
- () => import("./SpeechToolbarControl-OSQS7NVY.js").then((module) => ({
7301
+ () => import("./SpeechToolbarControl-CLU7RB2G.js").then((module) => ({
7132
7302
  default: module.SpeechMenuBridge
7133
7303
  }))
7134
7304
  );
7135
7305
  var DOCBLOCKS_VIDEO_EXPORT_PALETTE = Object.freeze({
7136
7306
  overlay: "rgba(0, 0, 0, 0.72)",
7137
- surface: "var(--db-bg)",
7307
+ // A dialog floats over the chrome, so it takes the raised surface.
7308
+ surface: "var(--db-bg-raised)",
7138
7309
  control: "var(--db-bg-subtle)",
7139
7310
  border: "var(--db-border-strong)",
7140
7311
  text: "var(--db-text)",
@@ -7394,7 +7565,7 @@ async function createHostProviderFromWorkspace(ws) {
7394
7565
  var DESKTOP_TOOLBAR_WRAP_WIDTH = 900;
7395
7566
  var WEB_TOOLBAR_WRAP_WIDTH = 700;
7396
7567
  function FolderGlyph() {
7397
- return /* @__PURE__ */ jsx16(
7568
+ return /* @__PURE__ */ jsx17(
7398
7569
  "svg",
7399
7570
  {
7400
7571
  viewBox: "0 0 24 24",
@@ -7403,12 +7574,12 @@ function FolderGlyph() {
7403
7574
  strokeWidth: "1.5",
7404
7575
  strokeLinejoin: "round",
7405
7576
  "aria-hidden": "true",
7406
- children: /* @__PURE__ */ jsx16("path", { d: "M3 7a1 1 0 0 1 1-1h5l2 2h9a1 1 0 0 1 1 1v9a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V7z" })
7577
+ children: /* @__PURE__ */ jsx17("path", { d: "M3 7a1 1 0 0 1 1-1h5l2 2h9a1 1 0 0 1 1 1v9a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V7z" })
7407
7578
  }
7408
7579
  );
7409
7580
  }
7410
7581
  function FileGlyph() {
7411
- return /* @__PURE__ */ jsxs14(
7582
+ return /* @__PURE__ */ jsxs15(
7412
7583
  "svg",
7413
7584
  {
7414
7585
  viewBox: "0 0 24 24",
@@ -7418,14 +7589,14 @@ function FileGlyph() {
7418
7589
  strokeLinejoin: "round",
7419
7590
  "aria-hidden": "true",
7420
7591
  children: [
7421
- /* @__PURE__ */ jsx16("path", { d: "M6 3h8l5 5v12a1 1 0 0 1-1 1H6a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1z" }),
7422
- /* @__PURE__ */ jsx16("path", { d: "M14 3v5h5" })
7592
+ /* @__PURE__ */ jsx17("path", { d: "M6 3h8l5 5v12a1 1 0 0 1-1 1H6a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1z" }),
7593
+ /* @__PURE__ */ jsx17("path", { d: "M14 3v5h5" })
7423
7594
  ]
7424
7595
  }
7425
7596
  );
7426
7597
  }
7427
7598
  function CollapseSidebarGlyph() {
7428
- return /* @__PURE__ */ jsxs14(
7599
+ return /* @__PURE__ */ jsxs15(
7429
7600
  "svg",
7430
7601
  {
7431
7602
  viewBox: "0 0 64 64",
@@ -7436,9 +7607,9 @@ function CollapseSidebarGlyph() {
7436
7607
  strokeLinejoin: "round",
7437
7608
  "aria-hidden": "true",
7438
7609
  children: [
7439
- /* @__PURE__ */ jsx16("rect", { x: "7", y: "10", width: "50", height: "44", rx: "6" }),
7440
- /* @__PURE__ */ jsx16("path", { d: "M24 10v44" }),
7441
- /* @__PURE__ */ jsx16("path", { d: "m17 25-7 7 7 7" })
7610
+ /* @__PURE__ */ jsx17("rect", { x: "7", y: "10", width: "50", height: "44", rx: "6" }),
7611
+ /* @__PURE__ */ jsx17("path", { d: "M24 10v44" }),
7612
+ /* @__PURE__ */ jsx17("path", { d: "m17 25-7 7 7 7" })
7442
7613
  ]
7443
7614
  }
7444
7615
  );
@@ -7446,9 +7617,11 @@ function CollapseSidebarGlyph() {
7446
7617
  function DocBlocksShell({
7447
7618
  theme: hostTheme = "auto",
7448
7619
  logoUrl,
7620
+ logoDarkUrl,
7449
7621
  issueReportVersion,
7450
7622
  appBuildDate,
7451
7623
  ffmpegWasm,
7624
+ pdfWorkerSrc: pdfWorkerSrc2,
7452
7625
  calcEngineFactory,
7453
7626
  proofing,
7454
7627
  proofingDefaultEnabled,
@@ -7918,6 +8091,8 @@ function DocBlocksShell({
7918
8091
  const findShortcut = useMemo6(findShortcutLabel, []);
7919
8092
  const searchShortcut = useMemo6(() => shortcutLabel("workspace-search", isApplePlatform()), []);
7920
8093
  const [quickOpenOpen, setQuickOpenOpen] = useState23(false);
8094
+ const [shortcutsOpen, setShortcutsOpen] = useState23(false);
8095
+ const openKeyboardShortcuts = useCallback18(() => setShortcutsOpen(true), []);
7921
8096
  const [quickOpenFocusRequest, setQuickOpenFocusRequest] = useState23(0);
7922
8097
  const [sidebarView, setSidebarView] = useState23("files");
7923
8098
  const [searchMounted, setSearchMounted] = useState23(false);
@@ -8020,7 +8195,20 @@ function DocBlocksShell({
8020
8195
  [documentSnapshot.frozen, documentSnapshot.generation, documentSnapshot.targetKey]
8021
8196
  );
8022
8197
  const [editorPresentationEpoch, setEditorPresentationEpoch] = useState23(0);
8023
- const editorKey = `${documentSnapshot.generation}:${editorPresentationEpoch}`;
8198
+ const [editorGeneration, setEditorGeneration] = useState23(documentSnapshot.generation);
8199
+ useEffect29(() => {
8200
+ const sync = () => setEditorGeneration(documentSession.getSnapshot().generation);
8201
+ const unsubscribe = documentSession.subscribe(sync);
8202
+ sync();
8203
+ return () => {
8204
+ unsubscribe();
8205
+ };
8206
+ }, [documentSession]);
8207
+ const editorGenerationSettled = editorGeneration === documentSnapshot.generation;
8208
+ useEffect29(() => {
8209
+ setOutsideInPdfWorker(pdfWorkerSrc2);
8210
+ }, [pdfWorkerSrc2]);
8211
+ const editorKey = `${editorGeneration}:${editorPresentationEpoch}`;
8024
8212
  const editorPlaceholder = useMemo6(() => {
8025
8213
  void editorKey;
8026
8214
  return pickEmptyDocumentPrompt();
@@ -8230,6 +8418,8 @@ function DocBlocksShell({
8230
8418
  );
8231
8419
  const mediaContainerRef = useRef19(null);
8232
8420
  const [mediaProvider, setMediaProvider] = useState23(null);
8421
+ const [mediaProviderScope, setMediaProviderScope] = useState23(null);
8422
+ const mediaProviderCurrent = mediaProviderScope !== null && mediaProviderScope.provider === provider && mediaProviderScope.file === selectedFile && mediaProviderScope.outsideIn === selectedOutsideIn;
8233
8423
  const [mediaEpoch, setMediaEpoch] = useState23(0);
8234
8424
  const versionsContainerRef = useRef19(null);
8235
8425
  const [versionsContainer, setVersionsContainer] = useState23(null);
@@ -8824,14 +9014,16 @@ function DocBlocksShell({
8824
9014
  }).catch(() => {
8825
9015
  });
8826
9016
  }, [showBrowserStorageWarning, browserStoragePersistent, documentSnapshot.status]);
8827
- useEffect29(() => {
9017
+ useLayoutEffect4(() => {
8828
9018
  if (!provider || !selectedFile) {
8829
9019
  mediaContainerRef.current = null;
8830
9020
  versionsContainerRef.current = null;
8831
9021
  setMediaProvider(null);
9022
+ setMediaProviderScope(null);
8832
9023
  setVersionsContainer(null);
8833
9024
  return;
8834
9025
  }
9026
+ setMediaProviderScope({ provider, file: selectedFile, outsideIn: selectedOutsideIn });
8835
9027
  if (selectedOutsideIn) {
8836
9028
  const container2 = createOutsideInContentContainer(provider, selectedOutsideIn);
8837
9029
  const mp2 = createMediaProviderFromContainer(container2);
@@ -9688,6 +9880,7 @@ function DocBlocksShell({
9688
9880
  ...canBrowseWorkspace ? { "quick-open": openQuickOpen, "workspace-search": openWorkspaceSearch } : {},
9689
9881
  "new-document": () => void handleNewFile(),
9690
9882
  "new-folder": () => void handleNewFolder(),
9883
+ shortcuts: openKeyboardShortcuts,
9691
9884
  "toggle-sidebar": () => {
9692
9885
  if (singlePane) {
9693
9886
  setMobileShowEditor((showingEditor) => !showingEditor);
@@ -9723,6 +9916,7 @@ function DocBlocksShell({
9723
9916
  saveActiveDocument,
9724
9917
  handleNewFile,
9725
9918
  handleNewFolder,
9919
+ openKeyboardShortcuts,
9726
9920
  singlePane,
9727
9921
  mobileShowEditor,
9728
9922
  sidebarPreference,
@@ -10759,8 +10953,7 @@ function DocBlocksShell({
10759
10953
  const url = URL.createObjectURL(blob);
10760
10954
  const a = document.createElement("a");
10761
10955
  a.href = url;
10762
- const stamp = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
10763
- a.download = `docblocks-workspaces-${stamp}.zip`;
10956
+ a.download = `docblocks-workspaces-${localDateStamp(/* @__PURE__ */ new Date())}.zip`;
10764
10957
  a.click();
10765
10958
  URL.revokeObjectURL(url);
10766
10959
  if (skipped.length > 0) {
@@ -10780,7 +10973,7 @@ function DocBlocksShell({
10780
10973
  if (!storage || typeof storage.persist !== "function") {
10781
10974
  await acknowledge({
10782
10975
  title: "Persistent storage unavailable",
10783
- message: "This browser does not support persistent storage requests. Please back up browser docs frequently."
10976
+ message: "This browser does not support persistent storage requests. Use Back up all workspaces regularly."
10784
10977
  });
10785
10978
  return;
10786
10979
  }
@@ -10796,18 +10989,18 @@ function DocBlocksShell({
10796
10989
  setBrowserStoragePersistent(true);
10797
10990
  await acknowledge({
10798
10991
  title: "Storage will be kept for longer",
10799
- message: "This browser will try to keep DocBlocks data for longer. Please still back up browser docs frequently."
10992
+ message: "This browser will try to keep DocBlocks data for longer. Keep using Back up all workspaces regularly."
10800
10993
  });
10801
10994
  } else {
10802
10995
  await acknowledge({
10803
10996
  title: "Storage request declined",
10804
- message: "The browser did not grant permanent storage for DocBlocks. Please try again in a day or two. Meanwhile, please back up browser documents frequently."
10997
+ message: "The browser did not grant permanent storage for DocBlocks. Please try again in a day or two. Meanwhile, use Back up all workspaces regularly."
10805
10998
  });
10806
10999
  }
10807
11000
  } catch {
10808
11001
  await acknowledge({
10809
11002
  title: "Storage request failed",
10810
- message: "DocBlocks could not request persistent browser storage. Please back up browser docs frequently."
11003
+ message: "DocBlocks could not request persistent browser storage. Use Back up all workspaces regularly."
10811
11004
  });
10812
11005
  }
10813
11006
  }, [acknowledge, showToast]);
@@ -10917,7 +11110,7 @@ function DocBlocksShell({
10917
11110
  transitionAwayFromDocument
10918
11111
  ]
10919
11112
  );
10920
- return /* @__PURE__ */ jsx16(
11113
+ return /* @__PURE__ */ jsx17(
10921
11114
  "div",
10922
11115
  {
10923
11116
  ref: shellRef,
@@ -10926,10 +11119,10 @@ function DocBlocksShell({
10926
11119
  "data-accent": accentColor,
10927
11120
  "data-interface-font": interfaceFont === "fixed" ? "fixed" : void 0,
10928
11121
  "data-document-status": documentSnapshot.status,
10929
- children: /* @__PURE__ */ jsxs14(GitContext.Provider, { value: git, children: [
11122
+ children: /* @__PURE__ */ jsxs15(GitContext.Provider, { value: git, children: [
10930
11123
  promptDialog,
10931
11124
  confirmDialog,
10932
- quickOpenOpen && activeWorkspaceId && /* @__PURE__ */ jsx16(Suspense2, { fallback: null, children: /* @__PURE__ */ jsx16(
11125
+ quickOpenOpen && activeWorkspaceId && /* @__PURE__ */ jsx17(Suspense2, { fallback: null, children: /* @__PURE__ */ jsx17(
10933
11126
  QuickOpenDialog,
10934
11127
  {
10935
11128
  index: workspaceIndex.index,
@@ -10943,7 +11136,8 @@ function DocBlocksShell({
10943
11136
  onClose: () => setQuickOpenOpen(false)
10944
11137
  }
10945
11138
  ) }),
10946
- newDocumentDialogOpen && /* @__PURE__ */ jsx16(
11139
+ shortcutsOpen && /* @__PURE__ */ jsx17(Suspense2, { fallback: null, children: /* @__PURE__ */ jsx17(KeyboardShortcutsDialog, { onClose: () => setShortcutsOpen(false) }) }),
11140
+ newDocumentDialogOpen && /* @__PURE__ */ jsx17(
10947
11141
  NewDocumentDialog,
10948
11142
  {
10949
11143
  initialFormat: defaultNewFileFormat,
@@ -10953,8 +11147,8 @@ function DocBlocksShell({
10953
11147
  }
10954
11148
  }
10955
11149
  ),
10956
- workspaceStartupError && /* @__PURE__ */ jsx16("div", { className: "db-save-toast db-save-toast--error", role: "alert", "aria-live": "assertive", children: workspaceStartupError }),
10957
- saveToast && /* @__PURE__ */ jsx16(
11150
+ workspaceStartupError && /* @__PURE__ */ jsx17("div", { className: "db-save-toast db-save-toast--error", role: "alert", "aria-live": "assertive", children: workspaceStartupError }),
11151
+ saveToast && /* @__PURE__ */ jsx17(
10958
11152
  "div",
10959
11153
  {
10960
11154
  className: "db-save-toast db-save-toast--" + saveToast.kind,
@@ -10963,12 +11157,12 @@ function DocBlocksShell({
10963
11157
  children: saveToast.message
10964
11158
  }
10965
11159
  ),
10966
- offlineReadyToast && !saveToast && /* @__PURE__ */ jsx16("div", { className: "db-save-toast db-save-toast--success", role: "status", "aria-live": "polite", children: "DocBlocks is ready to work offline." }),
10967
- documentSnapshot.conflict && /* @__PURE__ */ jsxs14("div", { className: "db-document-conflict", role: "alert", children: [
10968
- /* @__PURE__ */ jsx16("span", { children: documentSnapshot.conflict.recoveredDraft ? "A recovery draft from a previous session differs from the saved file. The saved file may be newer. Choose which version to use." : "This document changed outside DocBlocks. Your unsaved version is still intact." }),
10969
- /* @__PURE__ */ jsx16("div", { className: "db-document-conflict-actions", children: /* @__PURE__ */ jsx16("button", { type: "button", onClick: () => setShowConflictComparison(true), children: "Compare versions" }) })
11160
+ offlineReadyToast && !saveToast && /* @__PURE__ */ jsx17("div", { className: "db-save-toast db-save-toast--success", role: "status", "aria-live": "polite", children: "DocBlocks is ready to work offline." }),
11161
+ documentSnapshot.conflict && /* @__PURE__ */ jsxs15("div", { className: "db-document-conflict", role: "alert", children: [
11162
+ /* @__PURE__ */ jsx17("span", { children: documentSnapshot.conflict.recoveredDraft ? "A recovery draft from a previous session differs from the saved file. The saved file may be newer. Choose which version to use." : "This document changed outside DocBlocks. Your unsaved version is still intact." }),
11163
+ /* @__PURE__ */ jsx17("div", { className: "db-document-conflict-actions", children: /* @__PURE__ */ jsx17("button", { type: "button", onClick: () => setShowConflictComparison(true), children: "Compare versions" }) })
10970
11164
  ] }),
10971
- documentSnapshot.conflict && showConflictComparison && /* @__PURE__ */ jsx16(Suspense2, { fallback: /* @__PURE__ */ jsx16("div", { role: "status", children: "Loading version comparison\u2026" }), children: /* @__PURE__ */ jsx16(
11165
+ documentSnapshot.conflict && showConflictComparison && /* @__PURE__ */ jsx17(Suspense2, { fallback: /* @__PURE__ */ jsx17("div", { role: "status", children: "Loading version comparison\u2026" }), children: /* @__PURE__ */ jsx17(
10972
11166
  DocumentConflictDialog,
10973
11167
  {
10974
11168
  conflict: documentSnapshot.conflict,
@@ -10978,14 +11172,14 @@ function DocBlocksShell({
10978
11172
  onClose: () => setShowConflictComparison(false)
10979
11173
  }
10980
11174
  ) }),
10981
- storageFull && !documentSnapshot.conflict && /* @__PURE__ */ jsxs14("div", { className: "db-storage-full-banner", role: "alert", children: [
10982
- /* @__PURE__ */ jsx16("span", { children: "Browser storage is full -- changes can\u2019t be saved. Free up space or back up your work now." }),
10983
- /* @__PURE__ */ jsxs14("div", { className: "db-storage-full-banner-actions", children: [
10984
- /* @__PURE__ */ jsx16("button", { type: "button", onClick: () => void handleDownloadAllWorkspaces(), children: "Download all workspaces" }),
10985
- /* @__PURE__ */ jsx16("button", { type: "button", onClick: () => setStorageFull(false), children: "Dismiss" })
11175
+ storageFull && !documentSnapshot.conflict && /* @__PURE__ */ jsxs15("div", { className: "db-storage-full-banner", role: "alert", children: [
11176
+ /* @__PURE__ */ jsx17("span", { children: "Browser storage is full -- changes can\u2019t be saved. Free up space or back up your work now." }),
11177
+ /* @__PURE__ */ jsxs15("div", { className: "db-storage-full-banner-actions", children: [
11178
+ /* @__PURE__ */ jsx17("button", { type: "button", onClick: () => void handleDownloadAllWorkspaces(), children: "Back up all workspaces" }),
11179
+ /* @__PURE__ */ jsx17("button", { type: "button", onClick: () => setStorageFull(false), children: "Dismiss" })
10986
11180
  ] })
10987
11181
  ] }),
10988
- workspaceSettingsOpen && activeWorkspaceDescriptor && /* @__PURE__ */ jsx16(
11182
+ workspaceSettingsOpen && activeWorkspaceDescriptor && /* @__PURE__ */ jsx17(
10989
11183
  WorkspaceSettingsDialog,
10990
11184
  {
10991
11185
  workspace: activeWorkspaceDescriptor,
@@ -10998,8 +11192,8 @@ function DocBlocksShell({
10998
11192
  onClose: () => setWorkspaceSettingsOpen(false)
10999
11193
  }
11000
11194
  ),
11001
- /* @__PURE__ */ jsxs14("div", { className: "db-shell-panes", ref: panesRef, children: [
11002
- /* @__PURE__ */ jsxs14(
11195
+ /* @__PURE__ */ jsxs15("div", { className: "db-shell-panes", ref: panesRef, children: [
11196
+ /* @__PURE__ */ jsxs15(
11003
11197
  "aside",
11004
11198
  {
11005
11199
  ref: sidebarRef,
@@ -11007,11 +11201,12 @@ function DocBlocksShell({
11007
11201
  "aria-label": "Workspace and files",
11008
11202
  style: singlePane ? void 0 : { width: `${sidebarWidth}px` },
11009
11203
  children: [
11010
- /* @__PURE__ */ jsxs14("div", { className: "db-shell-sidebar-header", children: [
11011
- /* @__PURE__ */ jsx16(
11204
+ /* @__PURE__ */ jsxs15("div", { className: "db-shell-sidebar-header", children: [
11205
+ /* @__PURE__ */ jsx17(
11012
11206
  AppMenu,
11013
11207
  {
11014
11208
  logoUrl,
11209
+ logoDarkUrl,
11015
11210
  themePreference,
11016
11211
  onThemeChange: handleThemeChange,
11017
11212
  accentColor,
@@ -11029,6 +11224,7 @@ function DocBlocksShell({
11029
11224
  onVersioningPreferenceChange: handleVersioningPreferenceChange,
11030
11225
  onOpenWorkspaceSettings: activeWorkspaceDescriptor ? handleOpenWorkspaceSettings : void 0,
11031
11226
  onDownloadAllWorkspaces: handleDownloadAllWorkspaces,
11227
+ onShowKeyboardShortcuts: singlePane ? void 0 : openKeyboardShortcuts,
11032
11228
  onKeepBrowserData: showBrowserStorageWarning && !browserStoragePersistent ? handleKeepBrowserData : void 0,
11033
11229
  onInstallApp: installPromptEvent ? handleInstallApp : void 0,
11034
11230
  getStorageEstimate: showBrowserStorageWarning ? getBrowserStorageEstimate : void 0,
@@ -11040,7 +11236,7 @@ function DocBlocksShell({
11040
11236
  settingsRequest
11041
11237
  }
11042
11238
  ),
11043
- /* @__PURE__ */ jsx16(
11239
+ /* @__PURE__ */ jsx17(
11044
11240
  WorkspacePicker,
11045
11241
  {
11046
11242
  activeWorkspaceId,
@@ -11051,7 +11247,7 @@ function DocBlocksShell({
11051
11247
  onRemoveWorkspace: (workspace) => void handleRemoveWorkspace(workspace.id)
11052
11248
  }
11053
11249
  ),
11054
- /* @__PURE__ */ jsx16(
11250
+ /* @__PURE__ */ jsx17(
11055
11251
  WorkspaceSettingsButton,
11056
11252
  {
11057
11253
  onSettings: handleOpenWorkspaceSettings,
@@ -11062,26 +11258,26 @@ function DocBlocksShell({
11062
11258
  }
11063
11259
  }
11064
11260
  ),
11065
- canRestoreSplitView && /* @__PURE__ */ jsx16(
11261
+ canRestoreSplitView && /* @__PURE__ */ jsx17(
11066
11262
  "button",
11067
11263
  {
11068
11264
  className: "db-restore-split",
11069
11265
  onClick: () => updateSidebarPreference("pinned"),
11070
11266
  "aria-label": "Restore split view",
11071
11267
  title: "Restore split view",
11072
- children: /* @__PURE__ */ jsx16(SplitViewIcon, {})
11268
+ children: /* @__PURE__ */ jsx17(SplitViewIcon, {})
11073
11269
  }
11074
11270
  ),
11075
- /* @__PURE__ */ jsx16("span", { className: "db-window-drag-grip", "aria-hidden": true })
11271
+ /* @__PURE__ */ jsx17("span", { className: "db-window-drag-grip", "aria-hidden": true })
11076
11272
  ] }),
11077
- git.available && /* @__PURE__ */ jsx16(Suspense2, { fallback: null, children: /* @__PURE__ */ jsx16(
11273
+ git.available && /* @__PURE__ */ jsx17(Suspense2, { fallback: null, children: /* @__PURE__ */ jsx17(
11078
11274
  GitUI,
11079
11275
  {
11080
11276
  onOpenFile: (path) => void handleSelect(path, "file"),
11081
11277
  onWorkspaceCloned: handleWorkspaceCloned
11082
11278
  }
11083
11279
  ) }),
11084
- /* @__PURE__ */ jsx16(
11280
+ /* @__PURE__ */ jsx17(
11085
11281
  FileExplorer,
11086
11282
  {
11087
11283
  className: sidebarView === "search" ? "db-sidebar-view--hidden" : void 0,
@@ -11115,7 +11311,7 @@ function DocBlocksShell({
11115
11311
  },
11116
11312
  explorerKey
11117
11313
  ),
11118
- searchMounted && /* @__PURE__ */ jsx16(Suspense2, { fallback: null, children: /* @__PURE__ */ jsx16(
11314
+ searchMounted && /* @__PURE__ */ jsx17(Suspense2, { fallback: null, children: /* @__PURE__ */ jsx17(
11119
11315
  WorkspaceSearchPanel,
11120
11316
  {
11121
11317
  index: workspaceIndex.index,
@@ -11126,12 +11322,12 @@ function DocBlocksShell({
11126
11322
  onShowFiles: () => setSidebarView("files")
11127
11323
  }
11128
11324
  ) }),
11129
- singlePane && showWelcomeGateway && /* @__PURE__ */ jsxs14("section", { className: "db-mobile-first-run", "aria-labelledby": "db-mobile-first-run-title", children: [
11130
- /* @__PURE__ */ jsx16("p", { className: "db-mobile-first-run-eyebrow", children: "Local-first Markdown editor" }),
11131
- /* @__PURE__ */ jsx16("h1", { id: "db-mobile-first-run-title", children: "Welcome to DocBlocks" }),
11132
- /* @__PURE__ */ jsx16("p", { children: "Write visually, keep plain Markdown underneath, and export the same document in useful formats. Keep your documents in the workspace you choose." }),
11133
- /* @__PURE__ */ jsxs14("div", { className: "db-mobile-first-run-actions", children: [
11134
- /* @__PURE__ */ jsx16(
11325
+ singlePane && showWelcomeGateway && /* @__PURE__ */ jsxs15("section", { className: "db-mobile-first-run", "aria-labelledby": "db-mobile-first-run-title", children: [
11326
+ /* @__PURE__ */ jsx17("p", { className: "db-mobile-first-run-eyebrow", children: "Local-first Markdown editor" }),
11327
+ /* @__PURE__ */ jsx17("h1", { id: "db-mobile-first-run-title", children: "Welcome to DocBlocks" }),
11328
+ /* @__PURE__ */ jsx17("p", { children: "Write visually, keep plain Markdown underneath, and export the same document in useful formats. Keep your documents in the workspace you choose." }),
11329
+ /* @__PURE__ */ jsxs15("div", { className: "db-mobile-first-run-actions", children: [
11330
+ /* @__PURE__ */ jsx17(
11135
11331
  "button",
11136
11332
  {
11137
11333
  type: "button",
@@ -11142,7 +11338,7 @@ function DocBlocksShell({
11142
11338
  children: "Tour the welcome document"
11143
11339
  }
11144
11340
  ),
11145
- /* @__PURE__ */ jsx16(
11341
+ /* @__PURE__ */ jsx17(
11146
11342
  "button",
11147
11343
  {
11148
11344
  type: "button",
@@ -11153,35 +11349,36 @@ function DocBlocksShell({
11153
11349
  )
11154
11350
  ] })
11155
11351
  ] }),
11156
- git.available && git.pendingGrant && /* @__PURE__ */ jsx16(Suspense2, { fallback: null, children: /* @__PURE__ */ jsx16(GitGrantNotice, {}) }),
11157
- /* @__PURE__ */ jsxs14("div", { className: "db-shell-sidebar-footer", children: [
11158
- /* @__PURE__ */ jsx16("a", { href: "https://docblocks.com/docs/", target: "_blank", rel: "noopener noreferrer", children: "Docs" }),
11159
- /* @__PURE__ */ jsx16("span", { className: "db-shell-sidebar-footer-separator", "aria-hidden": "true", children: "\u2022" }),
11160
- /* @__PURE__ */ jsx16("a", { href: "https://docblocks.com/terms/", target: "_blank", rel: "noopener noreferrer", children: "Terms" }),
11161
- /* @__PURE__ */ jsx16("span", { className: "db-shell-sidebar-footer-separator", "aria-hidden": "true", children: "\u2022" }),
11162
- /* @__PURE__ */ jsx16("a", { href: issueReportUrl, target: "_blank", rel: "noopener noreferrer", children: "Report issue" }),
11163
- showBrowserStorageWarning && /* @__PURE__ */ jsxs14(Fragment11, { children: [
11164
- /* @__PURE__ */ jsx16("span", { className: "db-shell-sidebar-footer-separator", "aria-hidden": "true", children: "\u2022" }),
11165
- /* @__PURE__ */ jsx16(
11166
- "button",
11167
- {
11168
- type: "button",
11169
- className: "db-shell-sidebar-footer-action",
11170
- onClick: () => void handleDownloadAllWorkspaces(),
11171
- title: "Browser documents can be removed automatically. Download all workspaces now.",
11172
- children: "Back up browser docs"
11173
- }
11174
- )
11175
- ] })
11352
+ git.available && git.pendingGrant && /* @__PURE__ */ jsx17(Suspense2, { fallback: null, children: /* @__PURE__ */ jsx17(GitGrantNotice, {}) }),
11353
+ /* @__PURE__ */ jsxs15("div", { className: "db-shell-sidebar-footer", children: [
11354
+ /* @__PURE__ */ jsx17("a", { href: "https://docblocks.com/docs/", target: "_blank", rel: "noopener noreferrer", children: "Docs" }),
11355
+ /* @__PURE__ */ jsx17("span", { className: "db-shell-sidebar-footer-separator", "aria-hidden": "true", children: "\u2022" }),
11356
+ /* @__PURE__ */ jsx17("a", { href: "https://docblocks.com/terms/", target: "_blank", rel: "noopener noreferrer", children: "Terms" }),
11357
+ /* @__PURE__ */ jsx17("span", { className: "db-shell-sidebar-footer-separator", "aria-hidden": "true", children: "\u2022" }),
11358
+ /* @__PURE__ */ jsx17("a", { href: issueReportUrl, target: "_blank", rel: "noopener noreferrer", children: "Report issue" }),
11359
+ showBrowserStorageWarning && /* @__PURE__ */ jsx17(Fragment11, { children: /* @__PURE__ */ jsxs15(
11360
+ "button",
11361
+ {
11362
+ type: "button",
11363
+ className: "db-shell-sidebar-footer-action",
11364
+ onClick: () => void handleDownloadAllWorkspaces(),
11365
+ "aria-label": "Back up all workspaces",
11366
+ title: "Browsers can clear site data. Download a backup of every workspace.",
11367
+ children: [
11368
+ /* @__PURE__ */ jsx17(BackupIcon, {}),
11369
+ "Back up"
11370
+ ]
11371
+ }
11372
+ ) })
11176
11373
  ] }),
11177
- /* @__PURE__ */ jsxs14("div", { className: "db-sidebar-collapse-preview", "aria-hidden": "true", children: [
11178
- /* @__PURE__ */ jsx16("span", { className: "db-sidebar-collapse-preview-icon", children: /* @__PURE__ */ jsx16(CollapseSidebarGlyph, {}) }),
11179
- /* @__PURE__ */ jsx16("span", { className: "db-sidebar-collapse-preview-label", children: "Release to hide files" })
11374
+ /* @__PURE__ */ jsxs15("div", { className: "db-sidebar-collapse-preview", "aria-hidden": "true", children: [
11375
+ /* @__PURE__ */ jsx17("span", { className: "db-sidebar-collapse-preview-icon", children: /* @__PURE__ */ jsx17(CollapseSidebarGlyph, {}) }),
11376
+ /* @__PURE__ */ jsx17("span", { className: "db-sidebar-collapse-preview-label", children: "Release to hide files" })
11180
11377
  ] })
11181
11378
  ]
11182
11379
  }
11183
11380
  ),
11184
- !singlePane && /* @__PURE__ */ jsx16(
11381
+ !singlePane && /* @__PURE__ */ jsx17(
11185
11382
  "div",
11186
11383
  {
11187
11384
  className: "db-shell-sidebar-resizer",
@@ -11191,7 +11388,7 @@ function DocBlocksShell({
11191
11388
  onPointerDown: handleResizerPointerDown
11192
11389
  }
11193
11390
  ),
11194
- singlePane && /* @__PURE__ */ jsx16(
11391
+ singlePane && /* @__PURE__ */ jsx17(
11195
11392
  "div",
11196
11393
  {
11197
11394
  className: "db-shell-scrim",
@@ -11199,7 +11396,7 @@ function DocBlocksShell({
11199
11396
  onPointerDown: () => setMobileShowEditor(true)
11200
11397
  }
11201
11398
  ),
11202
- /* @__PURE__ */ jsxs14(
11399
+ /* @__PURE__ */ jsxs15(
11203
11400
  "main",
11204
11401
  {
11205
11402
  ref: editorAreaRef,
@@ -11210,8 +11407,8 @@ function DocBlocksShell({
11210
11407
  editorDropActive ? "db-shell-editor-area--drop-active" : ""
11211
11408
  ].filter(Boolean).join(" "),
11212
11409
  children: [
11213
- selectedFile && mediaProvider ? /* @__PURE__ */ jsxs14(Fragment11, { children: [
11214
- selectedManagedOutput === "catalog-html" ? /* @__PURE__ */ jsx16(
11410
+ selectedFile && mediaProvider ? /* @__PURE__ */ jsxs15(Fragment11, { children: [
11411
+ selectedManagedOutput === "catalog-html" ? /* @__PURE__ */ jsx17(
11215
11412
  GeneratedCatalogPage,
11216
11413
  {
11217
11414
  html: editorContent,
@@ -11219,17 +11416,17 @@ function DocBlocksShell({
11219
11416
  onOpenSettings: activeWorkspaceDescriptor ? handleOpenWorkspaceSettings : void 0,
11220
11417
  onBack: singlePane ? openDrawer : void 0
11221
11418
  }
11222
- ) : /* @__PURE__ */ jsx16(
11419
+ ) : /* @__PURE__ */ jsx17(
11223
11420
  GeneratedFileFrame,
11224
11421
  {
11225
11422
  kind: selectedManagedOutput,
11226
11423
  onOpenSettings: activeWorkspaceDescriptor ? handleOpenWorkspaceSettings : void 0,
11227
11424
  onBack: singlePane ? openDrawer : void 0,
11228
- children: /* @__PURE__ */ jsx16(
11425
+ children: /* @__PURE__ */ jsx17(
11229
11426
  Suspense2,
11230
11427
  {
11231
- fallback: /* @__PURE__ */ jsx16("div", { className: "db-shell-empty", role: "status", children: "Loading your document\u2026" }),
11232
- children: /* @__PURE__ */ jsx16(
11428
+ fallback: /* @__PURE__ */ jsx17("div", { className: "db-shell-empty", role: "status", children: "Loading your document\u2026" }),
11429
+ children: editorGenerationSettled && mediaProviderCurrent && /* @__PURE__ */ jsx17(EditorErrorBoundary, { resetKey: `${selectedFile}-${editorKey}`, children: /* @__PURE__ */ jsx17(
11233
11430
  EditorShell,
11234
11431
  {
11235
11432
  initialMarkdown: editorContent,
@@ -11247,6 +11444,8 @@ function DocBlocksShell({
11247
11444
  onChange: handleEditorChange,
11248
11445
  onLinkClick: handleEditorLinkClick,
11249
11446
  colorScheme: resolvedTheme,
11447
+ defaultThemeId: workspaceDefaultThemeId,
11448
+ defaultThemeLabel: "Workspace default",
11250
11449
  writeCanvasSettings: editorWriteCanvasSettings,
11251
11450
  height: "100%",
11252
11451
  placeholder: editorPlaceholder,
@@ -11277,19 +11476,19 @@ function DocBlocksShell({
11277
11476
  versioningAutoSaveIdleMs,
11278
11477
  onSaveVersion,
11279
11478
  statusBarSlotRight,
11280
- sidePanelSlot: ai && aiPanel && selectedImage === void 0 && (selectedOutsideIn === null || selectedOutsideInEditingEnabled) ? /* @__PURE__ */ jsx16(Suspense2, { fallback: null, children: aiPanel === "review" ? /* @__PURE__ */ jsx16(AiReviewPanel, { ai, onClose: () => setAiPanel(null) }) : /* @__PURE__ */ jsx16(AiIllustratePanel, { ai, onClose: () => setAiPanel(null) }) }) : void 0,
11281
- toolbarSlotLeft: singlePane ? /* @__PURE__ */ jsx16(
11479
+ sidePanelSlot: ai && aiPanel && selectedImage === void 0 && (selectedOutsideIn === null || selectedOutsideInEditingEnabled) ? /* @__PURE__ */ jsx17(Suspense2, { fallback: null, children: aiPanel === "review" ? /* @__PURE__ */ jsx17(AiReviewPanel, { ai, onClose: () => setAiPanel(null) }) : /* @__PURE__ */ jsx17(AiIllustratePanel, { ai, onClose: () => setAiPanel(null) }) }) : void 0,
11480
+ toolbarSlotLeft: singlePane ? /* @__PURE__ */ jsx17(
11282
11481
  "button",
11283
11482
  {
11284
11483
  className: "db-mobile-back",
11285
11484
  onClick: () => setMobileShowEditor(false),
11286
11485
  "aria-label": "Show file list",
11287
- children: /* @__PURE__ */ jsx16("span", { className: "db-mobile-files-icon", children: /* @__PURE__ */ jsx16(FolderGlyph, {}) })
11486
+ children: /* @__PURE__ */ jsx17("span", { className: "db-mobile-files-icon", children: /* @__PURE__ */ jsx17(FolderGlyph, {}) })
11288
11487
  }
11289
11488
  ) : void 0,
11290
- summarizationDesigner: selectedImage === void 0 && selectedManagedOutput === void 0 && (selectedOutsideIn === null || selectedOutsideInEditingEnabled) ? (onClose) => /* @__PURE__ */ jsx16(Suspense2, { fallback: null, children: /* @__PURE__ */ jsx16(PresentationMaker, { ai: ai ?? void 0, onClose }) }) : void 0,
11291
- toolbarSlotRight: /* @__PURE__ */ jsxs14(Fragment11, { children: [
11292
- canFind && /* @__PURE__ */ jsx16(
11489
+ summarizationDesigner: selectedImage === void 0 && selectedManagedOutput === void 0 && (selectedOutsideIn === null || selectedOutsideInEditingEnabled) ? (onClose) => /* @__PURE__ */ jsx17(Suspense2, { fallback: null, children: /* @__PURE__ */ jsx17(PresentationMaker, { ai: ai ?? void 0, onClose }) }) : void 0,
11490
+ toolbarSlotRight: /* @__PURE__ */ jsxs15(Fragment11, { children: [
11491
+ canFind && /* @__PURE__ */ jsx17(
11293
11492
  FindButton,
11294
11493
  {
11295
11494
  active: findMode,
@@ -11297,7 +11496,7 @@ function DocBlocksShell({
11297
11496
  shortcutLabel: findShortcut
11298
11497
  }
11299
11498
  ),
11300
- ai && /* @__PURE__ */ jsx16(Suspense2, { fallback: null, children: /* @__PURE__ */ jsx16(
11499
+ ai && /* @__PURE__ */ jsx17(Suspense2, { fallback: null, children: /* @__PURE__ */ jsx17(
11301
11500
  AiToolbarControl,
11302
11501
  {
11303
11502
  ai,
@@ -11306,8 +11505,8 @@ function DocBlocksShell({
11306
11505
  onOpenPanel: setAiPanel
11307
11506
  }
11308
11507
  ) }),
11309
- speech && /* @__PURE__ */ jsxs14(Suspense2, { fallback: null, children: [
11310
- /* @__PURE__ */ jsx16(
11508
+ speech && /* @__PURE__ */ jsxs15(Suspense2, { fallback: null, children: [
11509
+ /* @__PURE__ */ jsx17(
11311
11510
  TextFromNarration,
11312
11511
  {
11313
11512
  speech,
@@ -11317,27 +11516,27 @@ function DocBlocksShell({
11317
11516
  onOpenSettings: openSettings
11318
11517
  }
11319
11518
  ),
11320
- hostSupports2("speechOutput") ? /* @__PURE__ */ jsx16(
11519
+ hostSupports2("speechOutput") ? /* @__PURE__ */ jsx17(
11321
11520
  SpeechToolbarControl,
11322
11521
  {
11323
11522
  speech,
11324
11523
  onOpenSettings: openSettings,
11325
11524
  readOnly: selectedImage !== void 0 || selectedOutsideIn !== null && !selectedOutsideInEditingEnabled
11326
11525
  }
11327
- ) : /* @__PURE__ */ jsx16(SpeechMenuBridge, {})
11526
+ ) : /* @__PURE__ */ jsx17(SpeechMenuBridge, {})
11328
11527
  ] }),
11329
- canRestoreSplitView && /* @__PURE__ */ jsx16(
11528
+ canRestoreSplitView && /* @__PURE__ */ jsx17(
11330
11529
  "button",
11331
11530
  {
11332
11531
  className: "db-restore-split",
11333
11532
  onClick: () => updateSidebarPreference("pinned"),
11334
11533
  "aria-label": "Restore split view",
11335
11534
  title: "Restore split view",
11336
- children: /* @__PURE__ */ jsx16(SplitViewIcon, {})
11535
+ children: /* @__PURE__ */ jsx17(SplitViewIcon, {})
11337
11536
  }
11338
11537
  ),
11339
- git.repo && /* @__PURE__ */ jsx16(Suspense2, { fallback: null, children: /* @__PURE__ */ jsx16(GitToolbarControl, { selectedFile }) }),
11340
- /* @__PURE__ */ jsx16(
11538
+ git.repo && /* @__PURE__ */ jsx17(Suspense2, { fallback: null, children: /* @__PURE__ */ jsx17(GitToolbarControl, { selectedFile }) }),
11539
+ /* @__PURE__ */ jsx17(
11341
11540
  ExportToolbarControls,
11342
11541
  {
11343
11542
  selectedFile,
@@ -11357,20 +11556,20 @@ function DocBlocksShell({
11357
11556
  ] })
11358
11557
  },
11359
11558
  `${selectedFile}-${editorKey}`
11360
- )
11559
+ ) })
11361
11560
  }
11362
11561
  )
11363
11562
  }
11364
11563
  ),
11365
- showWelcomeGateway && !singlePane && /* @__PURE__ */ jsxs14("div", { className: "db-welcome-gateway", role: "note", "aria-label": "Welcome tip", children: [
11366
- /* @__PURE__ */ jsxs14("span", { className: "db-welcome-gateway-text", children: [
11564
+ showWelcomeGateway && !singlePane && /* @__PURE__ */ jsxs15("div", { className: "db-welcome-gateway", role: "note", "aria-label": "Welcome tip", children: [
11565
+ /* @__PURE__ */ jsxs15("span", { className: "db-welcome-gateway-text", children: [
11367
11566
  "You\u2019re watching this welcome doc in ",
11368
- /* @__PURE__ */ jsx16("strong", { children: "Slideshow" }),
11567
+ /* @__PURE__ */ jsx17("strong", { children: "Slideshow" }),
11369
11568
  " ",
11370
- "view\u2014 it\u2019s a regular markdown file, and so is everything you\u2019ll write."
11569
+ "view\u2014it\u2019s a regular Markdown file, and so is everything you\u2019ll write."
11371
11570
  ] }),
11372
- /* @__PURE__ */ jsx16("button", { className: "db-welcome-gateway-cta", onClick: handleStartWriting, children: "Start writing" }),
11373
- /* @__PURE__ */ jsx16(
11571
+ /* @__PURE__ */ jsx17("button", { className: "db-welcome-gateway-cta", onClick: handleStartWriting, children: "Start writing" }),
11572
+ /* @__PURE__ */ jsx17(
11374
11573
  "button",
11375
11574
  {
11376
11575
  className: "db-welcome-gateway-dismiss",
@@ -11381,39 +11580,39 @@ function DocBlocksShell({
11381
11580
  }
11382
11581
  )
11383
11582
  ] })
11384
- ] }) : selectedFolder ? /* @__PURE__ */ jsxs14("div", { className: "db-folder-view", children: [
11385
- singlePane && /* @__PURE__ */ jsxs14("button", { className: "db-mobile-back", onClick: () => setMobileShowEditor(false), children: [
11386
- /* @__PURE__ */ jsx16("span", { className: "db-mobile-files-icon", children: /* @__PURE__ */ jsx16(FolderGlyph, {}) }),
11583
+ ] }) : selectedFolder ? /* @__PURE__ */ jsxs15("div", { className: "db-folder-view", children: [
11584
+ singlePane && /* @__PURE__ */ jsxs15("button", { className: "db-mobile-back", onClick: () => setMobileShowEditor(false), children: [
11585
+ /* @__PURE__ */ jsx17("span", { className: "db-mobile-files-icon", children: /* @__PURE__ */ jsx17(FolderGlyph, {}) }),
11387
11586
  "Back to files"
11388
11587
  ] }),
11389
- /* @__PURE__ */ jsxs14("div", { className: "db-folder-view-header", children: [
11390
- /* @__PURE__ */ jsx16("span", { className: "db-folder-view-icon", children: /* @__PURE__ */ jsx16(FolderGlyph, {}) }),
11391
- /* @__PURE__ */ jsx16("span", { className: "db-folder-view-path", children: selectedFolder })
11588
+ /* @__PURE__ */ jsxs15("div", { className: "db-folder-view-header", children: [
11589
+ /* @__PURE__ */ jsx17("span", { className: "db-folder-view-icon", children: /* @__PURE__ */ jsx17(FolderGlyph, {}) }),
11590
+ /* @__PURE__ */ jsx17("span", { className: "db-folder-view-path", children: selectedFolder })
11392
11591
  ] }),
11393
- visibleFolderEntries.length === 0 ? /* @__PURE__ */ jsx16("p", { className: "db-folder-view-empty", children: "This folder is empty." }) : /* @__PURE__ */ jsx16("ul", { className: "db-folder-view-list", children: visibleFolderEntries.map((entry) => /* @__PURE__ */ jsxs14(
11592
+ visibleFolderEntries.length === 0 ? /* @__PURE__ */ jsx17("p", { className: "db-folder-view-empty", children: "This folder is empty." }) : /* @__PURE__ */ jsx17("ul", { className: "db-folder-view-list", children: visibleFolderEntries.map((entry) => /* @__PURE__ */ jsxs15(
11394
11593
  "li",
11395
11594
  {
11396
11595
  className: "db-folder-view-item",
11397
11596
  onClick: () => handleSelect(entry.path, entry.kind),
11398
11597
  children: [
11399
- /* @__PURE__ */ jsx16("span", { className: "db-folder-view-item-icon", children: entry.kind === "directory" ? /* @__PURE__ */ jsx16(FolderGlyph, {}) : /* @__PURE__ */ jsx16(FileGlyph, {}) }),
11598
+ /* @__PURE__ */ jsx17("span", { className: "db-folder-view-item-icon", children: entry.kind === "directory" ? /* @__PURE__ */ jsx17(FolderGlyph, {}) : /* @__PURE__ */ jsx17(FileGlyph, {}) }),
11400
11599
  entry.name
11401
11600
  ]
11402
11601
  },
11403
11602
  entry.path
11404
11603
  )) })
11405
- ] }) : /* @__PURE__ */ jsxs14("div", { className: "db-shell-empty db-shell-empty--workspace", children: [
11406
- singlePane && /* @__PURE__ */ jsxs14("button", { className: "db-mobile-back", onClick: () => setMobileShowEditor(false), children: [
11407
- /* @__PURE__ */ jsx16("span", { className: "db-mobile-files-icon", children: /* @__PURE__ */ jsx16(FolderGlyph, {}) }),
11604
+ ] }) : /* @__PURE__ */ jsxs15("div", { className: "db-shell-empty db-shell-empty--workspace", children: [
11605
+ singlePane && /* @__PURE__ */ jsxs15("button", { className: "db-mobile-back", onClick: () => setMobileShowEditor(false), children: [
11606
+ /* @__PURE__ */ jsx17("span", { className: "db-mobile-files-icon", children: /* @__PURE__ */ jsx17(FolderGlyph, {}) }),
11408
11607
  "Back to files"
11409
11608
  ] }),
11410
- /* @__PURE__ */ jsxs14("div", { className: "db-workspace-empty-content", children: [
11411
- /* @__PURE__ */ jsx16("span", { className: "db-workspace-empty-icon", "aria-hidden": "true", children: /* @__PURE__ */ jsx16(FileGlyph, {}) }),
11412
- /* @__PURE__ */ jsx16("h1", { children: activeWorkspaceDescriptor?.name ?? "Workspace" }),
11413
- /* @__PURE__ */ jsx16("p", { children: "Choose a Markdown document from the sidebar, or create a new one." }),
11414
- /* @__PURE__ */ jsxs14("div", { className: "db-workspace-empty-actions", children: [
11415
- /* @__PURE__ */ jsx16("button", { type: "button", onClick: () => void handleNewFile(), children: "New document" }),
11416
- /* @__PURE__ */ jsx16(
11609
+ /* @__PURE__ */ jsxs15("div", { className: "db-workspace-empty-content", children: [
11610
+ /* @__PURE__ */ jsx17("span", { className: "db-workspace-empty-icon", "aria-hidden": "true", children: /* @__PURE__ */ jsx17(FileGlyph, {}) }),
11611
+ /* @__PURE__ */ jsx17("h1", { children: activeWorkspaceDescriptor?.name ?? "Workspace" }),
11612
+ /* @__PURE__ */ jsx17("p", { children: "Choose a Markdown document from the sidebar, or create a new one." }),
11613
+ /* @__PURE__ */ jsxs15("div", { className: "db-workspace-empty-actions", children: [
11614
+ /* @__PURE__ */ jsx17("button", { type: "button", onClick: () => void handleNewFile(), children: "New document" }),
11615
+ /* @__PURE__ */ jsx17(
11417
11616
  "button",
11418
11617
  {
11419
11618
  type: "button",
@@ -11422,7 +11621,7 @@ function DocBlocksShell({
11422
11621
  children: "New folder"
11423
11622
  }
11424
11623
  ),
11425
- (hostSupports2("workspaceFolderPicker") || typeof globalThis.showDirectoryPicker === "function") && /* @__PURE__ */ jsx16(
11624
+ (hostSupports2("workspaceFolderPicker") || typeof globalThis.showDirectoryPicker === "function") && /* @__PURE__ */ jsx17(
11426
11625
  "button",
11427
11626
  {
11428
11627
  type: "button",
@@ -11432,10 +11631,10 @@ function DocBlocksShell({
11432
11631
  }
11433
11632
  )
11434
11633
  ] }),
11435
- /* @__PURE__ */ jsx16("p", { className: "db-workspace-empty-hint", children: "Use the sidebar backup action to keep a portable copy of this workspace." })
11634
+ /* @__PURE__ */ jsx17("p", { className: "db-workspace-empty-hint", children: "Use the sidebar backup action to keep a portable copy of this workspace." })
11436
11635
  ] })
11437
11636
  ] }),
11438
- /* @__PURE__ */ jsx16(
11637
+ /* @__PURE__ */ jsx17(
11439
11638
  UpdateAvailableNotice,
11440
11639
  {
11441
11640
  available: updateAvailable,