@manifest-editor/shell 1.1.0 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -40,12 +40,15 @@ __export(src_exports, {
40
40
  AppProvider: () => AppProvider,
41
41
  AppResourceInstanceProvider: () => AppResourceInstanceProvider,
42
42
  AppResourceProvider: () => AppResourceProvider,
43
+ AtlasStoreProvider: () => AtlasStoreProvider,
44
+ AtlasStoreReactContext: () => AtlasStoreReactContext,
43
45
  BaseEditor: () => BaseEditor,
44
46
  BaseEditorBackButton: () => BaseEditorBackButton,
45
47
  BaseEditorCloseButton: () => BaseEditorCloseButton,
46
48
  ConfigEditor: () => ConfigEditor,
47
49
  ConfigProvider: () => ConfigProvider,
48
50
  EditingStack: () => EditingStack,
51
+ EventEmitterProvider: () => EventEmitterProvider,
49
52
  ExportPanel: () => ExportPanel,
50
53
  HOMEPAGE_COLLECTION: () => HOMEPAGE_COLLECTION,
51
54
  HandleContainer: () => HandleContainer,
@@ -63,7 +66,9 @@ __export(src_exports, {
63
66
  PreviewVaultBoundary: () => PreviewVaultBoundary,
64
67
  PreviewVaultContext: () => PreviewVaultContext,
65
68
  PrimeAppReactContext: () => PrimeAppReactContext,
69
+ ReactEmitterContext: () => ReactEmitterContext,
66
70
  ResourceEditingProvider: () => ResourceEditingProvider,
71
+ ResourceEditingReactContext: () => ResourceEditingReactContext,
67
72
  ShellProvider: () => ShellProvider,
68
73
  TaskBridge: () => TaskBridge,
69
74
  UniversalCopyTarget: () => UniversalCopyTarget,
@@ -73,10 +78,12 @@ __export(src_exports, {
73
78
  baseEditor: () => baseEditor,
74
79
  copyToClipboard: () => copyToClipboard,
75
80
  createActionIdentity: () => createActionIdentity,
81
+ createAtlasStore: () => createAtlasStore,
76
82
  createDownload: () => createDownload,
77
83
  createPreviewVault: () => createPreviewVault,
78
84
  detectMedia: () => detectMedia,
79
85
  editBasedOnResource: () => editBasedOnResource,
86
+ extendApp: () => extendApp,
80
87
  getDefaultLayoutState: () => getDefaultLayoutState,
81
88
  getDefaultPanelState: () => getDefaultPanelState,
82
89
  getFormat: () => getFormat,
@@ -85,10 +92,11 @@ __export(src_exports, {
85
92
  isPinnableState: () => isPinnableState,
86
93
  layoutReducer: () => layoutReducer,
87
94
  mapApp: () => mapApp,
88
- matchBasedOnResource: () => matchBasedOnResource,
89
95
  panelSizing: () => panelSizing,
96
+ polygonToBoundingBox: () => polygonToBoundingBox,
90
97
  randomId: () => randomId,
91
98
  renderHelper: () => renderHelper,
99
+ requestToAnnotationResponse: () => requestToAnnotationResponse,
92
100
  useAnnotationPageEditor: () => useAnnotationPageEditor,
93
101
  useApp: () => useApp,
94
102
  useAppInstance: () => useAppInstance,
@@ -98,6 +106,7 @@ __export(src_exports, {
98
106
  useAppResourceInstance: () => useAppResourceInstance,
99
107
  useAppState: () => useAppState,
100
108
  useApps: () => useApps,
109
+ useAtlasStore: () => useAtlasStore,
101
110
  useAvailableLayouts: () => useAvailableLayouts,
102
111
  useCollectionEditor: () => useCollectionEditor,
103
112
  useConfig: () => useConfig,
@@ -109,6 +118,8 @@ __export(src_exports, {
109
118
  useEditingResourceStack: () => useEditingResourceStack,
110
119
  useEditingStack: () => useEditingStack,
111
120
  useEditor: () => useEditor,
121
+ useEmitter: () => useEmitter,
122
+ useEvent: () => useEvent,
112
123
  useGenericEditor: () => useGenericEditor,
113
124
  useHighlightedImageResource: () => useHighlightedImageResource,
114
125
  useHoverHighlightImageResource: () => useHoverHighlightImageResource,
@@ -117,16 +128,19 @@ __export(src_exports, {
117
128
  useLayoutProvider: () => useLayoutProvider,
118
129
  useLayoutState: () => useLayoutState,
119
130
  useManifestEditor: () => useManifestEditor,
131
+ useMatchMedia: () => useMatchMedia,
120
132
  useOptionalResource: () => useOptionalResource,
121
133
  usePanelActions: () => usePanelActions,
122
134
  usePreviewContext: () => usePreviewContext,
123
135
  usePreviewHistory: () => usePreviewHistory,
124
136
  usePreviewVault: () => usePreviewVault,
125
137
  usePreviews: () => usePreviews,
138
+ useRequestAnnotation: () => useRequestAnnotation,
126
139
  useResource: () => useResource,
127
140
  useSaveConfig: () => useSaveConfig,
128
141
  useSaveVault: () => useSaveVault,
129
142
  useSetCustomTitle: () => useSetCustomTitle,
143
+ useSvgTools: () => useSvgTools,
130
144
  useTask: () => useTask,
131
145
  useTaskDispatch: () => useTaskDispatch,
132
146
  useTaskEvent: () => useTaskEvent,
@@ -135,24 +149,6 @@ __export(src_exports, {
135
149
  });
136
150
  module.exports = __toCommonJS(src_exports);
137
151
 
138
- // src/AppContext/AppContext.tsx
139
- var import_react2 = require("react");
140
-
141
- // ../../node_modules/.pnpm/tiny-invariant@1.3.3/node_modules/tiny-invariant/dist/esm/tiny-invariant.js
142
- var isProduction = false;
143
- var prefix = "Invariant failed";
144
- function invariant(condition, message) {
145
- if (condition) {
146
- return;
147
- }
148
- if (isProduction) {
149
- throw new Error(prefix);
150
- }
151
- var provided = typeof message === "function" ? message() : message;
152
- var value = provided ? "".concat(prefix, ": ").concat(provided) : prefix;
153
- throw new Error(value);
154
- }
155
-
156
152
  // ../ui/madoc/use-local-storage.ts
157
153
  var import_react = require("react");
158
154
  var import_mitt = __toESM(require("mitt"), 1);
@@ -226,33 +222,127 @@ function useLocalStorage(key, initialValue) {
226
222
  }
227
223
 
228
224
  // src/AppContext/AppContext.tsx
225
+ var import_react3 = require("react");
226
+
227
+ // ../../node_modules/.pnpm/tiny-invariant@1.3.3/node_modules/tiny-invariant/dist/esm/tiny-invariant.js
228
+ var isProduction = false;
229
+ var prefix = "Invariant failed";
230
+ function invariant(condition, message) {
231
+ if (condition) {
232
+ return;
233
+ }
234
+ if (isProduction) {
235
+ throw new Error(prefix);
236
+ }
237
+ var provided = typeof message === "function" ? message() : message;
238
+ var value = provided ? "".concat(prefix, ": ").concat(provided) : prefix;
239
+ throw new Error(value);
240
+ }
241
+
242
+ // src/ConfigContext/ConfigContext.tsx
243
+ var import_react2 = require("react");
229
244
  var import_jsx_runtime = require("react/jsx-runtime");
230
- var PrimeAppReactContext = (0, import_react2.createContext)(null);
231
- var AppReactContext = (0, import_react2.createContext)(null);
232
- var AppStateReactContext = (0, import_react2.createContext)({
245
+ var DEFAULT_CONFIG = {
246
+ previews: [],
247
+ behaviorPresets: [
248
+ "auto-advance",
249
+ "no-auto-advance",
250
+ "repeat",
251
+ "no-repeat",
252
+ "unordered",
253
+ "individuals",
254
+ "continuous",
255
+ "paged",
256
+ "non-paged",
257
+ "facing-pages",
258
+ "multi-part",
259
+ "together",
260
+ "sequence",
261
+ "thumbnail-nav",
262
+ "no-nav",
263
+ "hidden"
264
+ ],
265
+ defaultPreview: null,
266
+ editorConfig: {},
267
+ newTemplates: null,
268
+ i18n: {
269
+ advancedLanguageMode: false,
270
+ availableLanguages: ["en", "cy", "nl", "fr"],
271
+ defaultLanguage: "en"
272
+ },
273
+ editorFeatureFlags: {
274
+ enableMultiImageCanvases: true,
275
+ enableMultiMediaCanvases: true
276
+ },
277
+ uploadBackends: [],
278
+ export: {
279
+ baseIdentifier: null,
280
+ version: 3
281
+ }
282
+ };
283
+ var ConfigReactContext = (0, import_react2.createContext)(DEFAULT_CONFIG);
284
+ var SaveConfigReactContext = (0, import_react2.createContext)(() => {
285
+ });
286
+ function useConfig() {
287
+ return (0, import_react2.useContext)(ConfigReactContext);
288
+ }
289
+ function useSaveConfig() {
290
+ return (0, import_react2.useContext)(SaveConfigReactContext);
291
+ }
292
+ function ConfigProvider({
293
+ children,
294
+ config,
295
+ saveConfig
296
+ }) {
297
+ const [runtimeConfig, setRuntimeConfig] = (0, import_react2.useState)(null);
298
+ const resolvedConfig = (0, import_react2.useMemo)(
299
+ () => ({
300
+ ...DEFAULT_CONFIG,
301
+ ...config || {},
302
+ ...runtimeConfig || {}
303
+ }),
304
+ [config, runtimeConfig]
305
+ );
306
+ const memoSaveConfig = (0, import_react2.useCallback)(
307
+ (config2) => {
308
+ setRuntimeConfig(config2);
309
+ if (saveConfig) {
310
+ saveConfig(config2);
311
+ }
312
+ },
313
+ [config]
314
+ );
315
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SaveConfigReactContext.Provider, { value: memoSaveConfig, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ConfigReactContext.Provider, { value: resolvedConfig, children }) });
316
+ }
317
+
318
+ // src/AppContext/AppContext.tsx
319
+ var import_jsx_runtime2 = require("react/jsx-runtime");
320
+ var PrimeAppReactContext = (0, import_react3.createContext)(null);
321
+ var AppReactContext = (0, import_react3.createContext)(null);
322
+ var AppStateReactContext = (0, import_react3.createContext)({
233
323
  state: null,
234
324
  setState: () => {
235
325
  }
236
326
  });
237
327
  function useAppInstance() {
238
- const ctx = (0, import_react2.useContext)(AppReactContext);
328
+ const ctx = (0, import_react3.useContext)(AppReactContext);
239
329
  invariant(ctx, "Hook useAppInstance must be used inside <AppProvider />");
240
330
  return ctx;
241
331
  }
242
332
  function useApp() {
243
- const app = (0, import_react2.useContext)(PrimeAppReactContext);
333
+ const app = (0, import_react3.useContext)(PrimeAppReactContext);
244
334
  invariant(app, "Hook useApp must be used inside <AppProvider />");
245
335
  return app;
246
336
  }
247
337
  function useAppState() {
248
- return (0, import_react2.useContext)(AppStateReactContext);
338
+ return (0, import_react3.useContext)(AppStateReactContext);
249
339
  }
250
340
  function AppStateProvider(props) {
251
341
  const [state, _setState, stateRef] = useLocalStorage(
252
342
  `app-state/${props.appId}/${props.instanceId}`,
253
343
  props.initialState || {}
254
344
  );
255
- const setState = (0, import_react2.useCallback)((partial) => {
345
+ const setState = (0, import_react3.useCallback)((partial) => {
256
346
  const existing = stateRef.current ? JSON.parse(stateRef.current || "{}") : {};
257
347
  const partialState = (typeof partial === "function" ? partial(existing) : partial) || {};
258
348
  _setState({
@@ -260,13 +350,16 @@ function AppStateProvider(props) {
260
350
  ...partialState
261
351
  });
262
352
  }, []);
263
- (0, import_react2.useEffect)(() => {
353
+ (0, import_react3.useEffect)(() => {
264
354
  if (props.args) {
265
355
  setState(props.args);
266
356
  }
267
357
  }, [props.appId]);
268
- const ctx = (0, import_react2.useMemo)(() => ({ state: state || {}, setState }), [setState, state]);
269
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(AppStateReactContext.Provider, { value: ctx, children: props.children });
358
+ const ctx = (0, import_react3.useMemo)(
359
+ () => ({ state: state || {}, setState }),
360
+ [setState, state]
361
+ );
362
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(AppStateReactContext.Provider, { value: ctx, children: props.children });
270
363
  }
271
364
  function AppProvider({
272
365
  instanceId,
@@ -276,17 +369,29 @@ function AppProvider({
276
369
  children,
277
370
  initialState
278
371
  }) {
279
- const ctx = (0, import_react2.useMemo)(() => ({ instanceId, appId, args }), [instanceId, appId, args]);
280
- const _initialState = (0, import_react2.useMemo)(() => initialState || {}, [instanceId]);
281
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(PrimeAppReactContext.Provider, { value: definition, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(AppReactContext.Provider, { value: ctx, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(AppStateProvider, { instanceId: ctx.instanceId, appId: ctx.appId, args: ctx.args, initialState: _initialState, children }) }) });
372
+ const ctx = (0, import_react3.useMemo)(
373
+ () => ({ instanceId, appId, args }),
374
+ [instanceId, appId, args]
375
+ );
376
+ const _initialState = (0, import_react3.useMemo)(() => initialState || {}, [instanceId]);
377
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ConfigProvider, { config: definition.config || {}, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(PrimeAppReactContext.Provider, { value: definition, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(AppReactContext.Provider, { value: ctx, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
378
+ AppStateProvider,
379
+ {
380
+ instanceId: ctx.instanceId,
381
+ appId: ctx.appId,
382
+ args: ctx.args,
383
+ initialState: _initialState,
384
+ children
385
+ }
386
+ ) }) }) });
282
387
  }
283
388
 
284
389
  // src/AppContext/MultiAppContext.tsx
285
- var import_react3 = require("react");
286
- var import_jsx_runtime2 = require("react/jsx-runtime");
287
- var MultiAppContext = (0, import_react3.createContext)(null);
390
+ var import_react4 = require("react");
391
+ var import_jsx_runtime3 = require("react/jsx-runtime");
392
+ var MultiAppContext = (0, import_react4.createContext)(null);
288
393
  function useApps() {
289
- const ctx = (0, import_react3.useContext)(MultiAppContext);
394
+ const ctx = (0, import_react4.useContext)(MultiAppContext);
290
395
  invariant(ctx, "Hook useApps must be used inside <MultiAppProvider />");
291
396
  return ctx;
292
397
  }
@@ -316,7 +421,7 @@ function MultiAppProvider({
316
421
  changeApp({ id: collectionApp });
317
422
  }
318
423
  };
319
- const ctx = (0, import_react3.useMemo)(
424
+ const ctx = (0, import_react4.useMemo)(
320
425
  () => ({
321
426
  currentApp: currentApp || { id: defaultApp },
322
427
  initialApp: initialApp || { id: defaultApp },
@@ -330,14 +435,14 @@ function MultiAppProvider({
330
435
  if (!currentApp || !currentFullApp) {
331
436
  return null;
332
437
  }
333
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
438
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
334
439
  AppProvider,
335
440
  {
336
441
  appId: currentApp.id,
337
442
  definition: currentFullApp,
338
443
  instanceId: currentApp.id + instanceId,
339
444
  args: currentApp.args,
340
- children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(MultiAppContext.Provider, { value: ctx, children })
445
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(MultiAppContext.Provider, { value: ctx, children })
341
446
  }
342
447
  );
343
448
  }
@@ -414,11 +519,89 @@ var ContextButton = import_styled_components.default.button`
414
519
  letter-spacing: -0.42px;
415
520
  `;
416
521
 
522
+ // src/PreviewButton/PreviewButton.tsx
523
+ var import_components = require("@manifest-editor/components");
524
+
525
+ // ../ui/icons/CloseIcon.tsx
526
+ var import_jsx_runtime4 = require("react/jsx-runtime");
527
+ var CloseIcon = ({ height = 16 }) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("svg", { xmlns: "http://www.w3.org/2000/svg", height, viewBox: "0 0 24 24", width: "24px", fill: "#000000", children: [
528
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("path", { d: "M0 0h24v24H0z", fill: "none" }),
529
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("path", { d: "M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z" })
530
+ ] });
531
+
532
+ // ../ui/icons/DownIcon.tsx
533
+ var import_jsx_runtime5 = require("react/jsx-runtime");
534
+ var DownIcon = ({ rotate = 0, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
535
+ "svg",
536
+ {
537
+ version: "1.2",
538
+ xmlns: "http://www.w3.org/2000/svg",
539
+ overflow: "visible",
540
+ preserveAspectRatio: "none",
541
+ viewBox: "0 0 24 24",
542
+ width: "1em",
543
+ height: "1em",
544
+ style: {
545
+ fill: "rgba(0, 0, 0, 0.6)",
546
+ transform: `rotate(${rotate}deg)`,
547
+ transition: "transform 0.2s"
548
+ },
549
+ ...props,
550
+ children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
551
+ "path",
552
+ {
553
+ d: "M8.12 9.29 12 13.17l3.88-3.88a.996.996 0 1 1 1.41 1.41l-4.59 4.59a.996.996 0 0 1-1.41 0L6.7 10.7a.996.996 0 0 1 0-1.41c.39-.38 1.03-.39 1.42 0z",
554
+ fill: "currentColor"
555
+ }
556
+ )
557
+ }
558
+ );
559
+
560
+ // src/PreviewButton/PreviewButton.tsx
561
+ var import_react_accessible_dropdown_menu_hook = __toESM(require("react-accessible-dropdown-menu-hook"), 1);
562
+ var import_react_iiif_vault3 = require("react-iiif-vault");
563
+
564
+ // src/AppResourceProvider/AppResourceProvider.tsx
565
+ var import_react5 = require("react");
566
+ var import_react_iiif_vault = require("react-iiif-vault");
567
+ var import_jsx_runtime6 = require("react/jsx-runtime");
568
+ var AppResourceReactProvider = (0, import_react5.createContext)(null);
569
+ var AppResourceInstanceReactProvider = (0, import_react5.createContext)(null);
570
+ function useAppResourceInstance() {
571
+ const ctx = (0, import_react5.useContext)(AppResourceInstanceReactProvider);
572
+ const resource = (0, import_react5.useContext)(AppResourceReactProvider);
573
+ const instanceId = ctx || resource?.id;
574
+ invariant(instanceId, "useResourceInstance can only be called from inside <ResourceProvider />");
575
+ return instanceId;
576
+ }
577
+ function useAppResource() {
578
+ const ctx = (0, import_react5.useContext)(AppResourceReactProvider);
579
+ invariant(ctx, "useResource can only be called from inside <ResourceProvider />");
580
+ return ctx;
581
+ }
582
+ function AppResourceInstanceProvider({ id, children }) {
583
+ if (!id) {
584
+ return children;
585
+ }
586
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(AppResourceInstanceReactProvider.Provider, { value: id, children });
587
+ }
588
+ function AppResourceProvider({ resource, children }) {
589
+ const vault = (0, import_react_iiif_vault.useExistingVault)();
590
+ let inner = children;
591
+ if (resource && resource.type === "Manifest") {
592
+ inner = /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_iiif_vault.VaultProvider, { vault: vault || void 0, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_iiif_vault.ManifestContext, { manifest: resource.id || "", children }) });
593
+ }
594
+ if (resource && resource.type === "Collection") {
595
+ inner = /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_iiif_vault.VaultProvider, { vault: vault || void 0, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_iiif_vault.CollectionContext, { collection: resource.id || "", children }) });
596
+ }
597
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(AppResourceReactProvider.Provider, { value: resource, children: inner });
598
+ }
599
+
417
600
  // src/PreviewContext/PreviewContext.tsx
418
- var import_react6 = require("react");
601
+ var import_react7 = require("react");
419
602
 
420
603
  // src/PreviewContext/PreviewContext.hooks.ts
421
- var import_react5 = require("react");
604
+ var import_react6 = require("react");
422
605
 
423
606
  // src/PreviewContext/previews/ExternalManifestUrlPreview.ts
424
607
  var ExternalManifestUrlPreview = class {
@@ -593,49 +776,11 @@ var IIIFPreviewService = class {
593
776
 
594
777
  // src/PreviewContext/PreviewContext.hooks.ts
595
778
  var import_react_iiif_vault2 = require("react-iiif-vault");
596
-
597
- // src/AppResourceProvider/AppResourceProvider.tsx
598
- var import_react4 = require("react");
599
- var import_react_iiif_vault = require("react-iiif-vault");
600
- var import_jsx_runtime3 = require("react/jsx-runtime");
601
- var AppResourceReactProvider = (0, import_react4.createContext)(null);
602
- var AppResourceInstanceReactProvider = (0, import_react4.createContext)(null);
603
- function useAppResourceInstance() {
604
- const ctx = (0, import_react4.useContext)(AppResourceInstanceReactProvider);
605
- const resource = (0, import_react4.useContext)(AppResourceReactProvider);
606
- const instanceId = ctx || resource?.id;
607
- invariant(instanceId, "useResourceInstance can only be called from inside <ResourceProvider />");
608
- return instanceId;
609
- }
610
- function useAppResource() {
611
- const ctx = (0, import_react4.useContext)(AppResourceReactProvider);
612
- invariant(ctx, "useResource can only be called from inside <ResourceProvider />");
613
- return ctx;
614
- }
615
- function AppResourceInstanceProvider({ id, children }) {
616
- if (!id) {
617
- return children;
618
- }
619
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(AppResourceInstanceReactProvider.Provider, { value: id, children });
620
- }
621
- function AppResourceProvider({ resource, children }) {
622
- const vault = (0, import_react_iiif_vault.useExistingVault)();
623
- let inner = children;
624
- if (resource && resource.type === "Manifest") {
625
- inner = /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_iiif_vault.VaultProvider, { vault: vault || void 0, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_iiif_vault.ManifestContext, { manifest: resource.id || "", children }) });
626
- }
627
- if (resource && resource.type === "Collection") {
628
- inner = /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_iiif_vault.VaultProvider, { vault: vault || void 0, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_iiif_vault.CollectionContext, { collection: resource.id || "", children }) });
629
- }
630
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(AppResourceReactProvider.Provider, { value: resource, children: inner });
631
- }
632
-
633
- // src/PreviewContext/PreviewContext.hooks.ts
634
779
  function usePreviewActions(state, dispatch, handlers, previews, setPreviews) {
635
780
  const resource = useAppResource();
636
781
  const instanceId = useAppResourceInstance();
637
782
  const vault = (0, import_react_iiif_vault2.useVault)();
638
- const previewActions = (0, import_react5.useMemo)(
783
+ const previewActions = (0, import_react6.useMemo)(
639
784
  () => ({
640
785
  setPreview: (preview) => {
641
786
  if (!preview)
@@ -648,7 +793,7 @@ function usePreviewActions(state, dispatch, handlers, previews, setPreviews) {
648
793
  }),
649
794
  [setPreviews, instanceId]
650
795
  );
651
- const [handlerMap, providesMap] = (0, import_react5.useMemo)(() => {
796
+ const [handlerMap, providesMap] = (0, import_react6.useMemo)(() => {
652
797
  const map = {};
653
798
  const providesMap2 = {};
654
799
  for (const handler of handlers) {
@@ -766,7 +911,7 @@ function usePreviewActions(state, dispatch, handlers, previews, setPreviews) {
766
911
  }
767
912
  }
768
913
  }
769
- return (0, import_react5.useMemo)(
914
+ return (0, import_react6.useMemo)(
770
915
  () => ({ selectPreview, deletePreview, focusPreview, activatePreview, updatePreviews, getPreviewLink }),
771
916
  // Dispatch has a stable identity.
772
917
  // eslint-disable-next-line react-hooks/exhaustive-deps
@@ -774,7 +919,7 @@ function usePreviewActions(state, dispatch, handlers, previews, setPreviews) {
774
919
  );
775
920
  }
776
921
  function usePreviewHandlers(configs) {
777
- return (0, import_react5.useMemo)(() => {
922
+ return (0, import_react6.useMemo)(() => {
778
923
  const handlers = [];
779
924
  for (const config of configs) {
780
925
  switch (config.type) {
@@ -827,23 +972,23 @@ function getDefaultPreviewState() {
827
972
  }
828
973
 
829
974
  // src/PreviewContext/PreviewContext.tsx
830
- var import_jsx_runtime4 = require("react/jsx-runtime");
831
- var PreviewReactContext = (0, import_react6.createContext)(null);
832
- var AvailablePreviewReactContext = (0, import_react6.createContext)([]);
833
- var PreviewProvider = (0, import_react6.memo)(function PreviewProvider2({
975
+ var import_jsx_runtime7 = require("react/jsx-runtime");
976
+ var PreviewReactContext = (0, import_react7.createContext)(null);
977
+ var AvailablePreviewReactContext = (0, import_react7.createContext)([]);
978
+ var PreviewProvider = (0, import_react7.memo)(function PreviewProvider2({
834
979
  children,
835
980
  configs = []
836
981
  }) {
837
982
  const instanceId = useAppResourceInstance();
838
983
  const handlers = usePreviewHandlers(configs);
839
984
  const [previews, setPreviews] = useLocalStorage(`preview-${instanceId}`, []);
840
- const [state, dispatch] = (0, import_react6.useReducer)(previewContextReducer, void 0, getDefaultPreviewState);
985
+ const [state, dispatch] = (0, import_react7.useReducer)(previewContextReducer, void 0, getDefaultPreviewState);
841
986
  const actions = usePreviewActions(state, dispatch, handlers, previews, setPreviews);
842
- const context = (0, import_react6.useMemo)(
987
+ const context = (0, import_react7.useMemo)(
843
988
  () => ({ configs, actions, handlers, ...state }),
844
989
  [actions, configs, handlers, state]
845
990
  );
846
- (0, import_react6.useEffect)(() => {
991
+ (0, import_react7.useEffect)(() => {
847
992
  for (const preview of previews) {
848
993
  if (!state.active.includes(preview.id)) {
849
994
  const handler = handlers.find((h) => h.id === preview.id);
@@ -859,13 +1004,13 @@ var PreviewProvider = (0, import_react6.memo)(function PreviewProvider2({
859
1004
  }
860
1005
  }
861
1006
  }, [instanceId]);
862
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(AvailablePreviewReactContext.Provider, { value: previews, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(PreviewReactContext.Provider, { value: context, children }) });
1007
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(AvailablePreviewReactContext.Provider, { value: previews, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(PreviewReactContext.Provider, { value: context, children }) });
863
1008
  });
864
1009
  function usePreviews() {
865
- return (0, import_react6.useContext)(AvailablePreviewReactContext);
1010
+ return (0, import_react7.useContext)(AvailablePreviewReactContext);
866
1011
  }
867
1012
  function usePreviewContext() {
868
- const ctx = (0, import_react6.useContext)(PreviewReactContext);
1013
+ const ctx = (0, import_react7.useContext)(PreviewReactContext);
869
1014
  invariant(ctx, "usePreviewContext() can only be called from inside <PreviewProvider />");
870
1015
  return ctx;
871
1016
  }
@@ -1075,134 +1220,23 @@ var ButtonEmpty = import_styled_components3.default.div`
1075
1220
  `;
1076
1221
 
1077
1222
  // src/PreviewButton/PreviewButton.tsx
1078
- var import_react_accessible_dropdown_menu_hook = __toESM(require("react-accessible-dropdown-menu-hook"), 1);
1079
-
1080
- // ../ui/icons/DownIcon.tsx
1081
- var import_jsx_runtime5 = require("react/jsx-runtime");
1082
- var DownIcon = ({ rotate = 0, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1083
- "svg",
1084
- {
1085
- version: "1.2",
1086
- xmlns: "http://www.w3.org/2000/svg",
1087
- overflow: "visible",
1088
- preserveAspectRatio: "none",
1089
- viewBox: "0 0 24 24",
1090
- width: "1em",
1091
- height: "1em",
1092
- style: {
1093
- fill: "rgba(0, 0, 0, 0.6)",
1094
- transform: `rotate(${rotate}deg)`,
1095
- transition: "transform 0.2s"
1096
- },
1097
- ...props,
1098
- children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1099
- "path",
1100
- {
1101
- d: "M8.12 9.29 12 13.17l3.88-3.88a.996.996 0 1 1 1.41 1.41l-4.59 4.59a.996.996 0 0 1-1.41 0L6.7 10.7a.996.996 0 0 1 0-1.41c.39-.38 1.03-.39 1.42 0z",
1102
- fill: "currentColor"
1103
- }
1104
- )
1105
- }
1106
- );
1107
-
1108
- // ../ui/icons/CloseIcon.tsx
1109
- var import_jsx_runtime6 = require("react/jsx-runtime");
1110
- var CloseIcon = ({ height = 16 }) => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("svg", { xmlns: "http://www.w3.org/2000/svg", height, viewBox: "0 0 24 24", width: "24px", fill: "#000000", children: [
1111
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M0 0h24v24H0z", fill: "none" }),
1112
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z" })
1113
- ] });
1114
-
1115
- // src/PreviewButton/PreviewButton.tsx
1116
- var import_react_iiif_vault3 = require("react-iiif-vault");
1117
- var import_components = require("@manifest-editor/components");
1118
-
1119
- // src/ConfigContext/ConfigContext.tsx
1120
- var import_react7 = require("react");
1121
- var import_jsx_runtime7 = require("react/jsx-runtime");
1122
- var DEFAULT_CONFIG = {
1123
- previews: [],
1124
- behaviorPresets: [
1125
- "auto-advance",
1126
- "no-auto-advance",
1127
- "repeat",
1128
- "no-repeat",
1129
- "unordered",
1130
- "individuals",
1131
- "continuous",
1132
- "paged",
1133
- "non-paged",
1134
- "facing-pages",
1135
- "multi-part",
1136
- "together",
1137
- "sequence",
1138
- "thumbnail-nav",
1139
- "no-nav",
1140
- "hidden"
1141
- ],
1142
- defaultPreview: null,
1143
- editorConfig: {},
1144
- newTemplates: null,
1145
- i18n: {
1146
- advancedLanguageMode: false,
1147
- availableLanguages: ["en", "cy", "nl", "fr"],
1148
- defaultLanguage: "en"
1149
- },
1150
- editorFeatureFlags: {
1151
- enableMultiImageCanvases: true,
1152
- enableMultiMediaCanvases: true
1153
- },
1154
- uploadBackends: [],
1155
- export: {
1156
- baseIdentifier: null,
1157
- version: 3
1158
- }
1159
- };
1160
- var ConfigReactContext = (0, import_react7.createContext)(DEFAULT_CONFIG);
1161
- var SaveConfigReactContext = (0, import_react7.createContext)(() => {
1162
- });
1163
- function useConfig() {
1164
- return (0, import_react7.useContext)(ConfigReactContext);
1165
- }
1166
- function useSaveConfig() {
1167
- return (0, import_react7.useContext)(SaveConfigReactContext);
1168
- }
1169
- function ConfigProvider({
1170
- children,
1171
- config,
1172
- saveConfig
1173
- }) {
1174
- const [runtimeConfig, setRuntimeConfig] = (0, import_react7.useState)(null);
1175
- const resolvedConfig = (0, import_react7.useMemo)(
1176
- () => ({
1177
- ...DEFAULT_CONFIG,
1178
- ...config || {},
1179
- ...runtimeConfig || {}
1180
- }),
1181
- [config, runtimeConfig]
1182
- );
1183
- const memoSaveConfig = (0, import_react7.useCallback)(
1184
- (config2) => {
1185
- setRuntimeConfig(config2);
1186
- if (saveConfig) {
1187
- saveConfig(config2);
1188
- }
1189
- },
1190
- [config]
1191
- );
1192
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(SaveConfigReactContext.Provider, { value: memoSaveConfig, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ConfigReactContext.Provider, { value: resolvedConfig, children }) });
1193
- }
1194
-
1195
- // src/PreviewButton/PreviewButton.tsx
1196
- var import_jsx_runtime8 = require("react/jsx-runtime");
1197
- function PreviewButton({ downloadEnabled, fileName }) {
1198
- const { active, configs, actions, selected } = usePreviewContext();
1199
- const vault = (0, import_react_iiif_vault3.useVault)();
1200
- const config = useConfig();
1201
- const resource = useAppResource();
1202
- const configsToShow = configs.filter((c) => c.type === "external-manifest-preview");
1203
- const { isOpen, buttonProps, itemProps } = (0, import_react_accessible_dropdown_menu_hook.default)(configsToShow.length);
1204
- if (configsToShow.length === 0) {
1205
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(ButtonEmpty, { children: "Preview not available" });
1223
+ var import_jsx_runtime8 = require("react/jsx-runtime");
1224
+ function PreviewButton({
1225
+ downloadEnabled,
1226
+ fileName
1227
+ }) {
1228
+ const { active, configs, actions, selected } = usePreviewContext();
1229
+ const vault = (0, import_react_iiif_vault3.useVault)();
1230
+ const config = useConfig();
1231
+ const resource = useAppResource();
1232
+ const configsToShow = configs.filter(
1233
+ (c) => c.type === "external-manifest-preview"
1234
+ );
1235
+ const { isOpen, buttonProps, itemProps } = (0, import_react_accessible_dropdown_menu_hook.default)(
1236
+ configsToShow.length
1237
+ );
1238
+ if (configsToShow.length === 0) {
1239
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(ButtonEmpty, { children: "Preview not available" });
1206
1240
  }
1207
1241
  return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_jsx_runtime8.Fragment, { children: [
1208
1242
  downloadEnabled ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "mr-4", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
@@ -1212,9 +1246,17 @@ function PreviewButton({ downloadEnabled, fileName }) {
1212
1246
  label: "Download manifest",
1213
1247
  getData: () => {
1214
1248
  if (config.export && config.export.version === 2) {
1215
- return JSON.stringify(vault.toPresentation2(resource), null, 2);
1249
+ return JSON.stringify(
1250
+ vault.toPresentation2(resource),
1251
+ null,
1252
+ 2
1253
+ );
1216
1254
  }
1217
- return JSON.stringify(vault.toPresentation3(resource), null, 2);
1255
+ return JSON.stringify(
1256
+ vault.toPresentation3(resource),
1257
+ null,
1258
+ 2
1259
+ );
1218
1260
  }
1219
1261
  }
1220
1262
  ) }) : null,
@@ -1228,7 +1270,6 @@ function PreviewButton({ downloadEnabled, fileName }) {
1228
1270
  if (defaultPreviewId) {
1229
1271
  const found = configs.find((c) => c.id === defaultPreviewId);
1230
1272
  if (found) {
1231
- console.log(found, { defaultPreviewId });
1232
1273
  actions.selectPreview(found.id);
1233
1274
  actions.updatePreviews();
1234
1275
  return;
@@ -1245,9 +1286,29 @@ function PreviewButton({ downloadEnabled, fileName }) {
1245
1286
  /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(MenuContainer, { $open: isOpen, children: configsToShow.map((config2, key) => {
1246
1287
  const inactive = active.indexOf(config2.id) === -1;
1247
1288
  return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(MenuItem, { ...itemProps[key], children: [
1248
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(MenuItemStatus, { $status: inactive ? "available" : config2.id === selected ? "active" : "configured" }),
1249
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(MenuItemLabel, { onClick: () => actions.selectPreview(config2.id), children: config2.label }),
1250
- !inactive ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(MenuItemClose, { onClick: () => actions.deletePreview(config2.id), children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(CloseIcon, {}) }) : null
1289
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1290
+ MenuItemStatus,
1291
+ {
1292
+ $status: inactive ? "available" : config2.id === selected ? "active" : "configured"
1293
+ }
1294
+ ),
1295
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1296
+ MenuItemLabel,
1297
+ {
1298
+ onClick: () => {
1299
+ actions.selectPreview(config2.id);
1300
+ actions.updatePreviews();
1301
+ },
1302
+ children: config2.label
1303
+ }
1304
+ ),
1305
+ !inactive ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1306
+ MenuItemClose,
1307
+ {
1308
+ onClick: () => actions.deletePreview(config2.id),
1309
+ children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(CloseIcon, {})
1310
+ }
1311
+ ) : null
1251
1312
  ] }, config2.id);
1252
1313
  }) })
1253
1314
  ] })
@@ -1288,161 +1349,456 @@ function AppMenuProvider({ children, menu }) {
1288
1349
  return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ReactAppMenuContext.Provider, { value: menu, children });
1289
1350
  }
1290
1351
 
1291
- // src/BaseCreator/BaseCreator.tsx
1292
- var import_react17 = require("react");
1293
- var import_react_iiif_vault7 = require("react-iiif-vault");
1294
- var import_parser3 = require("@iiif/parser");
1352
+ // src/AtlasStore/AtlasStoreProvider.tsx
1353
+ var import_react11 = require("react");
1295
1354
 
1296
- // ../ui/madoc/components/icons/Spinner.tsx
1297
- var import_jsx_runtime11 = require("react/jsx-runtime");
1298
- function Spinner(props) {
1299
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("svg", { width: "1em", height: "1em", viewBox: "0 0 42 42", xmlns: "http://www.w3.org/2000/svg", stroke: "#fff", ...props, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("g", { transform: "translate(2 2)", strokeWidth: 5, fill: "none", fillRule: "evenodd", children: [
1300
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("circle", { strokeOpacity: 0.5, cx: 18, cy: 18, r: 18 }),
1301
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("path", { d: "M36 18c0-9.94-8.06-18-18-18", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1302
- "animateTransform",
1303
- {
1304
- attributeName: "transform",
1305
- type: "rotate",
1306
- from: "0 18 18",
1307
- to: "360 18 18",
1308
- dur: "1s",
1309
- repeatCount: "indefinite"
1310
- }
1311
- ) })
1312
- ] }) });
1313
- }
1355
+ // src/AtlasStore/AtlasStore.ts
1356
+ var import_polygon_editor = require("polygon-editor");
1357
+ var import_vanilla = require("zustand/vanilla");
1314
1358
 
1315
- // src/highlighted-image-resources.ts
1316
- var import_zustand = require("zustand");
1317
- var import_react10 = require("react");
1318
-
1319
- // src/helpers.ts
1320
- var import_parser = require("@iiif/parser");
1321
- async function getManifestNomalized(id) {
1322
- let responseData = void 0;
1323
- try {
1324
- await fetch(id).then((response) => {
1325
- return response.json().catch((err) => {
1326
- console.error(`'${err}' happened!`);
1327
- });
1328
- }).then((data) => {
1329
- responseData = { ...data };
1330
- });
1331
- } catch (error) {
1332
- console.log(error);
1359
+ // src/AtlasStore/polygon-to-bounding-box.ts
1360
+ function polygonToBoundingBox(polygon) {
1361
+ if (!polygon) {
1362
+ return null;
1333
1363
  }
1334
- return responseData;
1335
- }
1336
- function createActionIdentity(type, property, parent) {
1337
- return `create_${type}_${property}_${(0, import_parser.toRef)(parent)?.type || "unknown"}`;
1338
- }
1339
- function createDownload(data, fileName, fileType = "text/json") {
1340
- const blob = data instanceof Blob ? data : new Blob([data], { type: fileType });
1341
- const a = document.createElement("a");
1342
- a.download = fileName;
1343
- a.href = window.URL.createObjectURL(blob);
1344
- const clickEvt = new MouseEvent("click", {
1345
- view: window,
1346
- bubbles: true,
1347
- cancelable: true
1348
- });
1349
- a.dispatchEvent(clickEvt);
1350
- a.remove();
1351
- }
1352
- async function copyToClipboard(json) {
1353
- return navigator.clipboard.writeText(typeof json === "string" ? json : JSON.stringify(json, null, 2));
1354
- }
1355
- function randomId() {
1356
- return `${Math.random().toString(36).substr(2)}-${Date.now().toString(36)}`;
1364
+ if (polygon.points.length > 2) {
1365
+ const x1 = Math.min(...polygon.points.map((p) => p[0]));
1366
+ const y1 = Math.min(...polygon.points.map((p) => p[1]));
1367
+ const x2 = Math.max(0, ...polygon.points.map((p) => p[0]));
1368
+ const y2 = Math.max(0, ...polygon.points.map((p) => p[1]));
1369
+ return {
1370
+ x: x1,
1371
+ y: y1,
1372
+ width: x2 - x1,
1373
+ height: y2 - y1
1374
+ };
1375
+ }
1376
+ return null;
1357
1377
  }
1358
- function mapApp(input, map) {
1359
- const { default: metadata, ...props } = input;
1360
- const app = {
1361
- metadata,
1362
- layout: {
1363
- leftPanels: [],
1364
- rightPanels: [],
1365
- centerPanels: [],
1366
- ...props
1367
- }
1378
+
1379
+ // src/AtlasStore/AtlasStore.ts
1380
+ function polygonToTarget(polygon) {
1381
+ if (!polygon)
1382
+ return null;
1383
+ return {
1384
+ type: "SvgSelector",
1385
+ value: `<svg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'><g><path d='M${polygon.points.map((p) => p.join(",")).join(" ")}${polygon.open ? "" : " Z"}' /></g></svg>`
1368
1386
  };
1369
- return map ? map(app) : app;
1370
1387
  }
1371
-
1372
- // src/highlighted-image-resources.ts
1373
- var useHighlightedImageResource = (0, import_zustand.create)((set) => ({
1374
- regions: {},
1375
- resources: [],
1376
- setRegion: (id, region) => {
1377
- set((ex) => ({ ...ex.regions, regions: { [id]: region || null } }));
1378
- },
1379
- setHighlight: (id) => {
1380
- set({ resources: Array.isArray(id) ? id : [id] });
1381
- },
1382
- highlight: (id) => {
1383
- set((s) => {
1384
- if (s.resources.indexOf(id) !== -1) {
1385
- return s;
1386
- }
1387
- return { resources: [...s.resources, id] };
1388
- });
1389
- },
1390
- clearHighlight: (id) => {
1391
- set((s) => ({ resources: s.resources.filter((item) => item !== id) }));
1388
+ function requestToAnnotationResponse(request) {
1389
+ if (request.type === "polygon") {
1390
+ return {
1391
+ polygon: {
1392
+ points: request.points || [],
1393
+ open: request.open || false
1394
+ },
1395
+ requestType: "polygon",
1396
+ boundingBox: polygonToBoundingBox({
1397
+ points: request.points || [],
1398
+ open: false
1399
+ }),
1400
+ target: polygonToTarget({ points: request.points || [], open: false })
1401
+ };
1392
1402
  }
1393
- }));
1394
- function useTemporaryHighlight(newValue) {
1395
- const id = (0, import_react10.useMemo)(() => randomId(), []);
1396
- const value = useHighlightedImageResource((s) => s.regions[id]);
1397
- const setRegion = useHighlightedImageResource((s) => s.setRegion);
1398
- (0, import_react10.useEffect)(() => {
1399
- if (value && newValue) {
1400
- if (value !== newValue && (value.x !== newValue.x || value.y !== newValue.y || value.width !== newValue.width || value.height !== newValue.height)) {
1401
- setRegion(id, newValue || null);
1402
- }
1403
- } else {
1404
- setRegion(id, newValue || null);
1405
- }
1406
- }, [value]);
1407
- (0, import_react10.useEffect)(() => {
1408
- return () => setRegion(id, null);
1409
- }, []);
1403
+ const box = request.selector;
1404
+ if (box) {
1405
+ const points = [
1406
+ [box.x, box.y],
1407
+ [box.x + box.width, box.y],
1408
+ [box.x + box.width, box.y + box.height],
1409
+ [box.x, box.y + box.height]
1410
+ ];
1411
+ return {
1412
+ polygon: {
1413
+ points,
1414
+ open: false
1415
+ },
1416
+ requestType: request.type,
1417
+ boundingBox: box,
1418
+ target: polygonToTarget({ points, open: false })
1419
+ };
1420
+ }
1421
+ return {
1422
+ polygon: { points: [], open: false },
1423
+ requestType: request.type,
1424
+ boundingBox: null,
1425
+ target: null
1426
+ };
1410
1427
  }
1411
- function useHoverHighlightImageResource(id) {
1412
- const highlight = useHighlightedImageResource((s) => s.highlight);
1413
- const clear = useHighlightedImageResource((s) => s.clearHighlight);
1414
- (0, import_react10.useEffect)(() => {
1415
- return () => {
1416
- if (id) {
1417
- clear(id);
1418
- }
1428
+ var defaultSlowState = {
1429
+ shapeId: null,
1430
+ noShape: true,
1431
+ transitioning: false,
1432
+ actionIntentType: null,
1433
+ transitionIntentType: null,
1434
+ selectedPoints: [],
1435
+ hasClosestLine: false,
1436
+ modifiers: {
1437
+ Alt: false,
1438
+ Shift: false,
1439
+ Meta: false,
1440
+ proximity: 0
1441
+ // default value.
1442
+ },
1443
+ showBoundingBox: false,
1444
+ currentModifiers: {},
1445
+ validIntentKeys: {},
1446
+ pointerInsideShape: false,
1447
+ closestPoint: null,
1448
+ transitionModifiers: null,
1449
+ selectedStamp: null,
1450
+ lineMode: false,
1451
+ lineBoxMode: false,
1452
+ drawMode: false,
1453
+ bezierLines: [],
1454
+ boxMode: false,
1455
+ fixedAspectRatio: false
1456
+ };
1457
+ function createAtlasStore({ events: events2 }) {
1458
+ const store = (0, import_vanilla.createStore)((set, get) => {
1459
+ let runtime = null;
1460
+ const onSave = (input) => {
1461
+ set(
1462
+ (s) => s.tool.requestId ? { polygon: { ...input, id: s.tool.requestId } } : {
1463
+ polygon: { id: void 0, points: [], open: true }
1464
+ }
1465
+ );
1419
1466
  };
1420
- }, [clear, id]);
1421
- return (0, import_react10.useMemo)(() => {
1467
+ const polygons = (0, import_polygon_editor.createHelper)(null, onSave);
1422
1468
  return {
1423
- onMouseEnter() {
1424
- if (id) {
1425
- highlight(id);
1469
+ mode: "explore",
1470
+ tool: {
1471
+ enabled: false,
1472
+ requestId: null,
1473
+ canvasId: null
1474
+ },
1475
+ requestType: null,
1476
+ history: polygons.history,
1477
+ polygon: null,
1478
+ validRequestIds: [],
1479
+ stableViewport: null,
1480
+ canvasRelativePositions: {},
1481
+ canvasViewports: {},
1482
+ polygons,
1483
+ polygonState: defaultSlowState,
1484
+ setToolCanvasId: (canvasId) => {
1485
+ set((state) => ({ tool: { ...state.tool, canvasId } }));
1486
+ },
1487
+ switchTool: {
1488
+ draw() {
1489
+ set({ mode: "sketch" });
1490
+ helper.stamps.clear();
1491
+ helper.draw.enable();
1492
+ },
1493
+ polygon() {
1494
+ set({ mode: "sketch" });
1495
+ helper.stamps.clear();
1496
+ helper.draw.disable();
1497
+ helper.modes.disableLineBoxMode();
1498
+ helper.modes.disableLineMode();
1499
+ },
1500
+ line() {
1501
+ set({ mode: "sketch" });
1502
+ helper.modes.enableLineMode();
1503
+ },
1504
+ lineBox() {
1505
+ set({ mode: "sketch" });
1506
+ helper.modes.enableLineBoxMode();
1507
+ },
1508
+ square() {
1509
+ set({ mode: "sketch" });
1510
+ helper.stamps.square();
1511
+ },
1512
+ triangle() {
1513
+ set({ mode: "sketch" });
1514
+ helper.stamps.triangle();
1515
+ },
1516
+ hexagon() {
1517
+ set({ mode: "sketch" });
1518
+ helper.stamps.hexagon();
1519
+ },
1520
+ circle() {
1521
+ set({ mode: "sketch" });
1522
+ helper.stamps.circle();
1523
+ },
1524
+ remove() {
1525
+ helper.key.down("Backspace");
1426
1526
  }
1427
1527
  },
1428
- onMouseLeave() {
1429
- if (id) {
1430
- clear(id);
1528
+ reset: () => {
1529
+ const state = get();
1530
+ if (state.tool.requestId) {
1531
+ state.cancelRequest(state.tool.requestId);
1431
1532
  }
1533
+ },
1534
+ setPolygonState: (state) => set({
1535
+ polygonState: typeof state === "function" ? state(get().polygonState) : state
1536
+ }),
1537
+ getRequestId: () => {
1538
+ const requestId = Math.random().toString(36).slice(2);
1539
+ set((state) => ({
1540
+ validRequestIds: [...state.validRequestIds, requestId]
1541
+ }));
1542
+ return {
1543
+ requestId,
1544
+ clear: () => {
1545
+ if (get().tool.requestId === requestId) {
1546
+ }
1547
+ set((state) => ({
1548
+ tool: state.tool.requestId === requestId ? { enabled: false, requestId: null, canvasId: null } : state.tool,
1549
+ validRequestIds: state.validRequestIds.filter((id) => id !== requestId)
1550
+ }));
1551
+ }
1552
+ };
1553
+ },
1554
+ cancelRequest: (requestId) => {
1555
+ set((state) => ({
1556
+ mode: "explore",
1557
+ tool: state.tool.requestId === requestId ? { enabled: false, requestId: null, canvasId: null } : state.tool,
1558
+ validRequestIds: state.validRequestIds.filter((id) => id !== requestId)
1559
+ }));
1560
+ events2.emit("atlas.request-cancelled", { id: requestId });
1561
+ },
1562
+ requestAnnotation: async (request, options) => {
1563
+ const response = requestToAnnotationResponse(request);
1564
+ try {
1565
+ const { points = [], open = true } = response.polygon || {};
1566
+ const { requestId, canvasId = null, toolId } = options;
1567
+ const state = get();
1568
+ const isValid = state.validRequestIds.includes(requestId);
1569
+ if (!isValid)
1570
+ return null;
1571
+ if (state.tool.enabled)
1572
+ return null;
1573
+ polygons.setShape({ id: requestId, points, open });
1574
+ if (request.type === "box") {
1575
+ polygons.modes.enableBoxMode();
1576
+ }
1577
+ if (request.type === "target") {
1578
+ polygons.modes.enableBoxMode();
1579
+ polygons.modes.lockAspectRatio();
1580
+ }
1581
+ events2.emit("atlas.annotation-request", { id: requestId });
1582
+ set({
1583
+ polygon: { id: requestId, points, open },
1584
+ mode: "sketch",
1585
+ requestType: request.type,
1586
+ tool: {
1587
+ enabled: true,
1588
+ requestId,
1589
+ canvasId
1590
+ }
1591
+ });
1592
+ if (toolId) {
1593
+ state.switchTool[toolId]?.();
1594
+ } else if (points.length === 0) {
1595
+ state.switchTool.square();
1596
+ }
1597
+ return new Promise((resolve) => {
1598
+ const cancelHandler = (e) => {
1599
+ if (e.id !== requestId)
1600
+ return;
1601
+ set({
1602
+ mode: "explore",
1603
+ tool: {
1604
+ requestId: null,
1605
+ enabled: false,
1606
+ canvasId: null
1607
+ }
1608
+ });
1609
+ events2.off("atlas.request-cancelled", cancelHandler);
1610
+ events2.off("atlas.annotation-completed", handler);
1611
+ resolve(null);
1612
+ };
1613
+ const handler = (e) => {
1614
+ if (e.id !== requestId)
1615
+ return;
1616
+ set({
1617
+ mode: "explore",
1618
+ tool: {
1619
+ requestId: null,
1620
+ enabled: false,
1621
+ canvasId: null
1622
+ }
1623
+ });
1624
+ events2.off("atlas.annotation-completed", handler);
1625
+ events2.off("atlas.request-cancelled", cancelHandler);
1626
+ resolve(e);
1627
+ };
1628
+ events2.on("atlas.request-cancelled", cancelHandler);
1629
+ events2.on("atlas.annotation-completed", handler);
1630
+ });
1631
+ } catch (err) {
1632
+ return null;
1633
+ }
1634
+ },
1635
+ completeRequest: (requestId) => {
1636
+ if (typeof requestId === "string" && requestId) {
1637
+ if (requestId !== get().tool.requestId) {
1638
+ return;
1639
+ }
1640
+ }
1641
+ const polygon = get().polygon;
1642
+ if (!polygon)
1643
+ return;
1644
+ events2.emit("atlas.annotation-completed", {
1645
+ id: polygon.id,
1646
+ polygon,
1647
+ requestType: get().requestType,
1648
+ target: polygonToTarget(polygon),
1649
+ canvasId: get().tool.canvasId,
1650
+ boundingBox: polygonToBoundingBox(polygon)
1651
+ });
1652
+ },
1653
+ setAtlasRuntime: (newRuntime) => {
1654
+ runtime = newRuntime;
1655
+ events2.emit("atlas.ready", { runtime: newRuntime });
1656
+ runtime.world.addLayoutSubscriber((ev, data) => {
1657
+ if (ev === "event-activation" || ev === "zoom-to" || ev === "go-home") {
1658
+ if (runtime?._lastGoodScale && !Number.isNaN(runtime._lastGoodScale)) {
1659
+ helper.setScale(1 / runtime._lastGoodScale);
1660
+ }
1661
+ }
1662
+ });
1663
+ },
1664
+ clearAtlasRuntime: () => {
1665
+ runtime = null;
1666
+ set({ stableViewport: null });
1667
+ },
1668
+ setCanvasRelativePosition: (canvasId, position) => {
1669
+ set((state) => ({
1670
+ canvasRelativePositions: {
1671
+ ...state.canvasRelativePositions,
1672
+ [canvasId]: position
1673
+ }
1674
+ }));
1675
+ },
1676
+ clearCanvasRelativePosition: (canvasId) => {
1677
+ set((state) => {
1678
+ const newPositions = { ...state.canvasRelativePositions };
1679
+ delete newPositions[canvasId];
1680
+ return { canvasRelativePositions: newPositions };
1681
+ });
1682
+ },
1683
+ changeMode: (mode) => {
1684
+ set({ mode });
1685
+ },
1686
+ // Navigation controls
1687
+ nudgeLeft: () => {
1688
+ },
1689
+ nudgeRight: () => {
1690
+ },
1691
+ nudgeUp: () => {
1692
+ },
1693
+ nudgeDown: () => {
1694
+ },
1695
+ zoomIn: () => {
1696
+ runtime?.world?.zoomIn();
1697
+ },
1698
+ zoomOut: () => {
1699
+ runtime?.world?.zoomOut();
1700
+ },
1701
+ goHome: () => {
1702
+ runtime?.world?.goHome();
1432
1703
  }
1433
1704
  };
1434
- }, [id, highlight, clear]);
1705
+ });
1706
+ const helper = store.getState().polygons;
1707
+ events2.on("atlas.annotation-request", () => {
1708
+ helper.clock.start((state, slowState, dt) => {
1709
+ events2.emit("atlas.polygon-render", { state, slowState, dt });
1710
+ }, store.getState().setPolygonState);
1711
+ });
1712
+ events2.on("atlas.annotation-completed", () => {
1713
+ helper.clock.stop();
1714
+ });
1715
+ events2.on("atlas.request-cancelled", () => {
1716
+ helper.clock.stop();
1717
+ });
1718
+ return store;
1719
+ }
1720
+
1721
+ // src/hooks/use-event.tsx
1722
+ var import_mitt2 = __toESM(require("mitt"), 1);
1723
+ var import_react10 = require("react");
1724
+ var import_jsx_runtime11 = require("react/jsx-runtime");
1725
+ var events = (0, import_mitt2.default)();
1726
+ var ReactEmitterContext = (0, import_react10.createContext)(events);
1727
+ function EventEmitterProvider({
1728
+ children,
1729
+ emitter
1730
+ }) {
1731
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(ReactEmitterContext.Provider, { value: emitter, children });
1732
+ }
1733
+ function useEmitter() {
1734
+ return (0, import_react10.useContext)(ReactEmitterContext);
1735
+ }
1736
+ function useEvent(key, listener, deps = []) {
1737
+ const emitter = (0, import_react10.useContext)(ReactEmitterContext);
1738
+ (0, import_react10.useEffect)(() => {
1739
+ const handler = (data) => {
1740
+ listener(data);
1741
+ };
1742
+ emitter.on(key, handler);
1743
+ return () => {
1744
+ emitter.off(key, handler);
1745
+ };
1746
+ }, [emitter, key, ...deps]);
1747
+ }
1748
+
1749
+ // src/AtlasStore/AtlasStoreProvider.tsx
1750
+ var import_jsx_runtime12 = require("react/jsx-runtime");
1751
+ var AtlasStoreReactContext = (0, import_react11.createContext)(null);
1752
+ function useAtlasStore() {
1753
+ return (0, import_react11.useContext)(AtlasStoreReactContext);
1754
+ }
1755
+ function AtlasStoreProvider({
1756
+ children
1757
+ }) {
1758
+ const emitter = useEmitter();
1759
+ const value = (0, import_react11.useMemo)(() => {
1760
+ return createAtlasStore({ events: emitter });
1761
+ }, []);
1762
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(AtlasStoreReactContext.Provider, { value, children });
1763
+ }
1764
+
1765
+ // src/BaseCreator/BaseCreator.tsx
1766
+ var import_parser3 = require("@iiif/parser");
1767
+ var import_components4 = require("@manifest-editor/components");
1768
+ var import_creator_api2 = require("@manifest-editor/creator-api");
1769
+
1770
+ // ../ui/madoc/components/icons/Spinner.tsx
1771
+ var import_jsx_runtime13 = require("react/jsx-runtime");
1772
+ function Spinner(props) {
1773
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("svg", { width: "1em", height: "1em", viewBox: "0 0 42 42", xmlns: "http://www.w3.org/2000/svg", stroke: "#fff", ...props, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("g", { transform: "translate(2 2)", strokeWidth: 5, fill: "none", fillRule: "evenodd", children: [
1774
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("circle", { strokeOpacity: 0.5, cx: 18, cy: 18, r: 18 }),
1775
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("path", { d: "M36 18c0-9.94-8.06-18-18-18", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1776
+ "animateTransform",
1777
+ {
1778
+ attributeName: "transform",
1779
+ type: "rotate",
1780
+ from: "0 18 18",
1781
+ to: "360 18 18",
1782
+ dur: "1s",
1783
+ repeatCount: "indefinite"
1784
+ }
1785
+ ) })
1786
+ ] }) });
1435
1787
  }
1436
1788
 
1789
+ // src/BaseCreator/BaseCreator.tsx
1790
+ var import_react19 = require("react");
1791
+ var import_react_iiif_vault7 = require("react-iiif-vault");
1792
+
1437
1793
  // src/Layout/Layout.context.tsx
1438
- var import_react11 = require("react");
1439
- var LayoutActionsReactContext = (0, import_react11.createContext)(null);
1440
- var LayoutStateReactContext = (0, import_react11.createContext)(null);
1794
+ var import_react12 = require("react");
1795
+ var LayoutActionsReactContext = (0, import_react12.createContext)(null);
1796
+ var LayoutStateReactContext = (0, import_react12.createContext)(null);
1441
1797
  function useLayoutState() {
1442
- return (0, import_react11.useContext)(LayoutStateReactContext);
1798
+ return (0, import_react12.useContext)(LayoutStateReactContext);
1443
1799
  }
1444
1800
  function useLayoutActions() {
1445
- return (0, import_react11.useContext)(LayoutActionsReactContext);
1801
+ return (0, import_react12.useContext)(LayoutActionsReactContext);
1446
1802
  }
1447
1803
  function useAvailableLayouts() {
1448
1804
  const app = useApp();
@@ -1451,22 +1807,22 @@ function useAvailableLayouts() {
1451
1807
  function useLayoutProvider() {
1452
1808
  const app = useApp();
1453
1809
  const layout = app.layout;
1454
- const actions = (0, import_react11.useContext)(LayoutActionsReactContext);
1455
- const state = (0, import_react11.useContext)(LayoutStateReactContext);
1456
- return (0, import_react11.useMemo)(() => {
1810
+ const actions = (0, import_react12.useContext)(LayoutActionsReactContext);
1811
+ const state = (0, import_react12.useContext)(LayoutStateReactContext);
1812
+ return (0, import_react12.useMemo)(() => {
1457
1813
  return { actions, state, ...layout };
1458
1814
  }, [app, state]);
1459
1815
  }
1460
1816
 
1461
1817
  // src/Layout/components/ModularPanel.tsx
1462
- var import_styled_components8 = __toESM(require("styled-components"), 1);
1818
+ var import_styled_components6 = __toESM(require("styled-components"), 1);
1463
1819
 
1464
1820
  // ../ui/icons/StarIcon.tsx
1465
- var import_jsx_runtime12 = require("react/jsx-runtime");
1466
- var StarIcon = (props) => /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("svg", { xmlns: "http://www.w3.org/2000/svg", height: "1em", width: "1em", viewBox: "0 0 24 24", ...props, children: [
1467
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("path", { d: "M0 0h24v24H0z", fill: "none" }),
1468
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("path", { d: "M0 0h24v24H0z", fill: "none" }),
1469
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1821
+ var import_jsx_runtime14 = require("react/jsx-runtime");
1822
+ var StarIcon = (props) => /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("svg", { xmlns: "http://www.w3.org/2000/svg", height: "1em", width: "1em", viewBox: "0 0 24 24", ...props, children: [
1823
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("path", { d: "M0 0h24v24H0z", fill: "none" }),
1824
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("path", { d: "M0 0h24v24H0z", fill: "none" }),
1825
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1470
1826
  "path",
1471
1827
  {
1472
1828
  d: "M12 17.27 18.18 21l-1.64-7.03L22 9.24l-7.19-.61L12 2 9.19 8.63 2 9.24l5.46 4.73L5.82 21z",
@@ -1476,15 +1832,15 @@ var StarIcon = (props) => /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("svg",
1476
1832
  ] });
1477
1833
 
1478
1834
  // ../ui/icons/BackIcon.tsx
1479
- var import_jsx_runtime13 = require("react/jsx-runtime");
1480
- var BackIcon = ({ style }) => /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("svg", { xmlns: "http://www.w3.org/2000/svg", height: "1rem", viewBox: "0 0 24 24", width: "1rem", fill: "#000000", style, children: [
1481
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("path", { d: "M0 0h24v24H0z", fill: "none" }),
1482
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("path", { d: "M20 11H7.83l5.59-5.59L12 4l-8 8 8 8 1.41-1.41L7.83 13H20v-2z" })
1835
+ var import_jsx_runtime15 = require("react/jsx-runtime");
1836
+ var BackIcon = ({ style }) => /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("svg", { xmlns: "http://www.w3.org/2000/svg", height: "1rem", viewBox: "0 0 24 24", width: "1rem", fill: "#000000", style, children: [
1837
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("path", { d: "M0 0h24v24H0z", fill: "none" }),
1838
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("path", { d: "M20 11H7.83l5.59-5.59L12 4l-8 8 8 8 1.41-1.41L7.83 13H20v-2z" })
1483
1839
  ] });
1484
1840
 
1485
1841
  // src/Layout/components/ModularPanel.tsx
1486
1842
  var import_react_error_boundary = require("react-error-boundary");
1487
- var import_react14 = require("react");
1843
+ var import_react15 = require("react");
1488
1844
 
1489
1845
  // ../ui/atoms/PaddedSidebarContainer.tsx
1490
1846
  var import_styled_components4 = __toESM(require("styled-components"), 1);
@@ -1495,75 +1851,21 @@ var PaddedSidebarContainer = import_styled_components4.default.div`
1495
1851
  overflow: visible;
1496
1852
  `;
1497
1853
 
1498
- // ../ui/madoc/components/callouts/ErrorMessage.tsx
1499
- var import_styled_components6 = __toESM(require("styled-components"), 1);
1500
-
1501
- // ../ui/madoc/components/callouts/BaseMessage.tsx
1502
- var import_styled_components5 = __toESM(require("styled-components"), 1);
1503
- var BaseMessage = import_styled_components5.default.div`
1504
- background: #000;
1505
- color: #fff;
1506
- width: 100%;
1507
- padding: 0.5em 1em;
1508
- line-height: 1.9em;
1509
- display: flex;
1510
-
1511
- a {
1512
- color: #fff;
1513
- }
1514
-
1515
- svg {
1516
- fill: #fff;
1517
- margin: 0 0.5em;
1518
- vertical-align: text-bottom;
1519
- }
1520
-
1521
- ${(props) => props.$small && import_styled_components5.css`
1522
- font-size: 0.75em;
1523
- padding: 0.25em 0.5em;
1524
- line-height: 1.6em;
1525
- `}
1526
-
1527
- ${(props) => props.$wide && import_styled_components5.css`
1528
- margin-left: -2em;
1529
- margin-right: -2em;
1530
- width: auto;
1531
- svg {
1532
- height: 0.8em;
1533
- vertical-align: baseline;
1534
- }
1535
- `}
1536
-
1537
- ${(props) => props.$margin && import_styled_components5.css`
1538
- margin-bottom: 1em;
1539
- `}
1540
-
1541
- ${(props) => props.$banner && import_styled_components5.css`
1542
- border-radius: 5px;
1543
- box-shadow: 0 3px 15px 0 rgb(0 0 0 / 16%);
1544
- `}
1545
- `;
1546
-
1547
- // ../ui/madoc/components/callouts/ErrorMessage.tsx
1548
- var ErrorMessage = (0, import_styled_components6.default)(BaseMessage)`
1549
- background: #c74158;
1550
- color: #fff;
1551
- `;
1552
-
1553
1854
  // src/Layout/components/PanelError.tsx
1554
- var import_react12 = require("react");
1555
- var import_jsx_runtime14 = require("react/jsx-runtime");
1855
+ var import_components3 = require("@manifest-editor/components");
1856
+ var import_react13 = require("react");
1857
+ var import_jsx_runtime16 = require("react/jsx-runtime");
1556
1858
  function PanelError(props) {
1557
1859
  let error = props.error.toString();
1558
- const [isFixing, setIsFixing] = (0, import_react12.useState)(false);
1559
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(PaddedSidebarContainer, { children: [
1560
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(ErrorMessage, { $margin: true, children: error }),
1561
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(CalltoButton, { onClick: props.resetErrorBoundary, children: "Try again" })
1860
+ const [isFixing, setIsFixing] = (0, import_react13.useState)(false);
1861
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(PaddedSidebarContainer, { children: [
1862
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_components3.ErrorMessage, { className: "mb-2", children: error }),
1863
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(CalltoButton, { onClick: props.resetErrorBoundary, children: "Try again" })
1562
1864
  ] });
1563
1865
  }
1564
1866
 
1565
1867
  // src/Layout/Layout.helpers.ts
1566
- var import_react13 = require("react");
1868
+ var import_react14 = require("react");
1567
1869
  function isPinnableState(t) {
1568
1870
  return t && t.pinnable;
1569
1871
  }
@@ -1576,7 +1878,7 @@ function panelSizing({
1576
1878
  }
1577
1879
  function renderHelper(htmlOrReact) {
1578
1880
  if (typeof htmlOrReact === "string") {
1579
- return (0, import_react13.createElement)("div", { dangerouslySetInnerHTML: { __html: htmlOrReact } });
1881
+ return (0, import_react14.createElement)("div", { dangerouslySetInnerHTML: { __html: htmlOrReact } });
1580
1882
  }
1581
1883
  return htmlOrReact;
1582
1884
  }
@@ -1585,12 +1887,12 @@ function renderHelper(htmlOrReact) {
1585
1887
  var import_react_iiif_vault4 = require("react-iiif-vault");
1586
1888
 
1587
1889
  // ../ui/atoms/Dropdown.tsx
1588
- var import_styled_components7 = __toESM(require("styled-components"), 1);
1589
- var Dropdown = import_styled_components7.default.div`
1890
+ var import_styled_components5 = __toESM(require("styled-components"), 1);
1891
+ var Dropdown = import_styled_components5.default.div`
1590
1892
  position: relative;
1591
1893
  display: inline-block;
1592
1894
  `;
1593
- var DropdownContent = import_styled_components7.default.div`
1895
+ var DropdownContent = import_styled_components5.default.div`
1594
1896
  display: flex;
1595
1897
  flex-direction: column;
1596
1898
  position: absolute;
@@ -1606,7 +1908,7 @@ var DropdownContent = import_styled_components7.default.div`
1606
1908
  }
1607
1909
  }
1608
1910
  `;
1609
- var DropdownItem = import_styled_components7.default.button`
1911
+ var DropdownItem = import_styled_components5.default.button`
1610
1912
  padding: 0 ${(props) => props.theme.padding.small || "0.5rem"};
1611
1913
  color: ${(props) => props.theme.color.main || "none"};
1612
1914
  background-color: ${(props) => props.theme.color.white || "white"};
@@ -1625,7 +1927,7 @@ var DropdownItem = import_styled_components7.default.button`
1625
1927
  background-color: ${(props) => props.theme.color.lightgrey || "lightgrey"};
1626
1928
  }
1627
1929
 
1628
- ${(props) => props.$active && import_styled_components7.css`
1930
+ ${(props) => props.$active && import_styled_components5.css`
1629
1931
  background: #b84c74;
1630
1932
  color: #fff;
1631
1933
  &:hover {
@@ -1634,7 +1936,7 @@ var DropdownItem = import_styled_components7.default.button`
1634
1936
  }
1635
1937
  `}
1636
1938
  `;
1637
- var DropdownMenu = import_styled_components7.default.div`
1939
+ var DropdownMenu = import_styled_components5.default.div`
1638
1940
  display: none;
1639
1941
  flex-direction: column;
1640
1942
  position: absolute;
@@ -1658,18 +1960,18 @@ var DropdownMenu = import_styled_components7.default.div`
1658
1960
  }
1659
1961
  }
1660
1962
 
1661
- ${(props) => props.$open && import_styled_components7.css`
1963
+ ${(props) => props.$open && import_styled_components5.css`
1662
1964
  display: flex;
1663
1965
  `}
1664
1966
  `;
1665
- var DropdownLabel = import_styled_components7.default.div`
1967
+ var DropdownLabel = import_styled_components5.default.div`
1666
1968
  color: #999;
1667
1969
  text-transform: uppercase;
1668
1970
  font-weight: 600;
1669
1971
  padding: 0.7em;
1670
1972
  font-size: 0.875em;
1671
1973
  `;
1672
- var DropdownDivider = import_styled_components7.default.div`
1974
+ var DropdownDivider = import_styled_components5.default.div`
1673
1975
  height: 1px;
1674
1976
  margin: 0 0.5em;
1675
1977
  background: #eee;
@@ -1682,12 +1984,12 @@ var import_react_accessible_dropdown_menu_hook2 = __toESM(require("react-accessi
1682
1984
  var OverrideScrollbar = "ModularPanel_OverrideScrollbar";
1683
1985
 
1684
1986
  // src/Layout/components/ModularPanel.tsx
1685
- var import_jsx_runtime15 = require("react/jsx-runtime");
1686
- var LayoutTitleReactContext = (0, import_react14.createContext)(null);
1987
+ var import_jsx_runtime17 = require("react/jsx-runtime");
1988
+ var LayoutTitleReactContext = (0, import_react15.createContext)(null);
1687
1989
  function useSetCustomTitle() {
1688
- return (0, import_react14.useContext)(LayoutTitleReactContext);
1990
+ return (0, import_react15.useContext)(LayoutTitleReactContext);
1689
1991
  }
1690
- var ModularPanelWrapper = import_styled_components8.default.div`
1992
+ var ModularPanelWrapper = import_styled_components6.default.div`
1691
1993
  display: flex;
1692
1994
  flex-direction: column;
1693
1995
  position: relative;
@@ -1740,7 +2042,7 @@ var ModularPanelWrapper = import_styled_components8.default.div`
1740
2042
  transform: translateX(100%);
1741
2043
  }
1742
2044
  `;
1743
- var ModularPanelHeader = import_styled_components8.default.div`
2045
+ var ModularPanelHeader = import_styled_components6.default.div`
1744
2046
  background: #fff;
1745
2047
  display: flex;
1746
2048
  height: 2.8em;
@@ -1763,7 +2065,7 @@ var ModularPanelHeader = import_styled_components8.default.div`
1763
2065
  box-shadow: inset 0 -5px 10px 0 rgba(255, 255, 255, 0.5);
1764
2066
  }
1765
2067
  `;
1766
- var ModulePanelButton = import_styled_components8.default.button`
2068
+ var ModulePanelButton = import_styled_components6.default.button`
1767
2069
  border: none;
1768
2070
  background: transparent;
1769
2071
  padding: 0 0.4em;
@@ -1776,17 +2078,17 @@ var ModulePanelButton = import_styled_components8.default.button`
1776
2078
  font-size: 1.2em;
1777
2079
  }
1778
2080
  `;
1779
- var ModulePanelSpacer = import_styled_components8.default.div`
2081
+ var ModulePanelSpacer = import_styled_components6.default.div`
1780
2082
  flex: 1 1 0px;
1781
2083
  `;
1782
- var ModularPanelLabel = import_styled_components8.default.h2`
2084
+ var ModularPanelLabel = import_styled_components6.default.h2`
1783
2085
  font-size: 0.875em;
1784
2086
  flex: 1 1 0px;
1785
2087
  padding-left: 1em;
1786
2088
  text-align: center;
1787
2089
  align-self: center;
1788
2090
  `;
1789
- var ModularPanelContent = import_styled_components8.default.div`
2091
+ var ModularPanelContent = import_styled_components6.default.div`
1790
2092
  flex: 1 1 0px;
1791
2093
  display: flex;
1792
2094
 
@@ -1810,32 +2112,32 @@ function ModularPanel({
1810
2112
  style,
1811
2113
  noHeader
1812
2114
  }) {
1813
- const vault = (0, import_react14.useContext)(import_react_iiif_vault4.ReactVaultContext) || null;
1814
- const [didError, setDidError] = (0, import_react14.useState)(false);
2115
+ const vault = (0, import_react15.useContext)(import_react_iiif_vault4.ReactVaultContext) || null;
2116
+ const [didError, setDidError] = (0, import_react15.useState)(false);
1815
2117
  const appState = useAppState();
1816
2118
  const layout = useLayoutProvider();
1817
2119
  const { tabs, pinnable, hideHeader } = panel?.options || {};
1818
2120
  const resetKeys = [appState.state.canvasId, panel?.id];
1819
- const switchablePanels = (0, import_react14.useMemo)(() => {
2121
+ const switchablePanels = (0, import_react15.useMemo)(() => {
1820
2122
  return (available || []).filter((p) => !p.requiresState);
1821
2123
  }, [available]);
1822
2124
  const { itemProps, isOpen, setIsOpen } = (0, import_react_accessible_dropdown_menu_hook2.default)(switchablePanels.length);
1823
- const [customTitle, setCustomTitle] = (0, import_react14.useState)("");
1824
- const setCustomTitleRef = (0, import_react14.useRef)();
1825
- (0, import_react14.useEffect)(() => setDidError(false), resetKeys);
1826
- (0, import_react14.useEffect)(() => setCustomTitle(""), [panel]);
1827
- (0, import_react14.useEffect)(() => {
2125
+ const [customTitle, setCustomTitle] = (0, import_react15.useState)("");
2126
+ const setCustomTitleRef = (0, import_react15.useRef)();
2127
+ (0, import_react15.useEffect)(() => setDidError(false), resetKeys);
2128
+ (0, import_react15.useEffect)(() => setCustomTitle(""), [panel]);
2129
+ (0, import_react15.useEffect)(() => {
1828
2130
  setCustomTitleRef.current = setCustomTitle;
1829
2131
  return () => {
1830
2132
  setCustomTitleRef.current = void 0;
1831
2133
  };
1832
2134
  }, []);
1833
- const _setCustomTitle = (0, import_react14.useCallback)((title) => {
2135
+ const _setCustomTitle = (0, import_react15.useCallback)((title) => {
1834
2136
  if (setCustomTitleRef.current) {
1835
2137
  setCustomTitleRef.current(title);
1836
2138
  }
1837
2139
  }, []);
1838
- const backAction = (0, import_react14.useCallback)(
2140
+ const backAction = (0, import_react15.useCallback)(
1839
2141
  (e) => {
1840
2142
  const originalCallback = panel ? state.stack.length ? actions.popStack : panel.backAction ? () => panel && panel.backAction && panel.backAction(state, { ...layout, current: actions }, appState) : null : null;
1841
2143
  if (e && (!originalCallback || e.metaKey) && switchablePanels.length) {
@@ -1857,16 +2159,16 @@ function ModularPanel({
1857
2159
  if (!panel || !state.current) {
1858
2160
  return null;
1859
2161
  }
1860
- const backButton = panel.backAction || state.stack.length ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ModulePanelButton, { onClick: backAction, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(BackIcon, {}) }) : null;
1861
- const closeButton = /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ModulePanelButton, { onClick: close || actions.close, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(CloseIcon, {}) });
1862
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(LayoutTitleReactContext.Provider, { value: _setCustomTitle, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(ModularPanelWrapper, { "data-state": transition, "data-flipped": isLeft, style, "data-header": !noHeader, children: [
1863
- noHeader ? null : /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(ModularPanelHeader, { "data-tabs": !!tabs, "data-error": didError, children: [
1864
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(Dropdown, { style: { display: "flex", height: "100%" }, children: [
2162
+ const backButton = panel.backAction || state.stack.length ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(ModulePanelButton, { onClick: backAction, children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(BackIcon, {}) }) : null;
2163
+ const closeButton = /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(ModulePanelButton, { onClick: close || actions.close, children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(CloseIcon, {}) });
2164
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(LayoutTitleReactContext.Provider, { value: _setCustomTitle, children: /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(ModularPanelWrapper, { "data-state": transition, "data-flipped": isLeft, style, "data-header": !noHeader, children: [
2165
+ noHeader ? null : /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(ModularPanelHeader, { "data-tabs": !!tabs, "data-error": didError, children: [
2166
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(Dropdown, { style: { display: "flex", height: "100%" }, children: [
1865
2167
  panel.renderBackAction ? panel.renderBackAction({ backAction, fallback: backButton }) : backButton,
1866
- switchablePanels.length ? /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(DropdownMenu, { $open: isOpen, style: { left: "0.5em" }, children: [
1867
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(DropdownLabel, { children: "All panels" }),
1868
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(DropdownDivider, {}),
1869
- switchablePanels.map((newPanel, i) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
2168
+ switchablePanels.length ? /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(DropdownMenu, { $open: isOpen, style: { left: "0.5em" }, children: [
2169
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(DropdownLabel, { children: "All panels" }),
2170
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(DropdownDivider, {}),
2171
+ switchablePanels.map((newPanel, i) => /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
1870
2172
  DropdownItem,
1871
2173
  {
1872
2174
  ...itemProps[i],
@@ -1878,11 +2180,11 @@ function ModularPanel({
1878
2180
  ))
1879
2181
  ] }) : null
1880
2182
  ] }),
1881
- customTitle ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ModularPanelLabel, { children: customTitle }) : hideHeader ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ModulePanelSpacer, {}) : /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ModularPanelLabel, { children: panel.label }),
1882
- pinnable ? state.pinned ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ModulePanelButton, { onClick: pinActions.unpin, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(StarIcon, { fill: "orange" }) }) : /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ModulePanelButton, { onClick: () => pinActions.pin({ id: panel.id, state: state.state }), children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(StarIcon, { fill: "#ddd" }) }) : null,
2183
+ customTitle ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(ModularPanelLabel, { children: customTitle }) : hideHeader ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(ModulePanelSpacer, {}) : /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(ModularPanelLabel, { children: panel.label }),
2184
+ pinnable ? state.pinned ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(ModulePanelButton, { onClick: pinActions.unpin, children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(StarIcon, { fill: "orange" }) }) : /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(ModulePanelButton, { onClick: () => pinActions.pin({ id: panel.id, state: state.state }), children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(StarIcon, { fill: "#ddd" }) }) : null,
1883
2185
  panel.renderCloseAction ? panel.renderCloseAction({ closeAction: close || actions.close, fallback: closeButton }) : closeButton
1884
2186
  ] }),
1885
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ModularPanelContent, { className: OverrideScrollbar, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
2187
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(ModularPanelContent, { className: OverrideScrollbar, children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
1886
2188
  import_react_error_boundary.ErrorBoundary,
1887
2189
  {
1888
2190
  onError: () => setDidError(true),
@@ -1901,14 +2203,189 @@ function ModularPanel({
1901
2203
  ] }) });
1902
2204
  }
1903
2205
 
2206
+ // src/highlighted-image-resources.ts
2207
+ var import_zustand = require("zustand");
2208
+ var import_react16 = require("react");
2209
+
2210
+ // src/helpers.ts
2211
+ var import_parser = require("@iiif/parser");
2212
+ async function getManifestNomalized(id) {
2213
+ let responseData = void 0;
2214
+ try {
2215
+ await fetch(id).then((response) => {
2216
+ return response.json().catch((err) => {
2217
+ console.error(`'${err}' happened!`);
2218
+ });
2219
+ }).then((data) => {
2220
+ responseData = { ...data };
2221
+ });
2222
+ } catch (error) {
2223
+ console.log(error);
2224
+ }
2225
+ return responseData;
2226
+ }
2227
+ function createActionIdentity(type, property, parent) {
2228
+ return `create_${type}_${property}_${(0, import_parser.toRef)(parent)?.type || "unknown"}`;
2229
+ }
2230
+ function createDownload(data, fileName, fileType = "text/json") {
2231
+ const blob = data instanceof Blob ? data : new Blob([data], { type: fileType });
2232
+ const a = document.createElement("a");
2233
+ a.download = fileName;
2234
+ a.href = window.URL.createObjectURL(blob);
2235
+ const clickEvt = new MouseEvent("click", {
2236
+ view: window,
2237
+ bubbles: true,
2238
+ cancelable: true
2239
+ });
2240
+ a.dispatchEvent(clickEvt);
2241
+ a.remove();
2242
+ }
2243
+ async function copyToClipboard(json) {
2244
+ return navigator.clipboard.writeText(
2245
+ typeof json === "string" ? json : JSON.stringify(json, null, 2)
2246
+ );
2247
+ }
2248
+ function randomId() {
2249
+ return `${Math.random().toString(36).substr(2)}-${Date.now().toString(36)}`;
2250
+ }
2251
+ function mapApp(input, map) {
2252
+ const { default: metadata, ...props } = input;
2253
+ const app = {
2254
+ metadata,
2255
+ layout: {
2256
+ leftPanels: [],
2257
+ rightPanels: [],
2258
+ centerPanels: [],
2259
+ ...props
2260
+ }
2261
+ };
2262
+ return map ? map(app) : app;
2263
+ }
2264
+ function extendApp(app, metadata, extensions) {
2265
+ return {
2266
+ ...app,
2267
+ metadata,
2268
+ config: {
2269
+ ...app.config || {},
2270
+ ...extensions.config || {}
2271
+ },
2272
+ layout: {
2273
+ ...app.layout,
2274
+ leftPanels: [
2275
+ ...(app.layout.leftPanels || []).filter((panel) => {
2276
+ if (extensions?.leftPanelIds) {
2277
+ return extensions.leftPanelIds.includes(panel.id);
2278
+ }
2279
+ return true;
2280
+ }),
2281
+ ...extensions?.leftPanels || []
2282
+ ],
2283
+ annotations: [
2284
+ ...extensions?.annotations || [],
2285
+ ...app.layout.annotations || []
2286
+ ],
2287
+ canvasEditors: [
2288
+ ...extensions?.canvasEditors || [],
2289
+ ...app.layout.canvasEditors || []
2290
+ ],
2291
+ creators: [
2292
+ ...extensions?.creators || [],
2293
+ ...app.layout.creators || []
2294
+ ],
2295
+ editors: [
2296
+ //
2297
+ ...extensions?.editors || [],
2298
+ ...app.layout.editors || []
2299
+ ],
2300
+ rightPanels: [
2301
+ ...app.layout.rightPanels || [],
2302
+ ...extensions?.rightPanels || []
2303
+ ],
2304
+ centerPanels: [
2305
+ ...app.layout.centerPanels || [],
2306
+ ...extensions?.centerPanels || []
2307
+ ],
2308
+ modals: [
2309
+ ...app.layout.modals || [],
2310
+ ...extensions?.modalPanels || []
2311
+ ]
2312
+ }
2313
+ };
2314
+ }
2315
+
2316
+ // src/highlighted-image-resources.ts
2317
+ var useHighlightedImageResource = (0, import_zustand.create)((set) => ({
2318
+ regions: {},
2319
+ resources: [],
2320
+ setRegion: (id, region) => {
2321
+ set((ex) => ({ ...ex.regions, regions: { [id]: region || null } }));
2322
+ },
2323
+ setHighlight: (id) => {
2324
+ set({ resources: Array.isArray(id) ? id : [id] });
2325
+ },
2326
+ highlight: (id) => {
2327
+ set((s) => {
2328
+ if (s.resources.indexOf(id) !== -1) {
2329
+ return s;
2330
+ }
2331
+ return { resources: [...s.resources, id] };
2332
+ });
2333
+ },
2334
+ clearHighlight: (id) => {
2335
+ set((s) => ({ resources: s.resources.filter((item) => item !== id) }));
2336
+ }
2337
+ }));
2338
+ function useTemporaryHighlight(newValue) {
2339
+ const id = (0, import_react16.useMemo)(() => randomId(), []);
2340
+ const value = useHighlightedImageResource((s) => s.regions[id]);
2341
+ const setRegion = useHighlightedImageResource((s) => s.setRegion);
2342
+ (0, import_react16.useEffect)(() => {
2343
+ if (value && newValue) {
2344
+ if (value !== newValue && (value.x !== newValue.x || value.y !== newValue.y || value.width !== newValue.width || value.height !== newValue.height)) {
2345
+ setRegion(id, newValue || null);
2346
+ }
2347
+ } else {
2348
+ setRegion(id, newValue || null);
2349
+ }
2350
+ }, [value]);
2351
+ (0, import_react16.useEffect)(() => {
2352
+ return () => setRegion(id, null);
2353
+ }, []);
2354
+ }
2355
+ function useHoverHighlightImageResource(id) {
2356
+ const highlight = useHighlightedImageResource((s) => s.highlight);
2357
+ const clear = useHighlightedImageResource((s) => s.clearHighlight);
2358
+ (0, import_react16.useEffect)(() => {
2359
+ return () => {
2360
+ if (id) {
2361
+ clear(id);
2362
+ }
2363
+ };
2364
+ }, [clear, id]);
2365
+ return (0, import_react16.useMemo)(() => {
2366
+ return {
2367
+ onMouseEnter() {
2368
+ if (id) {
2369
+ highlight(id);
2370
+ }
2371
+ },
2372
+ onMouseLeave() {
2373
+ if (id) {
2374
+ clear(id);
2375
+ }
2376
+ }
2377
+ };
2378
+ }, [id, highlight, clear]);
2379
+ }
2380
+
1904
2381
  // src/BaseCreator/BaseCreator.hooks.tsx
2382
+ var import_parser2 = require("@iiif/parser");
1905
2383
  var import_creator_api = require("@manifest-editor/creator-api");
1906
- var import_react16 = require("react");
2384
+ var import_react18 = require("react");
1907
2385
  var import_react_iiif_vault6 = require("react-iiif-vault");
1908
- var import_parser2 = require("@iiif/parser");
1909
2386
 
1910
2387
  // src/PreviewVault/PreviewVault.tsx
1911
- var import_react15 = require("react");
2388
+ var import_react17 = require("react");
1912
2389
  var import_vault2 = require("@iiif/helpers/vault");
1913
2390
  var import_react_iiif_vault5 = require("react-iiif-vault");
1914
2391
 
@@ -1998,12 +2475,12 @@ function createPreviewVault(homepageCollectionId = "vault://homepage-collection.
1998
2475
  }
1999
2476
 
2000
2477
  // src/PreviewVault/PreviewVault.tsx
2001
- var import_jsx_runtime16 = require("react/jsx-runtime");
2478
+ var import_jsx_runtime18 = require("react/jsx-runtime");
2002
2479
  function usePreviewVault() {
2003
- return (0, import_react15.useContext)(PreviewVaultReactContext);
2480
+ return (0, import_react17.useContext)(PreviewVaultReactContext);
2004
2481
  }
2005
- var PreviewVaultReactContext = (0, import_react15.createContext)(new import_vault2.Vault());
2006
- var PreviewVaultAddHistory = (0, import_react15.createContext)({
2482
+ var PreviewVaultReactContext = (0, import_react17.createContext)(new import_vault2.Vault());
2483
+ var PreviewVaultAddHistory = (0, import_react17.createContext)({
2007
2484
  addHistory: (id, type) => {
2008
2485
  },
2009
2486
  clearHistory: () => {
@@ -2011,118 +2488,127 @@ var PreviewVaultAddHistory = (0, import_react15.createContext)({
2011
2488
  });
2012
2489
  var HOMEPAGE_COLLECTION = "manifest-editor://homepage-collection.json";
2013
2490
  function usePreviewHistory() {
2014
- return (0, import_react15.useContext)(PreviewVaultAddHistory);
2491
+ return (0, import_react17.useContext)(PreviewVaultAddHistory);
2015
2492
  }
2016
2493
  function PreviewVaultContext(props) {
2017
- const { vault, unsubscribe, addHistory, clearHistory } = (0, import_react15.useMemo)(() => {
2494
+ const { vault, unsubscribe, addHistory, clearHistory } = (0, import_react17.useMemo)(() => {
2018
2495
  return createPreviewVault(HOMEPAGE_COLLECTION);
2019
2496
  }, []);
2020
- (0, import_react15.useEffect)(() => {
2497
+ (0, import_react17.useEffect)(() => {
2021
2498
  return unsubscribe;
2022
2499
  }, []);
2023
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(PreviewVaultAddHistory.Provider, { value: { addHistory, clearHistory }, children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(PreviewVaultReactContext.Provider, { value: vault, children: props.children }) });
2500
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(PreviewVaultAddHistory.Provider, { value: { addHistory, clearHistory }, children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(PreviewVaultReactContext.Provider, { value: vault, children: props.children }) });
2024
2501
  }
2025
2502
  function PreviewVaultBoundary({ children }) {
2026
2503
  const vault = usePreviewVault();
2027
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_react_iiif_vault5.VaultProvider, { vault, children });
2504
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_iiif_vault5.VaultProvider, { vault, children });
2028
2505
  }
2029
2506
 
2030
2507
  // src/BaseCreator/BaseCreator.hooks.tsx
2031
- function matchBasedOnResource(resource, list, options) {
2032
- const supported = [];
2033
- if (list.length === 0) {
2034
- return [];
2035
- }
2036
- const parent = (0, import_parser2.toRef)(resource.parent);
2037
- const property = resource.property;
2038
- for (const def of list) {
2039
- if (parent && property) {
2040
- if (def.supports.parentTypes) {
2041
- if (!def.supports.parentTypes.includes(parent.type)) {
2042
- continue;
2043
- }
2044
- }
2045
- if (def.supports.parentFields) {
2046
- if (!def.supports.parentFields.includes(property)) {
2047
- continue;
2048
- }
2049
- }
2050
- if (def.supports.parentFieldMap) {
2051
- const type = def.supports.parentFieldMap[parent.type];
2052
- if (!type || !type.includes(property)) {
2053
- continue;
2054
- }
2055
- }
2056
- if (def.supports.disallowPainting && resource.isPainting) {
2057
- continue;
2058
- }
2059
- if (def.supports.custom) {
2060
- const isValid = def.supports.custom({ property, resource: parent, atIndex: resource.index }, options.vault);
2061
- if (!isValid) {
2062
- continue;
2063
- }
2064
- }
2065
- if (!def.supports.initialData && Object.keys(resource.initialData || {}).length !== 0) {
2066
- continue;
2067
- }
2068
- if (def.resourceType !== resource.type) {
2069
- if (!(def.additionalTypes || []).includes(resource.type)) {
2070
- continue;
2071
- }
2072
- }
2073
- supported.push(def);
2074
- }
2075
- }
2076
- return supported;
2077
- }
2078
2508
  function useCreator(parent, property, type, target, options) {
2079
2509
  const vault = (0, import_react_iiif_vault6.useVault)();
2080
2510
  const app = useApp();
2081
2511
  const { create: create2, edit } = useLayoutActions();
2082
- const supported = (0, import_react16.useMemo)(
2083
- () => matchBasedOnResource({ type, parent, index: 0, property }, app.layout.creators || [], { vault }),
2512
+ const supported = (0, import_react18.useMemo)(
2513
+ () => (0, import_creator_api.matchBasedOnResource)(
2514
+ { type, parent, index: 0, property },
2515
+ app.layout.creators || [],
2516
+ { vault }
2517
+ ),
2084
2518
  [parent, property, app.layout.creators, type, vault]
2085
2519
  );
2086
2520
  const canCreate = parent && supported.length !== 0;
2087
- const wrappedCreate = (0, import_react16.useCallback)(
2521
+ const wrappedCreate = (0, import_react18.useCallback)(
2088
2522
  (index, initialData) => {
2089
2523
  if (parent) {
2090
- create2({ type, parent: (0, import_parser2.toRef)(parent), property, index, target, initialData, ...options || {} });
2524
+ create2({
2525
+ type,
2526
+ parent: (0, import_parser2.toRef)(parent),
2527
+ property,
2528
+ index,
2529
+ target,
2530
+ initialData,
2531
+ ...options || {}
2532
+ });
2533
+ }
2534
+ },
2535
+ [create2, parent, property, type, options, target]
2536
+ );
2537
+ const wrappedFilteredCreate = (0, import_react18.useCallback)(
2538
+ (filter, index, initialData) => {
2539
+ if (parent) {
2540
+ create2({
2541
+ type,
2542
+ filter,
2543
+ parent: (0, import_parser2.toRef)(parent),
2544
+ property,
2545
+ index,
2546
+ target,
2547
+ initialData,
2548
+ ...options || {}
2549
+ });
2091
2550
  }
2092
2551
  },
2093
- [create2, parent, property, type]
2552
+ [create2, parent, property, type, options, target]
2094
2553
  );
2095
- const wrappedEdit = (0, import_react16.useCallback)(
2554
+ const wrappedEdit = (0, import_react18.useCallback)(
2096
2555
  (resource, index) => {
2097
- edit(resource, parent ? { parent: (0, import_parser2.toRef)(parent), property, index } : void 0);
2556
+ edit(
2557
+ resource,
2558
+ parent ? { parent: (0, import_parser2.toRef)(parent), property, index } : void 0
2559
+ );
2560
+ },
2561
+ [edit, parent, property]
2562
+ );
2563
+ const wrappedCreator = (0, import_react18.useCallback)(
2564
+ (initialCreator, initialData) => {
2565
+ if (parent) {
2566
+ create2({
2567
+ type,
2568
+ initialCreator,
2569
+ parent: (0, import_parser2.toRef)(parent),
2570
+ property,
2571
+ target,
2572
+ initialData,
2573
+ ...options || {}
2574
+ });
2575
+ }
2098
2576
  },
2099
- [edit, parent, property]
2577
+ [type, property, parent, target, create2, options]
2100
2578
  );
2101
- const buttonProps = (0, import_react16.useMemo)(() => {
2579
+ const buttonProps = (0, import_react18.useMemo)(() => {
2102
2580
  return {
2103
2581
  "data-action-id": createActionIdentity(type, property, parent)
2104
2582
  };
2105
- }, []);
2106
- return [canCreate, { create: wrappedCreate, edit: wrappedEdit, buttonProps }];
2583
+ }, [type, property, parent]);
2584
+ return [
2585
+ canCreate,
2586
+ {
2587
+ create: wrappedCreate,
2588
+ edit: wrappedEdit,
2589
+ createFiltered: wrappedFilteredCreate,
2590
+ creator: wrappedCreator,
2591
+ buttonProps
2592
+ }
2593
+ ];
2107
2594
  }
2108
2595
  function useInlineCreator() {
2109
2596
  const vault = (0, import_react_iiif_vault6.useVault)();
2110
2597
  const previewVault = usePreviewVault();
2111
2598
  const app = useApp();
2112
- return (0, import_react16.useMemo)(() => {
2599
+ return (0, import_react18.useMemo)(() => {
2113
2600
  return new import_creator_api.Creator(vault, app.layout.creators || [], previewVault);
2114
2601
  }, [app.layout.creators, vault]);
2115
2602
  }
2116
2603
 
2117
2604
  // src/BaseCreator/BaseCreator.tsx
2118
- var import_components3 = require("@manifest-editor/components");
2119
- var import_jsx_runtime17 = require("react/jsx-runtime");
2120
- var RenderCreator = (0, import_react17.memo)(function RenderCreator2(props) {
2605
+ var import_jsx_runtime19 = require("react/jsx-runtime");
2606
+ var RenderCreator = (0, import_react19.memo)(function RenderCreator2(props) {
2121
2607
  const vault = (0, import_react_iiif_vault7.useVault)();
2122
2608
  const { edit, modal } = useLayoutActions();
2123
- const [isCreating, setIsCreating] = (0, import_react17.useState)(false);
2609
+ const [isCreating, setIsCreating] = (0, import_react19.useState)(false);
2124
2610
  const creator = useInlineCreator();
2125
- const isCreatingRef = (0, import_react17.useRef)(false);
2611
+ const isCreatingRef = (0, import_react19.useRef)(false);
2126
2612
  const canvasSelector = props.resource.initialData?.selector;
2127
2613
  useTemporaryHighlight(canvasSelector);
2128
2614
  const options = {
@@ -2152,12 +2638,12 @@ var RenderCreator = (0, import_react17.memo)(function RenderCreator2(props) {
2152
2638
  const validate = async () => {
2153
2639
  return true;
2154
2640
  };
2155
- (0, import_react17.useEffect)(() => {
2641
+ (0, import_react19.useEffect)(() => {
2156
2642
  if (!props.creator.render && !isCreating) {
2157
2643
  runCreate({});
2158
2644
  }
2159
2645
  }, [props.creator]);
2160
- (0, import_react17.useEffect)(() => {
2646
+ (0, import_react19.useEffect)(() => {
2161
2647
  if (isCreating) {
2162
2648
  modal.popStack();
2163
2649
  modal.close();
@@ -2167,9 +2653,9 @@ var RenderCreator = (0, import_react17.memo)(function RenderCreator2(props) {
2167
2653
  return null;
2168
2654
  }
2169
2655
  if (!props.creator.render) {
2170
- return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Button, { onClick: () => runCreate({}), children: "Create" }) });
2656
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Button, { onClick: () => runCreate({}), children: "Create" }) });
2171
2657
  }
2172
- return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_jsx_runtime17.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_react17.Suspense, { fallback: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Spinner, {}), children: props.creator.render({
2658
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_jsx_runtime19.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_react19.Suspense, { fallback: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Spinner, {}), children: props.creator.render({
2173
2659
  vault,
2174
2660
  runCreate,
2175
2661
  validate,
@@ -2179,32 +2665,40 @@ var RenderCreator = (0, import_react17.memo)(function RenderCreator2(props) {
2179
2665
  function BaseCreator(props) {
2180
2666
  const app = useApp();
2181
2667
  const vault = (0, import_react_iiif_vault7.useVault)();
2182
- const [currentId, setCurrentId] = (0, import_react17.useState)("");
2668
+ const [currentId, setCurrentId] = (0, import_react19.useState)(
2669
+ props.resource.initialCreator || ""
2670
+ );
2183
2671
  const set = useSetCustomTitle();
2184
- const supported = (0, import_react17.useMemo)(
2185
- () => matchBasedOnResource(props.resource, app.layout.creators || [], { vault }),
2672
+ const supported = (0, import_react19.useMemo)(
2673
+ () => (0, import_creator_api2.matchBasedOnResource)(props.resource, app.layout.creators || [], {
2674
+ vault
2675
+ }),
2186
2676
  [props.resource, app.layout.creators, vault]
2187
2677
  );
2188
2678
  if (supported.length === 1 && !currentId) {
2189
2679
  setCurrentId(supported[0].id);
2190
2680
  }
2191
2681
  const current = supported.find((t) => t.id === currentId);
2192
- (0, import_react17.useEffect)(() => {
2682
+ (0, import_react19.useEffect)(() => {
2193
2683
  if (current) {
2194
- set && set(current.label);
2684
+ set?.(current.label);
2195
2685
  }
2196
2686
  });
2197
2687
  if (supported.length === 0) {
2198
- return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { children: "Not currently supported" });
2688
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { children: "Not currently supported" });
2199
2689
  }
2200
2690
  if (current) {
2201
- return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { children: [
2202
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "bg-me-gray-100 p-2", children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Button, { onClick: () => setCurrentId(""), children: "Back" }) }),
2203
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "p-2 py-6", children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(RenderCreator, { creator: current, resource: props.resource }) })
2691
+ const shouldHideModal = current.hiddenModal;
2692
+ if (shouldHideModal) {
2693
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(RenderCreator, { creator: current, resource: props.resource });
2694
+ }
2695
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { children: [
2696
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "bg-me-gray-100 p-2", children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Button, { onClick: () => setCurrentId(""), children: "Back" }) }),
2697
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "p-2 py-6", children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(RenderCreator, { creator: current, resource: props.resource }) })
2204
2698
  ] });
2205
2699
  }
2206
- return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
2207
- import_components3.CreatorGrid,
2700
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
2701
+ import_components4.CreatorGrid,
2208
2702
  {
2209
2703
  label: "Select a type",
2210
2704
  items: supported.map((item) => ({
@@ -2219,22 +2713,23 @@ function BaseCreator(props) {
2219
2713
  }
2220
2714
 
2221
2715
  // src/BaseCreator/index.tsx
2222
- var import_jsx_runtime18 = require("react/jsx-runtime");
2716
+ var import_jsx_runtime20 = require("react/jsx-runtime");
2223
2717
  var baseCreator = {
2224
2718
  id: "@manifest-editor/creator",
2225
2719
  label: "Add content",
2226
2720
  options: { hideHeader: true, tabs: false },
2227
2721
  render(state) {
2228
- return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(BaseCreator, { resource: state });
2722
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(BaseCreator, { resource: state });
2229
2723
  }
2230
2724
  };
2231
2725
 
2232
2726
  // src/BaseEditor/BaseEditor.tsx
2233
- var import_react19 = require("react");
2727
+ var import_components5 = require("@manifest-editor/components");
2728
+ var import_react21 = require("react");
2234
2729
  var import_react_iiif_vault9 = require("react-iiif-vault");
2235
2730
 
2236
2731
  // src/EditingStack/EditingStack.tsx
2237
- var import_react18 = require("react");
2732
+ var import_react20 = require("react");
2238
2733
 
2239
2734
  // src/EditingStack/EditingStack.reducer.ts
2240
2735
  var import_parser4 = require("@iiif/parser");
@@ -2331,10 +2826,10 @@ function filterStack(newStackWithDuplicates, current) {
2331
2826
  var import_editor_api = require("@manifest-editor/editor-api");
2332
2827
  var import_react_iiif_vault8 = require("react-iiif-vault");
2333
2828
  var import_parser5 = require("@iiif/parser");
2334
- var import_jsx_runtime19 = require("react/jsx-runtime");
2829
+ var import_jsx_runtime21 = require("react/jsx-runtime");
2335
2830
  var defaultState = { stack: [], current: null, create: null };
2336
- var EditingStackContext = (0, import_react18.createContext)(defaultState);
2337
- var EditingStackActionsContext = (0, import_react18.createContext)({
2831
+ var EditingStackContext = (0, import_react20.createContext)(defaultState);
2832
+ var EditingStackActionsContext = (0, import_react20.createContext)({
2338
2833
  edit() {
2339
2834
  },
2340
2835
  close() {
@@ -2349,29 +2844,29 @@ var EditingStackActionsContext = (0, import_react18.createContext)({
2349
2844
  }
2350
2845
  });
2351
2846
  function useEditingStack() {
2352
- return (0, import_react18.useContext)(EditingStackActionsContext);
2847
+ return (0, import_react20.useContext)(EditingStackActionsContext);
2353
2848
  }
2354
2849
  function useEditingResource() {
2355
- return (0, import_react18.useContext)(EditingStackContext).current;
2850
+ return (0, import_react20.useContext)(EditingStackContext).current;
2356
2851
  }
2357
2852
  function useEditingResourceStack() {
2358
- return (0, import_react18.useContext)(EditingStackContext).stack;
2853
+ return (0, import_react20.useContext)(EditingStackContext).stack;
2359
2854
  }
2360
2855
  function useCreatingResource() {
2361
- return (0, import_react18.useContext)(EditingStackContext).create;
2856
+ return (0, import_react20.useContext)(EditingStackContext).create;
2362
2857
  }
2363
2858
  function useManifestEditor() {
2364
2859
  const { manifest } = (0, import_react_iiif_vault8.useResourceContext)();
2365
2860
  const vault = (0, import_react_iiif_vault8.useVault)();
2366
- const [key, invalidate] = (0, import_react18.useReducer)((i) => i + 1, 0);
2861
+ const [key, invalidate] = (0, import_react20.useReducer)((i) => i + 1, 0);
2367
2862
  invariant(manifest, "Manifest not found");
2368
- const editor = (0, import_react18.useMemo)(() => {
2863
+ const editor = (0, import_react20.useMemo)(() => {
2369
2864
  return new import_editor_api.EditorInstance({
2370
2865
  reference: { id: manifest, type: "Manifest" },
2371
2866
  vault
2372
2867
  });
2373
2868
  }, [manifest, vault]);
2374
- (0, import_react18.useEffect)(() => {
2869
+ (0, import_react20.useEffect)(() => {
2375
2870
  return editor.observe.start(invalidate);
2376
2871
  }, [editor]);
2377
2872
  editor.observe.key = `${key}`;
@@ -2381,15 +2876,15 @@ function useManifestEditor() {
2381
2876
  function useCollectionEditor() {
2382
2877
  const { collection } = (0, import_react_iiif_vault8.useResourceContext)();
2383
2878
  const vault = (0, import_react_iiif_vault8.useVault)();
2384
- const [key, invalidate] = (0, import_react18.useReducer)((i) => i + 1, 0);
2879
+ const [key, invalidate] = (0, import_react20.useReducer)((i) => i + 1, 0);
2385
2880
  invariant(collection, "Collection not found");
2386
- const editor = (0, import_react18.useMemo)(() => {
2881
+ const editor = (0, import_react20.useMemo)(() => {
2387
2882
  return new import_editor_api.EditorInstance({
2388
2883
  reference: { id: collection, type: "Collection" },
2389
2884
  vault
2390
2885
  });
2391
2886
  }, [collection, vault]);
2392
- (0, import_react18.useEffect)(() => {
2887
+ (0, import_react20.useEffect)(() => {
2393
2888
  return editor.observe.start(invalidate);
2394
2889
  }, [editor]);
2395
2890
  editor.observe.key = `${key}`;
@@ -2398,16 +2893,16 @@ function useCollectionEditor() {
2398
2893
  }
2399
2894
  function useGenericEditor(ref, ctx = {}) {
2400
2895
  const vault = (0, import_react_iiif_vault8.useVault)();
2401
- const [key, invalidate] = (0, import_react18.useReducer)((i) => i + 1, 0);
2896
+ const [key, invalidate] = (0, import_react20.useReducer)((i) => i + 1, 0);
2402
2897
  invariant(ref, "Resource not found");
2403
- const editor = (0, import_react18.useMemo)(() => {
2898
+ const editor = (0, import_react20.useMemo)(() => {
2404
2899
  return new import_editor_api.EditorInstance({
2405
2900
  reference: (0, import_parser5.toRef)(ref),
2406
2901
  vault,
2407
2902
  context: { resource: ref, parent: ctx.parent, index: ctx.index, parentProperty: ctx.parentProperty }
2408
2903
  });
2409
2904
  }, [ref, vault]);
2410
- (0, import_react18.useEffect)(() => {
2905
+ (0, import_react20.useEffect)(() => {
2411
2906
  return editor.observe.start(invalidate);
2412
2907
  }, [editor]);
2413
2908
  editor.observe.key = `${key}`;
@@ -2422,15 +2917,15 @@ function useAnnotationPageEditor() {
2422
2917
  function useEditor() {
2423
2918
  const resource = useEditingResource();
2424
2919
  const vault = (0, import_react_iiif_vault8.useVault)();
2425
- const [key, invalidate] = (0, import_react18.useReducer)((i) => i + 1, 0);
2920
+ const [key, invalidate] = (0, import_react20.useReducer)((i) => i + 1, 0);
2426
2921
  invariant(resource, "No resource selected");
2427
- const editor = (0, import_react18.useMemo)(() => {
2922
+ const editor = (0, import_react20.useMemo)(() => {
2428
2923
  return new import_editor_api.EditorInstance({
2429
2924
  reference: resource.resource.source || resource.resource,
2430
2925
  vault
2431
2926
  });
2432
2927
  }, [resource, vault]);
2433
- (0, import_react18.useEffect)(() => {
2928
+ (0, import_react20.useEffect)(() => {
2434
2929
  return editor.observe.start(invalidate);
2435
2930
  }, [editor]);
2436
2931
  editor.observe.key = `${key}`;
@@ -2439,11 +2934,11 @@ function useEditor() {
2439
2934
  }
2440
2935
  function EditingStack(props) {
2441
2936
  const vault = (0, import_react_iiif_vault8.useVault)();
2442
- const [state, _dispatch] = (0, import_react18.useReducer)(editingStackReducer, defaultState);
2443
- const dispatch = (0, import_react18.useCallback)((action) => {
2937
+ const [state, _dispatch] = (0, import_react20.useReducer)(editingStackReducer, defaultState);
2938
+ const dispatch = (0, import_react20.useCallback)((action) => {
2444
2939
  _dispatch(action);
2445
2940
  }, []);
2446
- (0, import_react18.useEffect)(() => {
2941
+ (0, import_react20.useEffect)(() => {
2447
2942
  return vault.on("@iiif/REMOVE_REFERENCE", (payload) => {
2448
2943
  const action = payload.action;
2449
2944
  const parent = { id: action.payload.id, type: action.payload.type };
@@ -2451,37 +2946,36 @@ function EditingStack(props) {
2451
2946
  _dispatch({ type: "syncRemoval", payload: { resource: { parent, resource } } });
2452
2947
  });
2453
2948
  }, [vault]);
2454
- const edit = (0, import_react18.useCallback)(
2949
+ const edit = (0, import_react20.useCallback)(
2455
2950
  (resource, reset = false) => dispatch({ type: "edit", payload: { resource, reset } }),
2456
2951
  []
2457
2952
  );
2458
- const updateCurrent = (0, import_react18.useCallback)(
2953
+ const updateCurrent = (0, import_react20.useCallback)(
2459
2954
  (resource) => dispatch({ type: "updateCurrent", payload: { resource } }),
2460
2955
  []
2461
2956
  );
2462
- const close = (0, import_react18.useCallback)(() => dispatch({ type: "close" }), []);
2463
- const back = (0, import_react18.useCallback)(() => dispatch({ type: "back" }), []);
2464
- const create2 = (0, import_react18.useCallback)((resource, options) => {
2957
+ const close = (0, import_react20.useCallback)(() => dispatch({ type: "close" }), []);
2958
+ const back = (0, import_react20.useCallback)(() => dispatch({ type: "back" }), []);
2959
+ const create2 = (0, import_react20.useCallback)((resource, options) => {
2465
2960
  dispatch({ type: "create", payload: { resource, options } });
2466
2961
  return () => {
2467
2962
  dispatch({ type: "create", payload: { resource: null } });
2468
2963
  };
2469
2964
  }, []);
2470
- const actions = (0, import_react18.useMemo)(() => {
2965
+ const actions = (0, import_react20.useMemo)(() => {
2471
2966
  return { edit, updateCurrent, close, back, create: create2 };
2472
2967
  }, []);
2473
2968
  const { instanceId } = useAppInstance();
2474
- return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(EditingStackActionsContext.Provider, { value: actions, children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(EditingStackContext.Provider, { value: state, children: props.children }) }, instanceId);
2969
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(EditingStackActionsContext.Provider, { value: actions, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(EditingStackContext.Provider, { value: state, children: props.children }) }, instanceId);
2475
2970
  }
2476
2971
 
2477
2972
  // src/BaseEditor/BaseEditor.tsx
2478
- var import_components4 = require("@manifest-editor/components");
2479
- var import_jsx_runtime20 = require("react/jsx-runtime");
2973
+ var import_jsx_runtime22 = require("react/jsx-runtime");
2480
2974
  function BaseEditorBackButton({ fallback, backAction }) {
2481
2975
  const stack = useEditingResourceStack();
2482
2976
  const { back } = useEditingStack();
2483
2977
  if (stack.length) {
2484
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ModulePanelButton, { onClick: back, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(BackIcon, {}) });
2978
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(ModulePanelButton, { onClick: back, children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(BackIcon, {}) });
2485
2979
  }
2486
2980
  return fallback;
2487
2981
  }
@@ -2489,20 +2983,22 @@ function BaseEditorCloseButton({ closeAction, fallback }) {
2489
2983
  const stack = useEditingResourceStack();
2490
2984
  const current = useEditingResource();
2491
2985
  if (current || stack.length) {
2492
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
2986
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
2493
2987
  ModulePanelButton,
2494
2988
  {
2495
2989
  onClick: () => {
2496
2990
  closeAction();
2497
2991
  },
2498
- children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(CloseIcon, {})
2992
+ children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(CloseIcon, {})
2499
2993
  }
2500
2994
  );
2501
2995
  }
2502
2996
  return fallback;
2503
2997
  }
2504
2998
  function editBasedOnResource(resource, list, options, config) {
2505
- const filteredList = list.filter((l) => l.resourceType === resource.resource.source.type);
2999
+ const filteredList = list.filter(
3000
+ (l) => l.resourceType === resource.resource.source.type
3001
+ );
2506
3002
  if (filteredList.length === 0) {
2507
3003
  return null;
2508
3004
  }
@@ -2550,86 +3046,136 @@ function editBasedOnResource(resource, list, options, config) {
2550
3046
  }
2551
3047
  return null;
2552
3048
  }
2553
- function BaseEditor({ currentTab = void 0 }) {
3049
+ function BaseEditor({
3050
+ currentTab = void 0
3051
+ }) {
2554
3052
  const resource = useEditingResource();
3053
+ const currentResourceContext = (0, import_react21.useContext)(import_react_iiif_vault9.ResourceReactContext);
2555
3054
  const app = useApp();
2556
3055
  const vault = (0, import_react_iiif_vault9.useVault)();
2557
3056
  const { change } = useLayoutActions();
2558
3057
  const set = useSetCustomTitle();
2559
3058
  const { editorConfig } = useConfig();
2560
3059
  const resourceConfig = (resource?.resource.source?.type ? editorConfig[resource?.resource.source?.type] : editorConfig.All) || {};
2561
- const match = (0, import_react19.useMemo)(() => {
3060
+ const newResourceContext = (0, import_react21.useMemo)(() => {
3061
+ const newCtx = { ...currentResourceContext };
3062
+ const id = resource?.resource.source.id;
3063
+ const type = resource?.resource.source.type;
3064
+ const mapping = {
3065
+ Collection: "collection",
3066
+ Manifest: "manifest",
3067
+ Range: "range",
3068
+ Canvas: "canvas",
3069
+ Annotation: "annotation",
3070
+ AnnotationPage: "annotationPage"
3071
+ };
3072
+ if (type && mapping[type]) {
3073
+ newCtx[mapping[type]] = id;
3074
+ }
3075
+ return newCtx;
3076
+ }, [resource, currentResourceContext]);
3077
+ function wrap(children) {
3078
+ if (!resource) {
3079
+ return children;
3080
+ }
3081
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_react_iiif_vault9.ResourceReactContext.Provider, { value: newResourceContext, children });
3082
+ }
3083
+ const match = (0, import_react21.useMemo)(() => {
2562
3084
  if (!resource) {
2563
3085
  return null;
2564
3086
  }
2565
3087
  const editors = app.layout.editors || [];
2566
3088
  const resources = app.layout.resources || [];
2567
- const mappedResources = resources.map((resource2) => {
2568
- if (typeof resource2 === "string") {
2569
- return {
2570
- id: "@default/" + resource2,
2571
- label: resource2,
2572
- resourceType: resource2,
2573
- auto: true,
2574
- editors: editors.filter((e) => e.supports.resourceTypes.includes(resource2))
2575
- };
3089
+ const mappedResources = resources.map(
3090
+ (resource2) => {
3091
+ if (typeof resource2 === "string") {
3092
+ return {
3093
+ id: "@default/" + resource2,
3094
+ label: resource2,
3095
+ resourceType: resource2,
3096
+ auto: true,
3097
+ editors: editors.filter(
3098
+ (e) => e.supports.resourceTypes.includes(resource2)
3099
+ )
3100
+ };
3101
+ }
3102
+ return resource2;
2576
3103
  }
2577
- return resource2;
2578
- });
2579
- return editBasedOnResource(resource, mappedResources, { edit: true, vault }, resourceConfig);
3104
+ );
3105
+ return editBasedOnResource(
3106
+ resource,
3107
+ mappedResources,
3108
+ { edit: true, vault },
3109
+ resourceConfig
3110
+ );
2580
3111
  }, [resource, app]);
2581
- (0, import_react19.useEffect)(() => {
3112
+ (0, import_react21.useEffect)(() => {
2582
3113
  set(match?.label || "");
2583
3114
  });
3115
+ (0, import_react21.useEffect)(() => {
3116
+ const availableKeys = match?.editors.map((editor, key) => editor.id + key) || [];
3117
+ const currentKey = availableKeys.find((key) => key === currentTab);
3118
+ if (!currentKey) {
3119
+ change("@manifest-editor/editor", { currentTab: availableKeys[0] });
3120
+ }
3121
+ }, [match?.editors, currentTab, change]);
2584
3122
  if (!resource || !match) {
2585
3123
  return null;
2586
3124
  }
2587
3125
  if (resourceConfig.singleTab) {
2588
- const first = (match?.editors || []).find((editor) => editor.id === resourceConfig.singleTab);
3126
+ const first = (match?.editors || []).find(
3127
+ (editor) => editor.id === resourceConfig.singleTab
3128
+ );
2589
3129
  if (first) {
2590
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "w-full", children: first.component(resourceConfig) });
3130
+ return wrap(
3131
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "w-full", children: first.component(resourceConfig) })
3132
+ );
2591
3133
  }
2592
3134
  }
2593
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
2594
- import_components4.SidebarTabs,
2595
- {
2596
- menuId: resource.resource.source.id,
2597
- menu: (match?.editors || []).map((editor, key) => {
2598
- return {
2599
- id: editor.id + key,
2600
- label: editor.label,
2601
- renderComponent: () => editor.component(resourceConfig)
2602
- };
2603
- }),
2604
- selectedKey: currentTab,
2605
- onSelectionChange: (p) => change("@manifest-editor/editor", { currentTab: p })
2606
- },
2607
- resource.resource.source?.id
3135
+ return wrap(
3136
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
3137
+ import_components5.SidebarTabs,
3138
+ {
3139
+ menuId: resource.resource.source.id,
3140
+ menu: (match?.editors || []).map((editor, key) => {
3141
+ return {
3142
+ id: editor.id + key,
3143
+ label: editor.label,
3144
+ renderComponent: () => editor.component(resourceConfig)
3145
+ };
3146
+ }),
3147
+ selectedKey: currentTab,
3148
+ onSelectionChange: (p) => {
3149
+ change("@manifest-editor/editor", { currentTab: p });
3150
+ }
3151
+ },
3152
+ resource.resource.source?.id
3153
+ )
2608
3154
  );
2609
3155
  }
2610
3156
 
2611
3157
  // src/BaseEditor/index.tsx
2612
- var import_jsx_runtime21 = require("react/jsx-runtime");
3158
+ var import_jsx_runtime23 = require("react/jsx-runtime");
2613
3159
  var baseEditor = {
2614
3160
  id: "@manifest-editor/editor",
2615
3161
  label: "Editor",
2616
3162
  options: { hideHeader: true, tabs: true, minWidth: 400 },
2617
- renderBackAction: ({ backAction, fallback }) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(BaseEditorBackButton, { backAction, fallback }),
2618
- renderCloseAction: ({ closeAction, fallback }) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(BaseEditorCloseButton, { closeAction, fallback }),
3163
+ renderBackAction: ({ backAction, fallback }) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(BaseEditorBackButton, { backAction, fallback }),
3164
+ renderCloseAction: ({ closeAction, fallback }) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(BaseEditorCloseButton, { closeAction, fallback }),
2619
3165
  render({ currentTab }) {
2620
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(BaseEditor, { currentTab });
3166
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(BaseEditor, { currentTab });
2621
3167
  }
2622
3168
  };
2623
3169
 
2624
3170
  // src/ConfigContext/ConfigEditor.tsx
2625
- var import_components5 = require("@manifest-editor/components");
3171
+ var import_components6 = require("@manifest-editor/components");
2626
3172
 
2627
3173
  // src/hooks/use-decay-state.ts
2628
- var import_react20 = require("react");
3174
+ var import_react22 = require("react");
2629
3175
  function useDecayState(time) {
2630
- const [active, _setActive] = (0, import_react20.useState)(false);
2631
- const lastTimeout = (0, import_react20.useRef)();
2632
- const focusCount = (0, import_react20.useRef)(0);
3176
+ const [active, _setActive] = (0, import_react22.useState)(false);
3177
+ const lastTimeout = (0, import_react22.useRef)();
3178
+ const focusCount = (0, import_react22.useRef)(0);
2633
3179
  function clear(existing) {
2634
3180
  focusCount.current--;
2635
3181
  if (existing && focusCount.current !== 0) {
@@ -2650,11 +3196,11 @@ function useDecayState(time) {
2650
3196
  }
2651
3197
  _setActive(true);
2652
3198
  }
2653
- return (0, import_react20.useMemo)(() => [active, { set, clear }], [active]);
3199
+ return (0, import_react22.useMemo)(() => [active, { set, clear }], [active]);
2654
3200
  }
2655
3201
 
2656
3202
  // src/ConfigContext/ConfigEditor.tsx
2657
- var import_jsx_runtime22 = require("react/jsx-runtime");
3203
+ var import_jsx_runtime24 = require("react/jsx-runtime");
2658
3204
  function ConfigEditor() {
2659
3205
  const previews = usePreviewContext();
2660
3206
  const config = useConfig();
@@ -2681,14 +3227,14 @@ function ConfigEditor() {
2681
3227
  saveState.set();
2682
3228
  saveState.clear();
2683
3229
  }
2684
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_components5.Sidebar, { children: [
2685
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_components5.SidebarHeader, { title: "Workspace configuration" }),
2686
- isSaved ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "bg-me-primary-500 text-white p-3 text-sm", children: "Changes saved" }) : null,
2687
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_components5.SidebarContent, { className: "p-4", children: /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_components5.Form.Form, { onSubmit, className: "flex flex-col gap-3", children: [
2688
- /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_components5.Form.InputContainer, { children: [
2689
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_components5.Form.Label, { htmlFor: "defaultLanguage", children: "Default Language" }),
2690
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
2691
- import_components5.Form.Input,
3230
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_components6.Sidebar, { children: [
3231
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_components6.SidebarHeader, { title: "Workspace configuration" }),
3232
+ isSaved ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "bg-me-primary-500 text-white p-3 text-sm", children: "Changes saved" }) : null,
3233
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_components6.SidebarContent, { className: "p-4", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_components6.Form.Form, { onSubmit, className: "flex flex-col gap-3", children: [
3234
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_components6.Form.InputContainer, { children: [
3235
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_components6.Form.Label, { htmlFor: "defaultLanguage", children: "Default Language" }),
3236
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
3237
+ import_components6.Form.Input,
2692
3238
  {
2693
3239
  type: "text",
2694
3240
  name: "defaultLanguage",
@@ -2697,10 +3243,10 @@ function ConfigEditor() {
2697
3243
  }
2698
3244
  )
2699
3245
  ] }),
2700
- /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_components5.Form.InputContainer, { children: [
2701
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_components5.Form.Label, { htmlFor: "availableLanguages", children: "Available Languages" }),
2702
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
2703
- import_components5.Form.Input,
3246
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_components6.Form.InputContainer, { children: [
3247
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_components6.Form.Label, { htmlFor: "availableLanguages", children: "Available Languages" }),
3248
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
3249
+ import_components6.Form.Input,
2704
3250
  {
2705
3251
  type: "text",
2706
3252
  name: "availableLanguages",
@@ -2709,9 +3255,9 @@ function ConfigEditor() {
2709
3255
  }
2710
3256
  )
2711
3257
  ] }),
2712
- /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_components5.Form.InputContainer, { horizontal: true, className: "my-3", children: [
2713
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
2714
- import_components5.Form.Input,
3258
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_components6.Form.InputContainer, { horizontal: true, className: "my-3", children: [
3259
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
3260
+ import_components6.Form.Input,
2715
3261
  {
2716
3262
  type: "checkbox",
2717
3263
  name: "advancedLanguageMode",
@@ -2719,11 +3265,23 @@ function ConfigEditor() {
2719
3265
  defaultChecked: config.i18n?.advancedLanguageMode || false
2720
3266
  }
2721
3267
  ),
2722
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_components5.Form.Label, { htmlFor: "advancedLanguageMode", children: "Advanced Language Mode" })
3268
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_components6.Form.Label, { htmlFor: "advancedLanguageMode", children: "Advanced Language Mode" })
3269
+ ] }),
3270
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_components6.Form.InputContainer, { horizontal: true, className: "my-3", children: [
3271
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
3272
+ import_components6.Form.Input,
3273
+ {
3274
+ type: "checkbox",
3275
+ name: "textGranularityEnabled",
3276
+ id: "textGranularityEnabled",
3277
+ defaultChecked: config.i18n?.textGranularityEnabled || false
3278
+ }
3279
+ ),
3280
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_components6.Form.Label, { htmlFor: "textGranularityEnabled", children: "Enable text granularity" })
2723
3281
  ] }),
2724
- /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_components5.Form.InputContainer, { horizontal: true, className: "my-3", children: [
2725
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
2726
- import_components5.Form.Input,
3282
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_components6.Form.InputContainer, { horizontal: true, className: "my-3", children: [
3283
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
3284
+ import_components6.Form.Input,
2727
3285
  {
2728
3286
  type: "checkbox",
2729
3287
  name: "isVersion2",
@@ -2731,17 +3289,17 @@ function ConfigEditor() {
2731
3289
  defaultChecked: config.export?.version === 2
2732
3290
  }
2733
3291
  ),
2734
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_components5.Form.Label, { htmlFor: "isVersion2", children: "Export Presentation 2 Manifests" })
3292
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_components6.Form.Label, { htmlFor: "isVersion2", children: "Export Presentation 2 Manifests" })
2735
3293
  ] }),
2736
- /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_components5.Form.InputContainer, { children: [
2737
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_components5.Form.Label, { htmlFor: "defaultPreview", children: "Default preview" }),
2738
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { children: previews.configs.map((preview, key) => {
3294
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_components6.Form.InputContainer, { children: [
3295
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_components6.Form.Label, { htmlFor: "defaultPreview", children: "Default preview" }),
3296
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { children: previews.configs.map((preview, key) => {
2739
3297
  if (preview.type === "iiif-preview-service") {
2740
3298
  return null;
2741
3299
  }
2742
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_components5.Form.InputContainer, { horizontal: true, children: [
2743
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
2744
- import_components5.Form.Input,
3300
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_components6.Form.InputContainer, { horizontal: true, children: [
3301
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
3302
+ import_components6.Form.Input,
2745
3303
  {
2746
3304
  type: "radio",
2747
3305
  id: preview.id,
@@ -2750,17 +3308,25 @@ function ConfigEditor() {
2750
3308
  defaultChecked: !config.defaultPreview ? key === 0 : config.defaultPreview === preview.id
2751
3309
  }
2752
3310
  ),
2753
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("label", { htmlFor: preview.id, children: preview.label })
3311
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("label", { htmlFor: preview.id, children: preview.label })
2754
3312
  ] }, preview.id);
2755
3313
  }) })
2756
3314
  ] }),
2757
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "mt-5", children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_components5.ActionButton, { type: "submit", children: "Save changes" }) })
3315
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
3316
+ "a",
3317
+ {
3318
+ className: "text-sm text-me-primary-500 hover:underline hover:text-me-primary-600",
3319
+ href: window.location.pathname.includes("/exhibition") ? window.location.pathname.replace("/exhibition", "") || "/" : `${window.location.pathname}/exhibition`,
3320
+ children: window.location.pathname.includes("/exhibition") ? "Return to Manifest Editor" : "Go to Exhibition Editor"
3321
+ }
3322
+ ),
3323
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "mt-5", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_components6.ActionButton, { type: "submit", children: "Save changes" }) })
2758
3324
  ] }) })
2759
3325
  ] });
2760
3326
  }
2761
3327
 
2762
3328
  // src/ExportPanel/ExportPanel.tsx
2763
- var import_react22 = require("react");
3329
+ var import_react24 = require("react");
2764
3330
  var import_react_iiif_vault10 = require("react-iiif-vault");
2765
3331
 
2766
3332
  // ../ui/ui/CenterPanelContainer/CenterPanelContainer.module.css
@@ -2772,29 +3338,29 @@ var CenterPanelContainer_default = {
2772
3338
  };
2773
3339
 
2774
3340
  // ../ui/ui/CenterPanelContainer/CenterPanelContainer.tsx
2775
- var import_jsx_runtime23 = require("react/jsx-runtime");
3341
+ var import_jsx_runtime25 = require("react/jsx-runtime");
2776
3342
  function CenterPanelContainer(props) {
2777
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: CenterPanelContainer_default.CenterPanelContainer, children: [
2778
- props.title || props.close ? /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: CenterPanelContainer_default.CenterPanelHeader, children: [
2779
- props.title ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("h2", { className: CenterPanelContainer_default.CenterPanelTitle, children: props.title }) : null,
2780
- props.close ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(Button, { className: CenterPanelContainer_default.CenterPanelClose, onClick: props.close, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(CloseIcon, {}) }) : null
3343
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: CenterPanelContainer_default.CenterPanelContainer, children: [
3344
+ props.title || props.close ? /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: CenterPanelContainer_default.CenterPanelHeader, children: [
3345
+ props.title ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("h2", { className: CenterPanelContainer_default.CenterPanelTitle, children: props.title }) : null,
3346
+ props.close ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Button, { className: CenterPanelContainer_default.CenterPanelClose, onClick: props.close, children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(CloseIcon, {}) }) : null
2781
3347
  ] }) : null,
2782
3348
  props.children
2783
3349
  ] });
2784
3350
  }
2785
3351
 
2786
3352
  // ../ui/atoms/Accordion.tsx
2787
- var import_styled_components9 = __toESM(require("styled-components"), 1);
2788
- var import_react21 = require("react");
2789
- var import_jsx_runtime24 = require("react/jsx-runtime");
2790
- var AccordionContainer = import_styled_components9.default.div`
3353
+ var import_styled_components7 = __toESM(require("styled-components"), 1);
3354
+ var import_react23 = require("react");
3355
+ var import_jsx_runtime26 = require("react/jsx-runtime");
3356
+ var AccordionContainer = import_styled_components7.default.div`
2791
3357
  flex: 1;
2792
3358
  display: flex;
2793
3359
  width: 100%;
2794
3360
  flex-direction: column;
2795
3361
  position: relative;
2796
3362
  `;
2797
- var ItemRow = import_styled_components9.default.div`
3363
+ var ItemRow = import_styled_components7.default.div`
2798
3364
  background: #fff;
2799
3365
  position: relative;
2800
3366
  border-bottom: 1px solid #d0d0d0;
@@ -2813,12 +3379,12 @@ var ItemRow = import_styled_components9.default.div`
2813
3379
  //justify-content: center;
2814
3380
  }
2815
3381
  `;
2816
- var ItemDescription = import_styled_components9.default.p`
3382
+ var ItemDescription = import_styled_components7.default.p`
2817
3383
  font-size: 0.9em;
2818
3384
  color: #777;
2819
3385
  font-weight: 400;
2820
3386
  `;
2821
- var ItemLabel = import_styled_components9.default.button`
3387
+ var ItemLabel = import_styled_components7.default.button`
2822
3388
  color: inherit;
2823
3389
  text-rendering: geometricPrecision;
2824
3390
  border: none;
@@ -2861,7 +3427,7 @@ var ItemLabel = import_styled_components9.default.button`
2861
3427
  }
2862
3428
  }
2863
3429
  `;
2864
- var ItemCollapse = import_styled_components9.default.div`
3430
+ var ItemCollapse = import_styled_components7.default.div`
2865
3431
  font-size: 1.4em;
2866
3432
  padding-right: 0.3em;
2867
3433
  display: flex;
@@ -2871,7 +3437,7 @@ var ItemCollapse = import_styled_components9.default.div`
2871
3437
  font-size: 2em;
2872
3438
  }
2873
3439
  `;
2874
- var ItemIcon = import_styled_components9.default.div`
3440
+ var ItemIcon = import_styled_components7.default.div`
2875
3441
  width: 2em;
2876
3442
  align-items: center;
2877
3443
  //padding-top: 0.5em;
@@ -2885,12 +3451,12 @@ var ItemIcon = import_styled_components9.default.div`
2885
3451
  color: #999;
2886
3452
  }
2887
3453
  `;
2888
- var ItemBodyInner = import_styled_components9.default.div`
3454
+ var ItemBodyInner = import_styled_components7.default.div`
2889
3455
  min-height: 0;
2890
3456
  overflow: visible;
2891
3457
  display: flex;
2892
3458
  `;
2893
- var ItemBodyPadding = import_styled_components9.default.div`
3459
+ var ItemBodyPadding = import_styled_components7.default.div`
2894
3460
  min-height: 0;
2895
3461
  overflow: visible;
2896
3462
  flex: 1;
@@ -2904,7 +3470,7 @@ var ItemBodyPadding = import_styled_components9.default.div`
2904
3470
  overflow-y: auto;
2905
3471
  }
2906
3472
  `;
2907
- var ItemBody = import_styled_components9.default.section`
3473
+ var ItemBody = import_styled_components7.default.section`
2908
3474
  display: grid;
2909
3475
  grid-template-rows: 0fr;
2910
3476
  overflow: hidden;
@@ -2933,7 +3499,7 @@ var ItemBody = import_styled_components9.default.section`
2933
3499
  box-shadow: inset 0px 2px 0px 0 rgba(0, 0, 0, 0.1);
2934
3500
  }
2935
3501
  `;
2936
- var ItemHeading = import_styled_components9.default.div`
3502
+ var ItemHeading = import_styled_components7.default.div`
2937
3503
  position: sticky;
2938
3504
  display: flex;
2939
3505
  top: 0;
@@ -2973,11 +3539,11 @@ var ItemHeading = import_styled_components9.default.div`
2973
3539
  var noop = () => void 0;
2974
3540
  var keyIdIndex = 0;
2975
3541
  function useId() {
2976
- return (0, import_react21.useMemo)(() => keyIdIndex++, []);
3542
+ return (0, import_react23.useMemo)(() => keyIdIndex++, []);
2977
3543
  }
2978
3544
  function useAccordionItems(itemsLength, singleMode = false) {
2979
- const [elRefs, setElRefs] = (0, import_react21.useState)([]);
2980
- const current = (0, import_react21.useRef)(-1);
3545
+ const [elRefs, setElRefs] = (0, import_react23.useState)([]);
3546
+ const current = (0, import_react23.useRef)(-1);
2981
3547
  const onKeyDown = (e) => {
2982
3548
  const currentEl = document.activeElement;
2983
3549
  const currentIndex = elRefs.findIndex((r) => r.current?.button?.current === currentEl);
@@ -3045,9 +3611,9 @@ function useAccordionItems(itemsLength, singleMode = false) {
3045
3611
  }
3046
3612
  }
3047
3613
  };
3048
- (0, import_react21.useEffect)(() => {
3614
+ (0, import_react23.useEffect)(() => {
3049
3615
  setElRefs(
3050
- (elRefs_) => Array(itemsLength).fill(0).map((_, i) => elRefs_[i] || (0, import_react21.createRef)())
3616
+ (elRefs_) => Array(itemsLength).fill(0).map((_, i) => elRefs_[i] || (0, import_react23.createRef)())
3051
3617
  );
3052
3618
  }, [itemsLength]);
3053
3619
  const getItemProps = (key) => {
@@ -3103,19 +3669,19 @@ function useAccordionItems(itemsLength, singleMode = false) {
3103
3669
  getItemProps
3104
3670
  };
3105
3671
  }
3106
- var AccordionItem = (0, import_react21.forwardRef)(function AccordionItem2(props, ref) {
3107
- const content = (0, import_react21.useRef)(null);
3108
- const btn = (0, import_react21.useRef)(null);
3672
+ var AccordionItem = (0, import_react23.forwardRef)(function AccordionItem2(props, ref) {
3673
+ const content = (0, import_react23.useRef)(null);
3674
+ const btn = (0, import_react23.useRef)(null);
3109
3675
  const id = useId();
3110
- const [open, setIsOpen] = (0, import_react21.useState)(props.initialOpen || false);
3676
+ const [open, setIsOpen] = (0, import_react23.useState)(props.initialOpen || false);
3111
3677
  const onChange = props.onChange || noop;
3112
3678
  const toggle = () => {
3113
3679
  onChange(!open);
3114
3680
  setIsOpen((o) => !o);
3115
3681
  };
3116
3682
  const maxHeight = props.maxHeight;
3117
- const [scrolled, setScrolled] = (0, import_react21.useState)(false);
3118
- (0, import_react21.useImperativeHandle)(ref, () => ({
3683
+ const [scrolled, setScrolled] = (0, import_react23.useState)(false);
3684
+ (0, import_react23.useImperativeHandle)(ref, () => ({
3119
3685
  open() {
3120
3686
  onChange(true);
3121
3687
  setIsOpen(true);
@@ -3141,16 +3707,16 @@ var AccordionItem = (0, import_react21.forwardRef)(function AccordionItem2(props
3141
3707
  setScrolled(false);
3142
3708
  }
3143
3709
  };
3144
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(ItemRow, { "data-large": props.large, "data-open": open, children: [
3145
- /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(ItemHeading, { "data-open": open, children: [
3146
- props.icon ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(ItemIcon, { onClick: toggle, children: props.icon }) : null,
3147
- /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(ItemLabel, { ref: btn, onClick: toggle, "aria-expanded": open, "aria-controls": `accordion-${id}`, children: [
3710
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(ItemRow, { "data-large": props.large, "data-open": open, children: [
3711
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(ItemHeading, { "data-open": open, children: [
3712
+ props.icon ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(ItemIcon, { onClick: toggle, children: props.icon }) : null,
3713
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(ItemLabel, { ref: btn, onClick: toggle, "aria-expanded": open, "aria-controls": `accordion-${id}`, children: [
3148
3714
  props.label,
3149
- props.description ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(ItemDescription, { children: props.description }) : null
3715
+ props.description ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(ItemDescription, { children: props.description }) : null
3150
3716
  ] }),
3151
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(ItemCollapse, { onClick: toggle, children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(DownIcon, { width: "1em", height: "1em", rotate: open ? 0 : 180 }) })
3717
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(ItemCollapse, { onClick: toggle, children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(DownIcon, { width: "1em", height: "1em", rotate: open ? 0 : 180 }) })
3152
3718
  ] }),
3153
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
3719
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
3154
3720
  ItemBody,
3155
3721
  {
3156
3722
  "aria-labelledby": `accordion-${id}`,
@@ -3162,7 +3728,7 @@ var AccordionItem = (0, import_react21.forwardRef)(function AccordionItem2(props
3162
3728
  $initial: !open,
3163
3729
  "data-scrolled": scrolled,
3164
3730
  hidden: !open,
3165
- children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(ItemBodyInner, { children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
3731
+ children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(ItemBodyInner, { children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
3166
3732
  ItemBodyPadding,
3167
3733
  {
3168
3734
  "data-max-height": !!maxHeight,
@@ -3177,18 +3743,18 @@ var AccordionItem = (0, import_react21.forwardRef)(function AccordionItem2(props
3177
3743
  });
3178
3744
  function Accordion(props) {
3179
3745
  const { getItemProps, onKeyDown } = useAccordionItems(props.items.length, props.singleMode);
3180
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(AccordionContainer, { onKeyDown, children: props.items.map((item, key) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(AccordionItem, { overflow: props.overflow, maxHeight: props.maxHeight, ...item, ...getItemProps(key), children: item.children }, key)) });
3746
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(AccordionContainer, { onKeyDown, children: props.items.map((item, key) => /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(AccordionItem, { overflow: props.overflow, maxHeight: props.maxHeight, ...item, ...getItemProps(key), children: item.children }, key)) });
3181
3747
  }
3182
3748
 
3183
3749
  // ../ui/icons/DownloadIcon.tsx
3184
- var import_jsx_runtime25 = require("react/jsx-runtime");
3750
+ var import_jsx_runtime27 = require("react/jsx-runtime");
3185
3751
  function DownloadIcon() {
3186
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("svg", { xmlns: "http://www.w3.org/2000/svg", height: "48", viewBox: "0 -960 960 960", width: "48", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("path", { d: "M220-160q-24 0-42-18t-18-42v-143h60v143h520v-143h60v143q0 24-18 42t-42 18H220Zm260-153L287-506l43-43 120 120v-371h60v371l120-120 43 43-193 193Z" }) });
3752
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("svg", { xmlns: "http://www.w3.org/2000/svg", height: "48", viewBox: "0 -960 960 960", width: "48", children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("path", { d: "M220-160q-24 0-42-18t-18-42v-143h60v143h520v-143h60v143q0 24-18 42t-42 18H220Zm260-153L287-506l43-43 120 120v-371h60v371l120-120 43 43-193 193Z" }) });
3187
3753
  }
3188
3754
 
3189
3755
  // ../ui/atoms/ButtonRow.tsx
3190
- var import_styled_components10 = __toESM(require("styled-components"), 1);
3191
- var ButtonRow = import_styled_components10.default.div`
3756
+ var import_styled_components8 = __toESM(require("styled-components"), 1);
3757
+ var ButtonRow = import_styled_components8.default.div`
3192
3758
  padding: 0.3em;
3193
3759
 
3194
3760
  display: flex;
@@ -3213,18 +3779,18 @@ var ButtonRow = import_styled_components10.default.div`
3213
3779
  `;
3214
3780
 
3215
3781
  // src/ExportPanel/ExportPanel.tsx
3216
- var import_jsx_runtime26 = require("react/jsx-runtime");
3782
+ var import_jsx_runtime28 = require("react/jsx-runtime");
3217
3783
  function ExportPanel(props) {
3218
3784
  const manifest = (0, import_react_iiif_vault10.useManifest)();
3219
3785
  const vault = (0, import_react_iiif_vault10.useVault)();
3220
3786
  const actions = useLayoutActions();
3221
- const version3 = (0, import_react22.useMemo)(() => {
3787
+ const version3 = (0, import_react24.useMemo)(() => {
3222
3788
  return JSON.stringify(vault.toPresentation3(manifest), null, 2);
3223
3789
  }, [manifest, vault]);
3224
- const version2 = (0, import_react22.useMemo)(() => {
3790
+ const version2 = (0, import_react24.useMemo)(() => {
3225
3791
  return JSON.stringify(vault.toPresentation2(manifest), null, 2);
3226
3792
  }, [manifest, vault]);
3227
- return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(CenterPanelContainer, { title: "Export manifest", close: actions.centerPanel.popStack, children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { style: { flex: 1, overflowY: "auto" }, children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
3793
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(CenterPanelContainer, { title: "Export manifest", close: actions.centerPanel.popStack, children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { style: { flex: 1, overflowY: "auto" }, children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
3228
3794
  Accordion,
3229
3795
  {
3230
3796
  items: [
@@ -3235,12 +3801,12 @@ function ExportPanel(props) {
3235
3801
  large: true,
3236
3802
  initialOpen: true,
3237
3803
  overflow: true,
3238
- icon: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(Button, { onClick: () => createDownload(version3, "manifest.json"), children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(DownloadIcon, {}) }),
3239
- children: /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { style: { maxWidth: "100%" }, children: [
3240
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("pre", { style: { whiteSpace: "pre-wrap" }, children: JSON.stringify(vault.toPresentation3(manifest), null, 2) }),
3241
- /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(ButtonRow, { "data-sticky": "true", children: [
3242
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(Button, { onClick: () => copyToClipboard(version3), children: "Copy to clipboard" }),
3243
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(Button, { onClick: () => createDownload(version3, "manifest.json"), children: "Download" })
3804
+ icon: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(Button, { onClick: () => createDownload(version3, "manifest.json"), children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(DownloadIcon, {}) }),
3805
+ children: /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { style: { maxWidth: "100%" }, children: [
3806
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("pre", { style: { whiteSpace: "pre-wrap" }, children: JSON.stringify(vault.toPresentation3(manifest), null, 2) }),
3807
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(ButtonRow, { "data-sticky": "true", children: [
3808
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(Button, { onClick: () => copyToClipboard(version3), children: "Copy to clipboard" }),
3809
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(Button, { onClick: () => createDownload(version3, "manifest.json"), children: "Download" })
3244
3810
  ] })
3245
3811
  ] })
3246
3812
  },
@@ -3249,12 +3815,12 @@ function ExportPanel(props) {
3249
3815
  description: 'Download this version by clicking the "Download" button.',
3250
3816
  maxHeight: 400,
3251
3817
  large: true,
3252
- icon: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(Button, { onClick: () => createDownload(version2, "manifest.json"), children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(DownloadIcon, {}) }),
3253
- children: /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { style: { maxWidth: "100%" }, children: [
3254
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("pre", { style: { whiteSpace: "pre-wrap" }, children: JSON.stringify(vault.toPresentation2(manifest), null, 2) }),
3255
- /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(ButtonRow, { "data-sticky": "true", children: [
3256
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(Button, { onClick: () => copyToClipboard(version2), children: "Copy to clipboard" }),
3257
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(Button, { onClick: () => createDownload(version2, "manifest.json"), children: "Download" })
3818
+ icon: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(Button, { onClick: () => createDownload(version2, "manifest.json"), children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(DownloadIcon, {}) }),
3819
+ children: /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { style: { maxWidth: "100%" }, children: [
3820
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("pre", { style: { whiteSpace: "pre-wrap" }, children: JSON.stringify(vault.toPresentation2(manifest), null, 2) }),
3821
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(ButtonRow, { "data-sticky": "true", children: [
3822
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(Button, { onClick: () => copyToClipboard(version2), children: "Copy to clipboard" }),
3823
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(Button, { onClick: () => createDownload(version2, "manifest.json"), children: "Download" })
3258
3824
  ] })
3259
3825
  ] })
3260
3826
  }
@@ -3263,6 +3829,9 @@ function ExportPanel(props) {
3263
3829
  ) }) });
3264
3830
  }
3265
3831
 
3832
+ // src/Layout/Layout.tsx
3833
+ var import_components7 = require("@manifest-editor/components");
3834
+
3266
3835
  // ../ui/ui/GhostBlocks/GhostBlocks.module.css
3267
3836
  var GhostBlocks_default = {
3268
3837
  ghostLoadingBlock: "GhostBlocks_ghostLoadingBlock",
@@ -3271,40 +3840,60 @@ var GhostBlocks_default = {
3271
3840
  };
3272
3841
 
3273
3842
  // ../ui/ui/GhostBlocks/GhostBlocks.tsx
3274
- var import_jsx_runtime27 = require("react/jsx-runtime");
3843
+ var import_jsx_runtime29 = require("react/jsx-runtime");
3275
3844
  function GhostBlocks() {
3276
- return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(import_jsx_runtime27.Fragment, { children: [
3277
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { "data-header": "true", className: GhostBlocks_default.ghostLoadingBlock }),
3278
- /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: GhostBlocks_default.ghostBlockList, children: [
3279
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: GhostBlocks_default.ghostLoadingBlock }),
3280
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: GhostBlocks_default.ghostLoadingBlock }),
3281
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: GhostBlocks_default.ghostLoadingBlock }),
3282
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: GhostBlocks_default.ghostLoadingBlock })
3845
+ return /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(import_jsx_runtime29.Fragment, { children: [
3846
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { "data-header": "true", className: GhostBlocks_default.ghostLoadingBlock }),
3847
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: GhostBlocks_default.ghostBlockList, children: [
3848
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: GhostBlocks_default.ghostLoadingBlock }),
3849
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: GhostBlocks_default.ghostLoadingBlock }),
3850
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: GhostBlocks_default.ghostLoadingBlock }),
3851
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: GhostBlocks_default.ghostLoadingBlock })
3283
3852
  ] })
3284
3853
  ] });
3285
3854
  }
3286
3855
 
3287
3856
  // src/Layout/Layout.tsx
3288
- var import_react27 = require("react");
3857
+ var import_react29 = require("react");
3289
3858
  var import_react_iiif_vault11 = require("react-iiif-vault");
3290
3859
  var import_react_transition_group = require("react-transition-group");
3291
3860
  var import_shallowequal = __toESM(require("shallowequal"), 1);
3292
3861
 
3862
+ // src/hooks/use-match-media.ts
3863
+ var import_react25 = require("react");
3864
+ function useMatchMedia(queries, defaultValues = []) {
3865
+ const initialValues = defaultValues.length ? defaultValues : Array(queries.length).fill(false);
3866
+ if (typeof window === "undefined")
3867
+ return initialValues;
3868
+ const mediaQueryLists = queries.map((q) => window.matchMedia(q));
3869
+ const getValue2 = () => {
3870
+ const matchedQueries = mediaQueryLists.map((mql) => mql.matches);
3871
+ return matchedQueries;
3872
+ };
3873
+ const [value, setValue] = (0, import_react25.useState)(getValue2);
3874
+ (0, import_react25.useLayoutEffect)(() => {
3875
+ const handler = () => setValue(getValue2);
3876
+ mediaQueryLists.forEach((mql) => mql.addListener(handler));
3877
+ return () => mediaQueryLists.forEach((mql) => mql.removeListener(handler));
3878
+ }, []);
3879
+ return value;
3880
+ }
3881
+
3293
3882
  // src/Layout/Layout.mobile.tsx
3294
- var import_styled_components11 = __toESM(require("styled-components"), 1);
3295
- var Container2 = import_styled_components11.default.div`
3883
+ var import_styled_components9 = __toESM(require("styled-components"), 1);
3884
+ var Container2 = import_styled_components9.default.div`
3296
3885
  position: relative;
3297
3886
  display: flex;
3298
3887
  flex: 1;
3299
3888
  overflow: hidden;
3300
3889
  flex-direction: column;
3301
3890
  `;
3302
- var CenterPanel = import_styled_components11.default.div`
3891
+ var CenterPanel = import_styled_components9.default.div`
3303
3892
  flex: 1;
3304
3893
  position: relative;
3305
3894
  z-index: 7;
3306
3895
  `;
3307
- var MobileBar = import_styled_components11.default.div`
3896
+ var MobileBar = import_styled_components9.default.div`
3308
3897
  display: flex;
3309
3898
  justify-content: space-around;
3310
3899
  width: 100%;
@@ -3313,7 +3902,7 @@ var MobileBar = import_styled_components11.default.div`
3313
3902
  padding: 0.5em;
3314
3903
  height: 3.4rem;
3315
3904
  `;
3316
- var LeftBarButton = import_styled_components11.default.button`
3905
+ var LeftBarButton = import_styled_components9.default.button`
3317
3906
  //background: red;
3318
3907
  padding: 0.5em 1em;
3319
3908
  width: 32%;
@@ -3322,7 +3911,7 @@ var LeftBarButton = import_styled_components11.default.button`
3322
3911
  border: none;
3323
3912
  background: #ffffff;
3324
3913
  `;
3325
- var PreviewBarButton = import_styled_components11.default.button`
3914
+ var PreviewBarButton = import_styled_components9.default.button`
3326
3915
  padding: 0.5em 1em;
3327
3916
  width: 32%;
3328
3917
 
@@ -3332,13 +3921,13 @@ var PreviewBarButton = import_styled_components11.default.button`
3332
3921
  border: 1px solid rgba(0, 0, 0, 0.21);
3333
3922
  color: #ffffff;
3334
3923
  `;
3335
- var DrawerContainer = import_styled_components11.default.div`
3924
+ var DrawerContainer = import_styled_components9.default.div`
3336
3925
  position: relative;
3337
3926
  width: 32%;
3338
3927
  margin: 0 0.75em;
3339
3928
  z-index: 9;
3340
3929
  `;
3341
- var DrawerButton = import_styled_components11.default.button`
3930
+ var DrawerButton = import_styled_components9.default.button`
3342
3931
  padding: 0.4em 1em 0.65em;
3343
3932
  position: absolute;
3344
3933
  width: 100%;
@@ -3358,7 +3947,7 @@ var DrawerButton = import_styled_components11.default.button`
3358
3947
  font-size: 1.8em;
3359
3948
  }
3360
3949
  `;
3361
- var DrawerBody = import_styled_components11.default.div`
3950
+ var DrawerBody = import_styled_components9.default.div`
3362
3951
  background: #fff;
3363
3952
  display: flex;
3364
3953
  position: absolute;
@@ -3375,7 +3964,7 @@ var DrawerBody = import_styled_components11.default.div`
3375
3964
  transition:
3376
3965
  0.3s transform ease-in-out,
3377
3966
  0.3s box-shadow;
3378
- ${(props) => props.$open && import_styled_components11.css`
3967
+ ${(props) => props.$open && import_styled_components9.css`
3379
3968
  box-shadow:
3380
3969
  0 -5px 15px 0 rgba(0, 0, 0, 0.1),
3381
3970
  0 -3px 5px 0 rgba(0, 0, 0, 0.1);
@@ -3389,7 +3978,7 @@ var DrawerBody = import_styled_components11.default.div`
3389
3978
  font-size: 1.1em;
3390
3979
  }
3391
3980
  `;
3392
- var LeftPanel = import_styled_components11.default.div`
3981
+ var LeftPanel = import_styled_components9.default.div`
3393
3982
  position: absolute;
3394
3983
  transform: translateX(-100%);
3395
3984
  background: #fff;
@@ -3399,11 +3988,11 @@ var LeftPanel = import_styled_components11.default.div`
3399
3988
  z-index: 10;
3400
3989
  overflow-y: auto;
3401
3990
  transition: 0.5s transform;
3402
- ${(props) => props.$open && import_styled_components11.css`
3991
+ ${(props) => props.$open && import_styled_components9.css`
3403
3992
  transform: translateX(0);
3404
3993
  `}
3405
3994
  `;
3406
- var Lightbox = import_styled_components11.default.div`
3995
+ var Lightbox = import_styled_components9.default.div`
3407
3996
  background: rgba(0, 0, 0, 0.4);
3408
3997
  pointer-events: none;
3409
3998
  position: absolute;
@@ -3415,15 +4004,15 @@ var Lightbox = import_styled_components11.default.div`
3415
4004
  opacity: 0;
3416
4005
  transition: opacity 0.5s;
3417
4006
 
3418
- ${(props) => props.$open && import_styled_components11.css`
4007
+ ${(props) => props.$open && import_styled_components9.css`
3419
4008
  pointer-events: visible;
3420
4009
  opacity: 1;
3421
4010
  `}
3422
4011
  `;
3423
4012
 
3424
4013
  // src/Layout/Layout.styles.ts
3425
- var import_styled_components12 = __toESM(require("styled-components"), 1);
3426
- var OuterWrapper = import_styled_components12.default.div`
4014
+ var import_styled_components10 = __toESM(require("styled-components"), 1);
4015
+ var OuterWrapper = import_styled_components10.default.div`
3427
4016
  display: flex;
3428
4017
  flex-direction: column;
3429
4018
  flex: 1;
@@ -3433,19 +4022,19 @@ var OuterWrapper = import_styled_components12.default.div`
3433
4022
  min-width: 0;
3434
4023
  overflow: hidden;
3435
4024
  `;
3436
- var Header2 = import_styled_components12.default.header`
4025
+ var Header2 = import_styled_components10.default.header`
3437
4026
  //box-shadow: 0 3px 2px 0 rgba(0, 0, 0, 0.04), 0 1px 0 0 rgba(0, 0, 0, 0.17);
3438
4027
  z-index: 200;
3439
4028
  `;
3440
- var Footer = import_styled_components12.default.div`
4029
+ var Footer = import_styled_components10.default.div`
3441
4030
  background: #fff;
3442
4031
  `;
3443
- var Main = import_styled_components12.default.div`
4032
+ var Main = import_styled_components10.default.div`
3444
4033
  display: flex;
3445
4034
  flex: 1 1 0;
3446
4035
  min-height: 0;
3447
4036
  `;
3448
- var LeftPanel2 = import_styled_components12.default.div`
4037
+ var LeftPanel2 = import_styled_components10.default.div`
3449
4038
  background: #fff;
3450
4039
  display: flex;
3451
4040
  flex-direction: column;
@@ -3453,29 +4042,29 @@ var LeftPanel2 = import_styled_components12.default.div`
3453
4042
  max-width: 720px;
3454
4043
  align-items: flex-end;
3455
4044
 
3456
- ${(props) => props.$motion ? import_styled_components12.css`
4045
+ ${(props) => props.$motion ? import_styled_components10.css`
3457
4046
  transition: max-width 400ms;
3458
4047
  ` : ""}
3459
4048
 
3460
4049
  ${(props) => {
3461
4050
  switch (props.$state) {
3462
4051
  case "entering":
3463
- return import_styled_components12.css`
4052
+ return import_styled_components10.css`
3464
4053
  max-width: ${props.$width};
3465
4054
  `;
3466
4055
  case "exiting":
3467
- return import_styled_components12.css`
4056
+ return import_styled_components10.css`
3468
4057
  max-width: 0;
3469
4058
  `;
3470
4059
  case "unmounted":
3471
4060
  case "exited":
3472
- return import_styled_components12.css`
4061
+ return import_styled_components10.css`
3473
4062
  max-width: 0;
3474
4063
  `;
3475
4064
  }
3476
4065
  }}
3477
4066
  `;
3478
- var CenterPanel2 = import_styled_components12.default.div`
4067
+ var CenterPanel2 = import_styled_components10.default.div`
3479
4068
  flex: 1 1 0;
3480
4069
  background: #e3e7f0;
3481
4070
  // background: #efefef;
@@ -3495,7 +4084,7 @@ var CenterPanel2 = import_styled_components12.default.div`
3495
4084
  min-width: 0;
3496
4085
  }
3497
4086
  `;
3498
- var RightPanel = import_styled_components12.default.div`
4087
+ var RightPanel = import_styled_components10.default.div`
3499
4088
  background: #fff;
3500
4089
  display: flex;
3501
4090
  flex-direction: column;
@@ -3507,22 +4096,22 @@ var RightPanel = import_styled_components12.default.div`
3507
4096
  ${(props) => {
3508
4097
  switch (props.$state) {
3509
4098
  case "entering":
3510
- return import_styled_components12.css`
4099
+ return import_styled_components10.css`
3511
4100
  max-width: ${props.$width};
3512
4101
  `;
3513
4102
  case "exiting":
3514
- return import_styled_components12.css`
4103
+ return import_styled_components10.css`
3515
4104
  max-width: 0;
3516
4105
  `;
3517
4106
  case "unmounted":
3518
4107
  case "exited":
3519
- return import_styled_components12.css`
4108
+ return import_styled_components10.css`
3520
4109
  max-width: 0;
3521
4110
  `;
3522
4111
  }
3523
4112
  }}
3524
4113
  `;
3525
- var PanelContainer = import_styled_components12.default.div`
4114
+ var PanelContainer = import_styled_components10.default.div`
3526
4115
  display: flex;
3527
4116
  flex: 1;
3528
4117
  height: 100%;
@@ -3533,14 +4122,14 @@ var PanelContainer = import_styled_components12.default.div`
3533
4122
  ${(props) => {
3534
4123
  switch (props.$menu) {
3535
4124
  case "top":
3536
- return import_styled_components12.css`
4125
+ return import_styled_components10.css`
3537
4126
  flex-direction: column;
3538
4127
  ${PanelMenu} {
3539
4128
  flex-direction: column;
3540
4129
  }
3541
4130
  `;
3542
4131
  case "left":
3543
- return import_styled_components12.css`
4132
+ return import_styled_components10.css`
3544
4133
  flex-direction: row;
3545
4134
  ${PanelMenu} {
3546
4135
  flex-direction: row;
@@ -3548,14 +4137,14 @@ var PanelContainer = import_styled_components12.default.div`
3548
4137
  `;
3549
4138
  default:
3550
4139
  case "bottom":
3551
- return import_styled_components12.css`
4140
+ return import_styled_components10.css`
3552
4141
  flex-direction: column-reverse;
3553
4142
  ${PanelMenu} {
3554
4143
  flex-direction: column;
3555
4144
  }
3556
4145
  `;
3557
4146
  case "right":
3558
- return import_styled_components12.css`
4147
+ return import_styled_components10.css`
3559
4148
  flex-direction: row-reverse;
3560
4149
  ${PanelMenu} {
3561
4150
  flex-direction: row;
@@ -3564,7 +4153,7 @@ var PanelContainer = import_styled_components12.default.div`
3564
4153
  }
3565
4154
  }}
3566
4155
  `;
3567
- var PanelSideMenu = import_styled_components12.default.div`
4156
+ var PanelSideMenu = import_styled_components10.default.div`
3568
4157
  background: #fff;
3569
4158
  border-top: 1px solid #e3e7f0;
3570
4159
  border-right: 1px solid #e3e7f0;
@@ -3575,7 +4164,7 @@ var PanelSideMenu = import_styled_components12.default.div`
3575
4164
  padding: 0.3em;
3576
4165
  gap: 0.3em; */
3577
4166
  `;
3578
- var PanelSideMenuItem = import_styled_components12.default.button`
4167
+ var PanelSideMenuItem = import_styled_components10.default.button`
3579
4168
  cursor: pointer;
3580
4169
  aspect-ratio: 1;
3581
4170
  width: 3em;
@@ -3603,17 +4192,17 @@ var PanelSideMenuItem = import_styled_components12.default.button`
3603
4192
  color: #999;
3604
4193
  }
3605
4194
  `;
3606
- var PanelMenu = import_styled_components12.default.div`
4195
+ var PanelMenu = import_styled_components10.default.div`
3607
4196
  display: flex;
3608
4197
  box-shadow:
3609
4198
  0 -3px 2px 0 rgba(0, 0, 0, 0.04),
3610
4199
  0 -1px 0 0 rgba(0, 0, 0, 0.17);
3611
4200
 
3612
- ${(props) => !props.$open && (props.$position === "top" || props.$position === "bottom") ? import_styled_components12.css`
4201
+ ${(props) => !props.$open && (props.$position === "top" || props.$position === "bottom") ? import_styled_components10.css`
3613
4202
  display: none;
3614
4203
  ` : ""}
3615
4204
  `;
3616
- var PanelContent = import_styled_components12.default.div`
4205
+ var PanelContent = import_styled_components10.default.div`
3617
4206
  display: flex;
3618
4207
  flex-direction: column;
3619
4208
  flex: 1;
@@ -3622,25 +4211,25 @@ var PanelContent = import_styled_components12.default.div`
3622
4211
  `;
3623
4212
 
3624
4213
  // src/Layout/components/HandleControls.tsx
3625
- var import_styled_components13 = __toESM(require("styled-components"), 1);
3626
- var import_react23 = require("react");
4214
+ var import_styled_components11 = __toESM(require("styled-components"), 1);
4215
+ var import_react26 = require("react");
3627
4216
 
3628
4217
  // ../ui/icons/ResetIcon.tsx
3629
- var import_jsx_runtime28 = require("react/jsx-runtime");
3630
- var ResetIcon = (props) => /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("svg", { xmlns: "http://www.w3.org/2000/svg", height: "1em", width: "1em", viewBox: "0 0 24 24", ...props, children: [
3631
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("path", { d: "M0 0h24v24H0V0z", fill: "none" }),
3632
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("path", { d: "M12 5V2L8 6l4 4V7c3.31 0 6 2.69 6 6 0 2.97-2.17 5.43-5 5.91v2.02c3.95-.49 7-3.85 7-7.93 0-4.42-3.58-8-8-8zM6 13c0-1.65.67-3.15 1.76-4.24L6.34 7.34A8.014 8.014 0 0 0 4 13c0 4.08 3.05 7.44 7 7.93v-2.02c-2.83-.48-5-2.94-5-5.91z" })
4218
+ var import_jsx_runtime30 = require("react/jsx-runtime");
4219
+ var ResetIcon = (props) => /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("svg", { xmlns: "http://www.w3.org/2000/svg", height: "1em", width: "1em", viewBox: "0 0 24 24", ...props, children: [
4220
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("path", { d: "M0 0h24v24H0V0z", fill: "none" }),
4221
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("path", { d: "M12 5V2L8 6l4 4V7c3.31 0 6 2.69 6 6 0 2.97-2.17 5.43-5 5.91v2.02c3.95-.49 7-3.85 7-7.93 0-4.42-3.58-8-8-8zM6 13c0-1.65.67-3.15 1.76-4.24L6.34 7.34A8.014 8.014 0 0 0 4 13c0 4.08 3.05 7.44 7 7.93v-2.02c-2.83-.48-5-2.94-5-5.91z" })
3633
4222
  ] });
3634
4223
 
3635
4224
  // src/Layout/components/HandleControls.tsx
3636
- var import_jsx_runtime29 = require("react/jsx-runtime");
3637
- var HandleContainer = import_styled_components13.default.div`
4225
+ var import_jsx_runtime31 = require("react/jsx-runtime");
4226
+ var HandleContainer = import_styled_components11.default.div`
3638
4227
  position: relative;
3639
4228
  width: 1px;
3640
4229
  background: rgba(0, 0, 0, 0.2);
3641
4230
  z-index: 50;
3642
4231
  `;
3643
- var HandleControl = (0, import_styled_components13.default)(ButtonReset)`
4232
+ var HandleControl = (0, import_styled_components11.default)(ButtonReset)`
3644
4233
  transition:
3645
4234
  opacity 300ms,
3646
4235
  transform 300ms;
@@ -3653,7 +4242,7 @@ var HandleControl = (0, import_styled_components13.default)(ButtonReset)`
3653
4242
  outline: 2px solid salmon;
3654
4243
  }
3655
4244
  `;
3656
- var ResizeHandle = (0, import_styled_components13.default)(HandleControl)`
4245
+ var ResizeHandle = (0, import_styled_components11.default)(HandleControl)`
3657
4246
  position: relative;
3658
4247
  background: #fff;
3659
4248
  height: 40px;
@@ -3662,7 +4251,7 @@ var ResizeHandle = (0, import_styled_components13.default)(HandleControl)`
3662
4251
  box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2);
3663
4252
  user-select: none;
3664
4253
  `;
3665
- var IconControl = (0, import_styled_components13.default)(HandleControl)`
4254
+ var IconControl = (0, import_styled_components11.default)(HandleControl)`
3666
4255
  background: #fff;
3667
4256
  width: 30px;
3668
4257
  height: 30px;
@@ -3677,7 +4266,7 @@ var IconControl = (0, import_styled_components13.default)(HandleControl)`
3677
4266
  fill: #9999;
3678
4267
  }
3679
4268
  `;
3680
- var OpenControl = (0, import_styled_components13.default)(HandleControl)`
4269
+ var OpenControl = (0, import_styled_components11.default)(HandleControl)`
3681
4270
  position: relative;
3682
4271
  display: flex;
3683
4272
  opacity: 1;
@@ -3705,7 +4294,7 @@ var OpenControl = (0, import_styled_components13.default)(HandleControl)`
3705
4294
  font-size: 1.5em;
3706
4295
  }
3707
4296
  `;
3708
- var InnerHandleContainer = import_styled_components13.default.div`
4297
+ var InnerHandleContainer = import_styled_components11.default.div`
3709
4298
  background: rgba(0, 0, 0, 0);
3710
4299
  position: absolute;
3711
4300
  width: 21px;
@@ -3734,7 +4323,7 @@ var InnerHandleContainer = import_styled_components13.default.div`
3734
4323
  }
3735
4324
  }
3736
4325
  `;
3737
- var UnscaledContainer = import_styled_components13.default.div`
4326
+ var UnscaledContainer = import_styled_components11.default.div`
3738
4327
  background: rgba(0, 0, 0, 0);
3739
4328
  position: absolute;
3740
4329
  pointer-events: none;
@@ -3744,9 +4333,9 @@ var UnscaledContainer = import_styled_components13.default.div`
3744
4333
  bottom: 0;
3745
4334
  z-index: 51; // This will always be quite high.
3746
4335
  `;
3747
- var HandleControls = (0, import_react23.forwardRef)(function HandleControls2({ dir, open, actions, reset }, ref) {
3748
- return /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(HandleContainer, { onClick: () => actions.open(), children: [
3749
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(UnscaledContainer, { $open: open, $dir: dir, children: !open ? /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
4336
+ var HandleControls = (0, import_react26.forwardRef)(function HandleControls2({ dir, open, actions, reset }, ref) {
4337
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(HandleContainer, { onClick: () => actions.open(), children: [
4338
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(UnscaledContainer, { $open: open, $dir: dir, children: !open ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
3750
4339
  OpenControl,
3751
4340
  {
3752
4341
  $dir: dir,
@@ -3754,42 +4343,42 @@ var HandleControls = (0, import_react23.forwardRef)(function HandleControls2({ d
3754
4343
  e.stopPropagation();
3755
4344
  actions.open();
3756
4345
  },
3757
- children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(DownIcon, { rotate: dir === "right" ? 90 : 270 })
4346
+ children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(DownIcon, { rotate: dir === "right" ? 90 : 270 })
3758
4347
  }
3759
4348
  ) : null }),
3760
- /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(InnerHandleContainer, { ref, $open: open, $dir: dir, children: [
3761
- open ? /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
4349
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(InnerHandleContainer, { ref, $open: open, $dir: dir, children: [
4350
+ open ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
3762
4351
  IconControl,
3763
4352
  {
3764
4353
  onClick: (e) => {
3765
4354
  e.stopPropagation();
3766
4355
  actions.close();
3767
4356
  },
3768
- children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(CloseIcon, {})
4357
+ children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(CloseIcon, {})
3769
4358
  }
3770
4359
  ) : null,
3771
- reset && open ? /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
4360
+ reset && open ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
3772
4361
  IconControl,
3773
4362
  {
3774
4363
  onClick: (e) => {
3775
4364
  e.stopPropagation();
3776
4365
  reset();
3777
4366
  },
3778
- children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(ResetIcon, {})
4367
+ children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(ResetIcon, {})
3779
4368
  }
3780
4369
  ) : null,
3781
- open ? /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(ResizeHandle, {}) : null
4370
+ open ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(ResizeHandle, {}) : null
3782
4371
  ] })
3783
4372
  ] });
3784
4373
  });
3785
4374
 
3786
4375
  // src/Layout/components/use-resize-layouts.tsx
3787
- var import_react25 = require("react");
4376
+ var import_react28 = require("react");
3788
4377
 
3789
4378
  // ../ui/madoc/use-event-handler.ts
3790
- var import_react24 = require("react");
4379
+ var import_react27 = require("react");
3791
4380
  function useEventHandler(ref, name, callback, deps = []) {
3792
- (0, import_react24.useLayoutEffect)(() => {
4381
+ (0, import_react27.useLayoutEffect)(() => {
3793
4382
  const current = ref.current;
3794
4383
  if (current) {
3795
4384
  current.addEventListener(name, callback);
@@ -3814,15 +4403,15 @@ function getMaxWidthPct(container, defaultMaxWidthPct, maxWidthPct, maxWidthPixe
3814
4403
  return defaultMaxWidthPct;
3815
4404
  }
3816
4405
  function useResizeLayout(name, options = {}) {
3817
- const container = (0, import_react25.useRef)(null);
3818
- const resizableDiv = (0, import_react25.useRef)(null);
3819
- const otherDiv = (0, import_react25.useRef)(null);
3820
- const resizer = (0, import_react25.useRef)(null);
3821
- const newPct = (0, import_react25.useRef)(0.5);
3822
- const [isDragging, setIsDragging] = (0, import_react25.useState)(false);
3823
- const isEventDragging = (0, import_react25.useRef)(false);
3824
- const isEventTimeout = (0, import_react25.useRef)(0);
3825
- const startPos = (0, import_react25.useRef)({ x: 0, y: 0 });
4406
+ const container = (0, import_react28.useRef)(null);
4407
+ const resizableDiv = (0, import_react28.useRef)(null);
4408
+ const otherDiv = (0, import_react28.useRef)(null);
4409
+ const resizer = (0, import_react28.useRef)(null);
4410
+ const newPct = (0, import_react28.useRef)(0.5);
4411
+ const [isDragging, setIsDragging] = (0, import_react28.useState)(false);
4412
+ const isEventDragging = (0, import_react28.useRef)(false);
4413
+ const isEventTimeout = (0, import_react28.useRef)(0);
4414
+ const startPos = (0, import_react28.useRef)({ x: 0, y: 0 });
3826
4415
  const [{ widthA, widthB }, setWidths] = useLocalStorage(`resize-layout/${name}`, {
3827
4416
  widthA: "auto",
3828
4417
  widthB: `${panelSizing({
@@ -3927,39 +4516,34 @@ function useResizeLayout(name, options = {}) {
3927
4516
  };
3928
4517
  }
3929
4518
 
3930
- // src/hooks/use-match-media.ts
3931
- var import_react26 = require("react");
3932
- function useMatchMedia(queries, defaultValues = []) {
3933
- const initialValues = defaultValues.length ? defaultValues : Array(queries.length).fill(false);
3934
- if (typeof window === "undefined")
3935
- return initialValues;
3936
- const mediaQueryLists = queries.map((q) => window.matchMedia(q));
3937
- const getValue2 = () => {
3938
- const matchedQueries = mediaQueryLists.map((mql) => mql.matches);
3939
- return matchedQueries;
3940
- };
3941
- const [value, setValue] = (0, import_react26.useState)(getValue2);
3942
- (0, import_react26.useLayoutEffect)(() => {
3943
- const handler = () => setValue(getValue2);
3944
- mediaQueryLists.forEach((mql) => mql.addListener(handler));
3945
- return () => mediaQueryLists.forEach((mql) => mql.removeListener(handler));
3946
- }, []);
3947
- return value;
3948
- }
3949
-
3950
4519
  // src/Layout/Layout.tsx
3951
- var import_components6 = require("@manifest-editor/components");
3952
- var import_jsx_runtime30 = require("react/jsx-runtime");
3953
- var Layout = (0, import_react27.memo)(function Layout2(props) {
4520
+ var import_jsx_runtime32 = require("react/jsx-runtime");
4521
+ var Layout = (0, import_react29.memo)(function Layout2(props) {
3954
4522
  const appState = useAppState();
3955
4523
  const layout = useLayoutProvider();
3956
- const { vault: _vault } = (0, import_react27.useContext)(import_react_iiif_vault11.ReactVaultContext);
4524
+ const { vault: _vault } = (0, import_react29.useContext)(import_react_iiif_vault11.ReactVaultContext);
3957
4525
  const vault = _vault || void 0;
3958
- const { loading, state, leftPanels, centerPanels, rightPanels, modals = [], actions } = layout;
3959
- const leftPanel = leftPanels.find((panel) => panel.id === state.leftPanel.current);
3960
- const rightPanel = rightPanels.find((panel) => panel.id === state.rightPanel.current);
3961
- const centerPanel = centerPanels.find((panel) => panel.id === state.centerPanel.current);
3962
- const modalToRender = modals.find((panel) => panel.id === state.modal.current);
4526
+ const {
4527
+ loading,
4528
+ state,
4529
+ leftPanels,
4530
+ centerPanels,
4531
+ rightPanels,
4532
+ modals = [],
4533
+ actions
4534
+ } = layout;
4535
+ const leftPanel = leftPanels.find(
4536
+ (panel) => panel.id === state.leftPanel.current
4537
+ );
4538
+ const rightPanel = rightPanels.find(
4539
+ (panel) => panel.id === state.rightPanel.current
4540
+ );
4541
+ const centerPanel = centerPanels.find(
4542
+ (panel) => panel.id === state.centerPanel.current
4543
+ );
4544
+ const modalToRender = modals.find(
4545
+ (panel) => panel.id === state.modal.current
4546
+ );
3963
4547
  const enableMotion = true;
3964
4548
  const pinnedRightPanel = state.pinnedRightPanel.pinned ? rightPanels.find((panel) => panel.id === state.pinnedRightPanel.current) : void 0;
3965
4549
  const [mobile] = useMatchMedia(["(max-width: 1020px)"]);
@@ -3991,13 +4575,13 @@ var Layout = (0, import_react27.memo)(function Layout2(props) {
3991
4575
  fallback: 320
3992
4576
  })
3993
4577
  }) : void 0;
3994
- (0, import_react27.useLayoutEffect)(() => {
4578
+ (0, import_react29.useLayoutEffect)(() => {
3995
4579
  if (mobile && state.leftPanel.open && state.rightPanel.open) {
3996
4580
  actions.leftPanel.close();
3997
4581
  actions.rightPanel.close();
3998
4582
  }
3999
4583
  }, [mobile]);
4000
- (0, import_react27.useLayoutEffect)(() => {
4584
+ (0, import_react29.useLayoutEffect)(() => {
4001
4585
  if (centerPanel && centerPanel.onMount) {
4002
4586
  return centerPanel.onMount(
4003
4587
  state.centerPanel.state || centerPanel.defaultState || {},
@@ -4006,7 +4590,7 @@ var Layout = (0, import_react27.memo)(function Layout2(props) {
4006
4590
  );
4007
4591
  }
4008
4592
  }, [state.centerPanel.current]);
4009
- (0, import_react27.useLayoutEffect)(() => {
4593
+ (0, import_react29.useLayoutEffect)(() => {
4010
4594
  rightPanels.length && actions.rightPanel.change({ id: rightPanels[0].id });
4011
4595
  leftPanels.length && actions.leftPanel.change({ id: leftPanels[0].id });
4012
4596
  centerPanels.length && actions.centerPanel.change({ id: centerPanels[0].id });
@@ -4014,7 +4598,7 @@ var Layout = (0, import_react27.memo)(function Layout2(props) {
4014
4598
  if (loading) {
4015
4599
  return null;
4016
4600
  }
4017
- const renderLeftPanel = (transition) => /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
4601
+ const renderLeftPanel = (transition) => /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
4018
4602
  PanelContainer,
4019
4603
  {
4020
4604
  $menu: props.leftPanelMenuPosition || "bottom",
@@ -4024,8 +4608,8 @@ var Layout = (0, import_react27.memo)(function Layout2(props) {
4024
4608
  width: state.leftPanel.open || transition !== "exited" ? leftPanelResizer.widthB : void 0,
4025
4609
  minWidth: leftPanel?.options?.minWidth
4026
4610
  },
4027
- children: isLoading ? /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(PanelContent, { children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(GhostBlocks, {}) }) : /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(import_jsx_runtime30.Fragment, { children: [
4028
- props.leftPanelMenu ? /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
4611
+ children: isLoading ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(PanelContent, { children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(GhostBlocks, {}) }) : /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(import_jsx_runtime32.Fragment, { children: [
4612
+ props.leftPanelMenu ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
4029
4613
  PanelMenu,
4030
4614
  {
4031
4615
  $open: state.leftPanel.open && transition !== "exited",
@@ -4033,7 +4617,7 @@ var Layout = (0, import_react27.memo)(function Layout2(props) {
4033
4617
  children: props.leftPanelMenu
4034
4618
  }
4035
4619
  ) : null,
4036
- /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(PanelContent, { children: state.leftPanel.open || transition !== "exited" ? /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_jsx_runtime30.Fragment, { children: leftPanel ? /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
4620
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(PanelContent, { children: state.leftPanel.open || transition !== "exited" ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_jsx_runtime32.Fragment, { children: leftPanel ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
4037
4621
  ModularPanel,
4038
4622
  {
4039
4623
  isLeft: true,
@@ -4051,7 +4635,7 @@ var Layout = (0, import_react27.memo)(function Layout2(props) {
4051
4635
  if (!modalToRender || state.modal.open === false) {
4052
4636
  return null;
4053
4637
  }
4054
- return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_components6.Modal, { title: modalToRender.label, onClose: () => actions.modal.close(), children: renderHelper(
4638
+ return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_components7.Modal, { title: modalToRender.label, onClose: () => actions.modal.close(), children: renderHelper(
4055
4639
  modalToRender.render(
4056
4640
  state.modal.state || modalToRender.defaultState || {},
4057
4641
  { ...layout, current: actions.modal, vault },
@@ -4059,9 +4643,27 @@ var Layout = (0, import_react27.memo)(function Layout2(props) {
4059
4643
  )
4060
4644
  ) });
4061
4645
  };
4062
- const renderCenterPanel = () => /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(PanelContainer, { $menu: props.centerPanelMenuPosition || "top", children: [
4063
- props.centerPanelMenu ? /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(PanelMenu, { $open: state.centerPanel.open, $position: props.centerPanelMenuPosition || "top", children: props.centerPanelMenu }) : null,
4064
- /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(PanelContent, { children: isLoading ? /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { style: { display: "flex", flex: 1, justifyContent: "center", alignItems: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(Spinner, { stroke: "rgba(0,0,0,.3)", fontSize: "2em" }) }) : state.centerPanel.open ? centerPanel ? renderHelper(
4646
+ const renderCenterPanel = () => /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(PanelContainer, { $menu: props.centerPanelMenuPosition || "top", children: [
4647
+ props.centerPanelMenu ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
4648
+ PanelMenu,
4649
+ {
4650
+ $open: state.centerPanel.open,
4651
+ $position: props.centerPanelMenuPosition || "top",
4652
+ children: props.centerPanelMenu
4653
+ }
4654
+ ) : null,
4655
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(PanelContent, { children: isLoading ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
4656
+ "div",
4657
+ {
4658
+ style: {
4659
+ display: "flex",
4660
+ flex: 1,
4661
+ justifyContent: "center",
4662
+ alignItems: "center"
4663
+ },
4664
+ children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(Spinner, { stroke: "rgba(0,0,0,.3)", fontSize: "2em" })
4665
+ }
4666
+ ) : state.centerPanel.open ? centerPanel ? renderHelper(
4065
4667
  centerPanel.render(
4066
4668
  state.centerPanel.state || centerPanel.defaultState || {},
4067
4669
  { ...layout, current: actions.centerPanel, vault },
@@ -4069,7 +4671,7 @@ var Layout = (0, import_react27.memo)(function Layout2(props) {
4069
4671
  )
4070
4672
  ) : null : null })
4071
4673
  ] });
4072
- const renderRightPanel = (transition) => /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
4674
+ const renderRightPanel = (transition) => /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
4073
4675
  PanelContainer,
4074
4676
  {
4075
4677
  $menu: props.rightPanelMenuPosition || "bottom",
@@ -4079,10 +4681,17 @@ var Layout = (0, import_react27.memo)(function Layout2(props) {
4079
4681
  width: state.rightPanel.open || transition !== "exited" ? rightPanelResizer.widthB : void 0,
4080
4682
  minWidth: rightPanel?.options?.minWidth
4081
4683
  },
4082
- children: isLoading ? /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(PanelContent, { children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(GhostBlocks, {}) }) : /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(import_jsx_runtime30.Fragment, { children: [
4083
- props.rightPanelMenu ? /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(PanelMenu, { $open: state.rightPanel.open, $position: props.rightPanelMenuPosition || "bottom", children: props.rightPanelMenu }) : null,
4084
- /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(PanelContent, { children: state.rightPanel.open || transition !== "exited" ? /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(import_jsx_runtime30.Fragment, { children: [
4085
- showRightPanel ? /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
4684
+ children: isLoading ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(PanelContent, { children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(GhostBlocks, {}) }) : /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(import_jsx_runtime32.Fragment, { children: [
4685
+ props.rightPanelMenu ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
4686
+ PanelMenu,
4687
+ {
4688
+ $open: state.rightPanel.open,
4689
+ $position: props.rightPanelMenuPosition || "bottom",
4690
+ children: props.rightPanelMenu
4691
+ }
4692
+ ) : null,
4693
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(PanelContent, { children: state.rightPanel.open || transition !== "exited" ? /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(import_jsx_runtime32.Fragment, { children: [
4694
+ showRightPanel ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
4086
4695
  ModularPanel,
4087
4696
  {
4088
4697
  panel: rightPanel,
@@ -4092,7 +4701,7 @@ var Layout = (0, import_react27.memo)(function Layout2(props) {
4092
4701
  available: rightPanels
4093
4702
  }
4094
4703
  ) : null,
4095
- pinnedRightPanel ? /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
4704
+ pinnedRightPanel ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
4096
4705
  ModularPanel,
4097
4706
  {
4098
4707
  panel: pinnedRightPanel,
@@ -4106,24 +4715,24 @@ var Layout = (0, import_react27.memo)(function Layout2(props) {
4106
4715
  }
4107
4716
  );
4108
4717
  if (mobile) {
4109
- return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(OuterWrapper, { children: [
4110
- props.hideHeader ? null : /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(Header2, { children: [
4718
+ return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(OuterWrapper, { children: [
4719
+ props.hideHeader ? null : /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(Header2, { children: [
4111
4720
  props.header || null,
4112
- props.menu ? /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("menu", { children: props.menu }) : null
4721
+ props.menu ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("menu", { children: props.menu }) : null
4113
4722
  ] }),
4114
- /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(Main, { children: /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(Container2, { children: [
4115
- /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(CenterPanel, { children: renderCenterPanel() }),
4116
- /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(MobileBar, { children: [
4117
- leftPanels.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(LeftBarButton, { onClick: actions.leftPanel.toggle, children: leftPanel?.label }) : null,
4118
- rightPanels.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(DrawerContainer, { children: /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(DrawerButton, { onClick: actions.rightPanel.toggle, children: [
4119
- /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(DownIcon, { rotate: 180 }),
4723
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(Main, { children: /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(Container2, { children: [
4724
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(CenterPanel, { children: renderCenterPanel() }),
4725
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(MobileBar, { children: [
4726
+ leftPanels.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(LeftBarButton, { onClick: actions.leftPanel.toggle, children: leftPanel?.label }) : null,
4727
+ rightPanels.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(DrawerContainer, { children: /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(DrawerButton, { onClick: actions.rightPanel.toggle, children: [
4728
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(DownIcon, { rotate: 180 }),
4120
4729
  rightPanel?.label
4121
4730
  ] }) }) : null,
4122
- /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(PreviewBarButton, { children: "Preview" })
4731
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(PreviewBarButton, { children: "Preview" })
4123
4732
  ] }),
4124
- rightPanels.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(DrawerBody, { $open: state.rightPanel.open, children: renderRightPanel() }) : null,
4125
- leftPanels.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(LeftPanel, { $open: state.leftPanel.open, children: renderLeftPanel() }) : null,
4126
- leftPanels.length > 0 || rightPanels.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
4733
+ rightPanels.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(DrawerBody, { $open: state.rightPanel.open, children: renderRightPanel() }) : null,
4734
+ leftPanels.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(LeftPanel, { $open: state.leftPanel.open, children: renderLeftPanel() }) : null,
4735
+ leftPanels.length > 0 || rightPanels.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
4127
4736
  Lightbox,
4128
4737
  {
4129
4738
  $open: state.leftPanel.open || state.rightPanel.open,
@@ -4136,12 +4745,12 @@ var Layout = (0, import_react27.memo)(function Layout2(props) {
4136
4745
  ] }) })
4137
4746
  ] });
4138
4747
  }
4139
- return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(OuterWrapper, { className: `manifest-editor ${props.className}`, children: [
4140
- props.hideHeader ? null : /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(Header2, { children: [
4748
+ return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(OuterWrapper, { className: `manifest-editor ${props.className}`, children: [
4749
+ props.hideHeader ? null : /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(Header2, { children: [
4141
4750
  props.header || null,
4142
- props.menu ? /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("menu", { children: props.menu }) : null
4751
+ props.menu ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("menu", { children: props.menu }) : null
4143
4752
  ] }),
4144
- /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
4753
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
4145
4754
  Main,
4146
4755
  {
4147
4756
  ref: (div) => {
@@ -4149,8 +4758,8 @@ var Layout = (0, import_react27.memo)(function Layout2(props) {
4149
4758
  rightPanelResizer.refs.container.current = div;
4150
4759
  },
4151
4760
  children: [
4152
- leftPanels.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
4153
- import_components6.PanelSideMenu,
4761
+ leftPanels.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
4762
+ import_components7.PanelSideMenu,
4154
4763
  {
4155
4764
  current: state.leftPanel.current,
4156
4765
  items: leftPanels.map((panel) => ({
@@ -4169,44 +4778,76 @@ var Layout = (0, import_react27.memo)(function Layout2(props) {
4169
4778
  open: state.leftPanel.open
4170
4779
  }
4171
4780
  ) : null,
4172
- leftPanels.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_react_transition_group.Transition, { in: state.leftPanel.open, timeout: enableMotion ? 400 : 0, unmountOnExit: false, children: (transition) => /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(import_jsx_runtime30.Fragment, { children: [
4173
- /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(LeftPanel2, { $width: leftPanelResizer.widthB, $state: transition, $motion: enableMotion, children: renderLeftPanel(transition) }),
4174
- /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
4175
- HandleControls,
4176
- {
4177
- ref: leftPanelResizer.refs.resizer,
4178
- reset: resetLeftPanel,
4179
- dir: "left",
4180
- transition,
4181
- open: state.leftPanel.open || transition !== "exited",
4182
- actions: actions.leftPanel
4183
- }
4184
- )
4185
- ] }) }) : null,
4186
- /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(CenterPanel2, { children: renderCenterPanel() }),
4187
- rightPanels.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_react_transition_group.Transition, { in: state.rightPanel.open, timeout: enableMotion ? 400 : 0, unmountOnExit: false, children: (transition) => /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(import_jsx_runtime30.Fragment, { children: [
4188
- /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
4189
- HandleControls,
4190
- {
4191
- ref: rightPanelResizer.refs.resizer,
4192
- dir: "right",
4193
- reset: resetRightPanel,
4194
- open: state.rightPanel.open,
4195
- actions: actions.rightPanel
4196
- }
4197
- ),
4198
- /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(RightPanel, { $width: rightPanelResizer.widthB, $state: transition, $motion: enableMotion, children: renderRightPanel(transition) })
4199
- ] }) }) : null
4781
+ leftPanels.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
4782
+ import_react_transition_group.Transition,
4783
+ {
4784
+ in: state.leftPanel.open,
4785
+ timeout: enableMotion ? 400 : 0,
4786
+ unmountOnExit: false,
4787
+ children: (transition) => /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(import_jsx_runtime32.Fragment, { children: [
4788
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
4789
+ LeftPanel2,
4790
+ {
4791
+ $width: leftPanelResizer.widthB,
4792
+ $state: transition,
4793
+ $motion: enableMotion,
4794
+ children: renderLeftPanel(transition)
4795
+ }
4796
+ ),
4797
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
4798
+ HandleControls,
4799
+ {
4800
+ ref: leftPanelResizer.refs.resizer,
4801
+ reset: resetLeftPanel,
4802
+ dir: "left",
4803
+ transition,
4804
+ open: state.leftPanel.open || transition !== "exited",
4805
+ actions: actions.leftPanel
4806
+ }
4807
+ )
4808
+ ] })
4809
+ }
4810
+ ) : null,
4811
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(CenterPanel2, { children: renderCenterPanel() }),
4812
+ rightPanels.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
4813
+ import_react_transition_group.Transition,
4814
+ {
4815
+ in: state.rightPanel.open,
4816
+ timeout: enableMotion ? 400 : 0,
4817
+ unmountOnExit: false,
4818
+ children: (transition) => /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(import_jsx_runtime32.Fragment, { children: [
4819
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
4820
+ HandleControls,
4821
+ {
4822
+ ref: rightPanelResizer.refs.resizer,
4823
+ dir: "right",
4824
+ reset: resetRightPanel,
4825
+ open: state.rightPanel.open,
4826
+ actions: actions.rightPanel
4827
+ }
4828
+ ),
4829
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
4830
+ RightPanel,
4831
+ {
4832
+ $width: rightPanelResizer.widthB,
4833
+ $state: transition,
4834
+ $motion: enableMotion,
4835
+ children: renderRightPanel(transition)
4836
+ }
4837
+ )
4838
+ ] })
4839
+ }
4840
+ ) : null
4200
4841
  ]
4201
4842
  }
4202
4843
  ),
4203
- /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(Footer, { children: props.footer || null }),
4204
- /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_jsx_runtime30.Fragment, { children: renderModal() })
4844
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(Footer, { children: props.footer || null }),
4845
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_jsx_runtime32.Fragment, { children: renderModal() })
4205
4846
  ] });
4206
4847
  });
4207
4848
 
4208
4849
  // src/Layout/Layout.hooks.ts
4209
- var import_react28 = require("react");
4850
+ var import_react30 = require("react");
4210
4851
  function usePanelActions(panel, dispatch) {
4211
4852
  function popStack() {
4212
4853
  dispatch({ type: "popStack", panel, payload: void 0 });
@@ -4241,7 +4882,7 @@ function usePanelActions(panel, dispatch) {
4241
4882
  function unpin() {
4242
4883
  dispatch({ type: "unpin", panel, payload: void 0 });
4243
4884
  }
4244
- return (0, import_react28.useMemo)(
4885
+ return (0, import_react30.useMemo)(
4245
4886
  () => ({
4246
4887
  popStack,
4247
4888
  change,
@@ -4407,14 +5048,14 @@ function getDefaultLayoutState() {
4407
5048
  }
4408
5049
 
4409
5050
  // src/ResourceEditingContext/ResourceEditingContext.tsx
4410
- var import_react29 = require("react");
5051
+ var import_react31 = require("react");
4411
5052
  var import_react_iiif_vault12 = require("react-iiif-vault");
4412
- var import_jsx_runtime31 = require("react/jsx-runtime");
4413
- var ResourceEditingReactContext = (0, import_react29.createContext)({
5053
+ var import_jsx_runtime33 = require("react/jsx-runtime");
5054
+ var ResourceEditingReactContext = (0, import_react31.createContext)({
4414
5055
  resource: null
4415
5056
  });
4416
5057
  function useEditingContext() {
4417
- return (0, import_react29.useContext)(ResourceEditingReactContext);
5058
+ return (0, import_react31.useContext)(ResourceEditingReactContext);
4418
5059
  }
4419
5060
  function useResource() {
4420
5061
  const vault = (0, import_react_iiif_vault12.useVault)();
@@ -4435,10 +5076,10 @@ function ResourceEditingProvider({
4435
5076
  children
4436
5077
  }) {
4437
5078
  const { id, type } = resource || {};
4438
- return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
5079
+ return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
4439
5080
  ResourceEditingReactContext.Provider,
4440
5081
  {
4441
- value: (0, import_react29.useMemo)(
5082
+ value: (0, import_react31.useMemo)(
4442
5083
  () => ({
4443
5084
  // Current resource.
4444
5085
  resource: id && type ? { id, type } : null
@@ -4450,10 +5091,13 @@ function ResourceEditingProvider({
4450
5091
  );
4451
5092
  }
4452
5093
 
5094
+ // src/ShellContext/ShellContext.tsx
5095
+ var import_iiif_image_api = require("@atlas-viewer/iiif-image-api");
5096
+
4453
5097
  // ../ui/atoms/ErrorBoundary.tsx
4454
- var import_react30 = require("react");
4455
- var import_jsx_runtime32 = require("react/jsx-runtime");
4456
- var ErrorBoundary2 = class extends import_react30.Component {
5098
+ var import_react32 = require("react");
5099
+ var import_jsx_runtime34 = require("react/jsx-runtime");
5100
+ var ErrorBoundary2 = class extends import_react32.Component {
4457
5101
  constructor() {
4458
5102
  super(...arguments);
4459
5103
  __publicField(this, "state", {
@@ -4469,34 +5113,43 @@ var ErrorBoundary2 = class extends import_react30.Component {
4469
5113
  }
4470
5114
  render() {
4471
5115
  if (this.state.hasError) {
4472
- return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("h1", { children: "Sorry.. there was an error" });
5116
+ return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("h1", { children: "Sorry.. there was an error" });
4473
5117
  }
4474
5118
  return this.props.children;
4475
5119
  }
4476
5120
  };
4477
5121
 
4478
5122
  // src/ShellContext/ShellContext.tsx
4479
- var import_styled_components14 = require("styled-components");
5123
+ var import_react34 = require("react");
5124
+ var import_react_iiif_vault13 = require("react-iiif-vault");
5125
+ var import_styled_components12 = require("styled-components");
4480
5126
 
4481
5127
  // src/Layout/Layout.context-internal.tsx
4482
5128
  var import_parser6 = require("@iiif/parser");
4483
- var import_react31 = require("react");
4484
- var import_jsx_runtime33 = require("react/jsx-runtime");
5129
+ var import_react33 = require("react");
5130
+ var import_jsx_runtime35 = require("react/jsx-runtime");
4485
5131
  function parse(args, _state) {
4486
5132
  if (typeof args === "string") {
4487
5133
  return { id: args, state: _state };
4488
5134
  }
4489
5135
  return args;
4490
5136
  }
4491
- var LayoutProvider = (0, import_react31.memo)(function LayoutProvider2(props) {
5137
+ var LayoutProvider = (0, import_react33.memo)(function LayoutProvider2(props) {
4492
5138
  const app = useApp();
4493
5139
  const available = app.layout;
4494
- const [state, dispatch] = (0, import_react31.useReducer)(layoutReducer, void 0, getDefaultLayoutState);
5140
+ const [state, dispatch] = (0, import_react33.useReducer)(
5141
+ layoutReducer,
5142
+ void 0,
5143
+ getDefaultLayoutState
5144
+ );
4495
5145
  const actions = {
4496
5146
  centerPanel: usePanelActions("centerPanel", dispatch),
4497
5147
  leftPanel: usePanelActions("leftPanel", dispatch),
4498
5148
  rightPanel: usePanelActions("rightPanel", dispatch),
4499
- pinnedRightPanel: usePanelActions("pinnedRightPanel", dispatch),
5149
+ pinnedRightPanel: usePanelActions(
5150
+ "pinnedRightPanel",
5151
+ dispatch
5152
+ ),
4500
5153
  modal: usePanelActions("modal", dispatch),
4501
5154
  editingStack: useEditingStack()
4502
5155
  };
@@ -4519,7 +5172,10 @@ var LayoutProvider = (0, import_react31.memo)(function LayoutProvider2(props) {
4519
5172
  const { id, state: state2, stacked } = parse(args, _state);
4520
5173
  const [found, actions2, pinnable] = find(id);
4521
5174
  if (pinnable && found.options?.openPinned) {
4522
- pinnable.pin({ id, state: { ...found.defaultState || {}, ...state2 || {} } });
5175
+ pinnable.pin({
5176
+ id,
5177
+ state: { ...found.defaultState || {}, ...state2 || {} }
5178
+ });
4523
5179
  } else {
4524
5180
  actions2.open({
4525
5181
  id,
@@ -4556,7 +5212,11 @@ var LayoutProvider = (0, import_react31.memo)(function LayoutProvider2(props) {
4556
5212
  const [, actions2] = find(id);
4557
5213
  actions2.toggle();
4558
5214
  }
4559
- function edit(resource, context = {}, { reset, property, stacked } = {}) {
5215
+ function edit(resource, context = {}, {
5216
+ reset,
5217
+ property,
5218
+ stacked
5219
+ } = {}) {
4560
5220
  const toEdit = {
4561
5221
  resource: (0, import_parser6.isSpecificResource)(resource) ? resource : {
4562
5222
  type: "SpecificResource",
@@ -4576,7 +5236,7 @@ var LayoutProvider = (0, import_react31.memo)(function LayoutProvider2(props) {
4576
5236
  }
4577
5237
  function create2(resource) {
4578
5238
  actions.editingStack.create(resource, {});
4579
- if (available.modals && available.modals.find((e) => e.id === "@manifest-editor/creator")) {
5239
+ if (available.modals?.find((e) => e.id === "@manifest-editor/creator")) {
4580
5240
  actions.modal.open({
4581
5241
  id: "@manifest-editor/creator",
4582
5242
  stacked: true,
@@ -4601,7 +5261,13 @@ var LayoutProvider = (0, import_react31.memo)(function LayoutProvider2(props) {
4601
5261
  edit,
4602
5262
  create: create2
4603
5263
  };
4604
- return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(LayoutActionsReactContext.Provider, { value: (0, import_react31.useMemo)(() => ({ ...actions, ...otherActions }), [available]), children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(LayoutStateReactContext.Provider, { value: state, children: props.children }) });
5264
+ return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
5265
+ LayoutActionsReactContext.Provider,
5266
+ {
5267
+ value: (0, import_react33.useMemo)(() => ({ ...actions, ...otherActions }), [available]),
5268
+ children: /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(LayoutStateReactContext.Provider, { value: state, children: props.children })
5269
+ }
5270
+ );
4605
5271
  });
4606
5272
 
4607
5273
  // src/ShellContext/default-theme.ts
@@ -4650,13 +5316,11 @@ var defaultTheme = {
4650
5316
  };
4651
5317
 
4652
5318
  // src/ShellContext/ShellContext.tsx
4653
- var import_react_iiif_vault13 = require("react-iiif-vault");
4654
- var import_iiif_image_api = require("@atlas-viewer/iiif-image-api");
4655
- var import_jsx_runtime34 = require("react/jsx-runtime");
5319
+ var import_jsx_runtime36 = require("react/jsx-runtime");
4656
5320
  var previewConfigs = [
4657
5321
  {
4658
5322
  id: "universal-viewer",
4659
- config: { url: "https://uv-v4.netlify.app/#?iiifManifestId={manifestId}" },
5323
+ config: { url: "https://universalviewer.dev/#?iiifManifestId={manifestId}" },
4660
5324
  type: "external-manifest-preview",
4661
5325
  label: "Universal viewer"
4662
5326
  },
@@ -4697,17 +5361,32 @@ function ShellProvider({
4697
5361
  resource,
4698
5362
  editing
4699
5363
  }) {
4700
- return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(ErrorBoundary2, { children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_react_iiif_vault13.ImageServiceLoaderContext.Provider, { value: imageServiceLoader, children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(AppResourceProvider, { resource, children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(PreviewVaultContext, { children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_styled_components14.ThemeProvider, { theme: theme || defaultTheme, children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(ConfigProvider, { config, saveConfig, children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(EditingStack, { children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(LayoutProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(PreviewProvider, { previews: previews || [], configs: config?.previews || previewConfigs, children }) }) }) }) }) }) }) }) });
5364
+ const existingConfig = useConfig();
5365
+ const mergedConfig = (0, import_react34.useMemo)(() => {
5366
+ return {
5367
+ ...existingConfig,
5368
+ ...config,
5369
+ previews: config?.previews || existingConfig.previews || previewConfigs
5370
+ };
5371
+ }, [existingConfig, config]);
5372
+ return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(ErrorBoundary2, { children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_react_iiif_vault13.ImageServiceLoaderContext.Provider, { value: imageServiceLoader, children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(AppResourceProvider, { resource, children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(PreviewVaultContext, { children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_styled_components12.ThemeProvider, { theme: theme || defaultTheme, children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(ConfigProvider, { config: mergedConfig, saveConfig, children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(EditingStack, { children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(LayoutProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
5373
+ PreviewProvider,
5374
+ {
5375
+ previews: previews || [],
5376
+ configs: mergedConfig.previews,
5377
+ children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(AtlasStoreProvider, { children })
5378
+ }
5379
+ ) }) }) }) }) }) }) }) });
4701
5380
  }
4702
5381
 
4703
5382
  // src/TaskBridge/TaskBridge.tsx
4704
- var import_mitt2 = __toESM(require("mitt"), 1);
4705
- var import_react32 = require("react");
4706
- var import_jsx_runtime35 = require("react/jsx-runtime");
5383
+ var import_mitt3 = __toESM(require("mitt"), 1);
5384
+ var import_react35 = require("react");
5385
+ var import_jsx_runtime37 = require("react/jsx-runtime");
4707
5386
  var tempGlobalState = {};
4708
- var DispatchReactContext = (0, import_react32.createContext)("global");
5387
+ var DispatchReactContext = (0, import_react35.createContext)("global");
4709
5388
  function useCurrentDispatchId() {
4710
- return (0, import_react32.useContext)(DispatchReactContext);
5389
+ return (0, import_react35.useContext)(DispatchReactContext);
4711
5390
  }
4712
5391
  function createDeferred() {
4713
5392
  let res = void 0;
@@ -4720,15 +5399,15 @@ function createDeferred() {
4720
5399
  }
4721
5400
  function useTask(name) {
4722
5401
  const id = useCurrentDispatchId();
4723
- const [, invalidate] = (0, import_react32.useReducer)((r) => r + 1, 0);
4724
- const task = (0, import_react32.useMemo)(() => {
5402
+ const [, invalidate] = (0, import_react35.useReducer)((r) => r + 1, 0);
5403
+ const task = (0, import_react35.useMemo)(() => {
4725
5404
  if (!tempGlobalState[id]) {
4726
5405
  tempGlobalState[id] = {};
4727
5406
  }
4728
5407
  if (!tempGlobalState[id][name]) {
4729
5408
  tempGlobalState[id][name] = {
4730
5409
  name,
4731
- emitter: (0, import_mitt2.default)(),
5410
+ emitter: (0, import_mitt3.default)(),
4732
5411
  status: "idle",
4733
5412
  promise: Promise.resolve(),
4734
5413
  abort: new AbortController(),
@@ -4745,8 +5424,8 @@ function useTask(name) {
4745
5424
  return task;
4746
5425
  }
4747
5426
  function useTaskEvent(task, name, _cb) {
4748
- const cb = (0, import_react32.useCallback)(() => _cb(task), [_cb]);
4749
- (0, import_react32.useEffect)(() => {
5427
+ const cb = (0, import_react35.useCallback)(() => _cb(task), [_cb]);
5428
+ (0, import_react35.useEffect)(() => {
4750
5429
  const em = task.emitter;
4751
5430
  em.on(name, cb);
4752
5431
  return () => em.off(name, cb);
@@ -4795,12 +5474,12 @@ function useTaskRunner(name, onRun) {
4795
5474
  return [completeTask, taskDetails, rejectTask];
4796
5475
  }
4797
5476
  function TaskBridge({ children }) {
4798
- return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(DispatchReactContext.Provider, { value: (0, import_react32.useMemo)(() => `id-${Date.now()}`, []), children });
5477
+ return /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(DispatchReactContext.Provider, { value: (0, import_react35.useMemo)(() => `id-${Date.now()}`, []), children });
4799
5478
  }
4800
5479
 
4801
5480
  // src/Universal/UniversalCopyPaste.tsx
4802
- var import_react33 = require("react");
4803
- var import_jsx_runtime36 = require("react/jsx-runtime");
5481
+ var import_react36 = require("react");
5482
+ var import_jsx_runtime38 = require("react/jsx-runtime");
4804
5483
  function analyse(t) {
4805
5484
  return false;
4806
5485
  }
@@ -4825,10 +5504,10 @@ function UniversalCopyTarget({
4825
5504
  const onPasteReference = _onPasteReference || onReference;
4826
5505
  const onPasteLink = _onPasteLink || onLink;
4827
5506
  const onPasteAnalysis = _onPasteAnalysis || onAnalysis;
4828
- const reference = (0, import_react33.useMemo)(() => {
5507
+ const reference = (0, import_react36.useMemo)(() => {
4829
5508
  return _ref;
4830
5509
  }, [_ref?.id, _ref?.type]);
4831
- const onCopy = (0, import_react33.useCallback)(
5510
+ const onCopy = (0, import_react36.useCallback)(
4832
5511
  function onCopy2(e) {
4833
5512
  if (e.defaultPrevented) {
4834
5513
  return;
@@ -4848,7 +5527,7 @@ function UniversalCopyTarget({
4848
5527
  },
4849
5528
  [reference]
4850
5529
  );
4851
- const onPaste = (0, import_react33.useCallback)(async function onPaste2(e) {
5530
+ const onPaste = (0, import_react36.useCallback)(async function onPaste2(e) {
4852
5531
  if (e.defaultPrevented) {
4853
5532
  return;
4854
5533
  }
@@ -4895,7 +5574,7 @@ function UniversalCopyTarget({
4895
5574
  }
4896
5575
  }
4897
5576
  }, []);
4898
- const onDragStart = (0, import_react33.useCallback)(function onPaste2(e) {
5577
+ const onDragStart = (0, import_react36.useCallback)(function onPaste2(e) {
4899
5578
  if (e.defaultPrevented) {
4900
5579
  return;
4901
5580
  }
@@ -4913,7 +5592,7 @@ function UniversalCopyTarget({
4913
5592
  }
4914
5593
  }
4915
5594
  }, []);
4916
- const onDrop = (0, import_react33.useCallback)(async function onDrop2(e) {
5595
+ const onDrop = (0, import_react36.useCallback)(async function onDrop2(e) {
4917
5596
  e.preventDefault();
4918
5597
  if (e.dataTransfer) {
4919
5598
  if (onDropReference) {
@@ -4940,13 +5619,13 @@ function UniversalCopyTarget({
4940
5619
  }
4941
5620
  }
4942
5621
  }, []);
4943
- const onDragOver = (0, import_react33.useCallback)((e) => {
5622
+ const onDragOver = (0, import_react36.useCallback)((e) => {
4944
5623
  e.preventDefault();
4945
5624
  if (e.dataTransfer) {
4946
5625
  e.dataTransfer.dropEffect = "copy";
4947
5626
  }
4948
5627
  }, []);
4949
- return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
5628
+ return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
4950
5629
  Component2,
4951
5630
  {
4952
5631
  onCopy,
@@ -5146,11 +5825,11 @@ async function getImageDimensions(url) {
5146
5825
  }
5147
5826
 
5148
5827
  // src/hooks/use-save-vault.ts
5149
- var import_react34 = require("react");
5828
+ var import_react37 = require("react");
5150
5829
  var import_tiny_use_debounce = require("tiny-use-debounce");
5151
5830
  function useSaveVault(vault, saveChanges, saveInterval, enabled = true) {
5152
5831
  const debounceSaveChanges = (0, import_tiny_use_debounce.useDebounce)(saveChanges, saveInterval);
5153
- (0, import_react34.useEffect)(() => {
5832
+ (0, import_react37.useEffect)(() => {
5154
5833
  if (typeof window === "undefined") {
5155
5834
  return () => void 0;
5156
5835
  }
@@ -5160,10 +5839,139 @@ function useSaveVault(vault, saveChanges, saveInterval, enabled = true) {
5160
5839
  window.removeEventListener("beforeunload", saveChanges);
5161
5840
  };
5162
5841
  }, [saveChanges]);
5163
- (0, import_react34.useEffect)(() => {
5842
+ (0, import_react37.useEffect)(() => {
5164
5843
  if (vault && enabled) {
5165
5844
  return vault.subscribe(debounceSaveChanges, true);
5166
5845
  }
5167
5846
  }, [debounceSaveChanges, vault, enabled]);
5168
5847
  }
5848
+
5849
+ // src/hooks/use-svg-tools.tsx
5850
+ var import_react38 = require("react");
5851
+ var import_zustand2 = require("zustand");
5852
+ function useSvgTools() {
5853
+ const store = useAtlasStore();
5854
+ const switchTool = (0, import_zustand2.useStore)(store, (s) => s.switchTool);
5855
+ const state = (0, import_zustand2.useStore)(store, (s) => s.polygons.state.slowState);
5856
+ return (0, import_react38.useMemo)(
5857
+ () => ({
5858
+ // Draw tool.
5859
+ draw: {
5860
+ active: !state.lineMode && !state.selectedStamp && state.drawMode,
5861
+ enable: switchTool.draw
5862
+ },
5863
+ // Polygon.
5864
+ polygon: {
5865
+ active: !state.lineMode && !state.selectedStamp && !state.drawMode,
5866
+ enable: switchTool.polygon
5867
+ },
5868
+ // Line
5869
+ line: {
5870
+ active: state.lineMode && !state.lineBoxMode,
5871
+ enable: switchTool.line
5872
+ },
5873
+ // Line box.
5874
+ lineBox: {
5875
+ active: state.lineBoxMode,
5876
+ enable: switchTool.lineBox
5877
+ },
5878
+ // Square.
5879
+ square: {
5880
+ active: state.selectedStamp?.id === "square",
5881
+ enable: switchTool.square
5882
+ },
5883
+ // Triangle.
5884
+ triangle: {
5885
+ active: state.selectedStamp?.id === "triangle",
5886
+ enable: switchTool.triangle
5887
+ },
5888
+ // Hexagon.
5889
+ hexagon: {
5890
+ active: state.selectedStamp?.id === "hexagon",
5891
+ enable: switchTool.hexagon
5892
+ },
5893
+ // Circle
5894
+ circle: {
5895
+ active: state.selectedStamp?.id === "circle40",
5896
+ enable: switchTool.circle
5897
+ },
5898
+ // Delete
5899
+ remove: {
5900
+ active: state.showBoundingBox,
5901
+ enable: switchTool.remove
5902
+ }
5903
+ }),
5904
+ [state, switchTool]
5905
+ );
5906
+ }
5907
+
5908
+ // src/hooks/use-request-annotation.ts
5909
+ var import_react39 = require("react");
5910
+ var import_zustand3 = require("zustand");
5911
+ function useRequestAnnotation(opts) {
5912
+ const [id, setId] = (0, import_react39.useState)(0);
5913
+ const store = useAtlasStore();
5914
+ const { tool, getRequestId, requestAnnotation, completeRequest, cancelRequest } = (0, import_zustand3.useStore)(store, (s) => ({
5915
+ getRequestId: s.getRequestId,
5916
+ requestAnnotation: s.requestAnnotation,
5917
+ completeRequest: s.completeRequest,
5918
+ cancelRequest: s.cancelRequest,
5919
+ tool: s.tool
5920
+ }));
5921
+ const [isPending, setIsPending] = (0, import_react39.useState)(false);
5922
+ const [data, setData] = (0, import_react39.useState)(null);
5923
+ const [requestId, setRequestId] = (0, import_react39.useState)(null);
5924
+ const busy = tool.enabled && tool.requestId !== requestId;
5925
+ const mutateAsync = (0, import_react39.useCallback)(
5926
+ async (request, options) => {
5927
+ if (requestId) {
5928
+ setIsPending(true);
5929
+ const response = await requestAnnotation(request, {
5930
+ ...options,
5931
+ requestId
5932
+ });
5933
+ if (response) {
5934
+ opts?.onSuccess?.(response);
5935
+ setId((i) => i + 1);
5936
+ setIsPending(false);
5937
+ setData(response);
5938
+ return response;
5939
+ }
5940
+ const resp = {
5941
+ id: requestId,
5942
+ cancelled: true,
5943
+ ...requestToAnnotationResponse(request)
5944
+ };
5945
+ opts?.onSuccess?.(resp);
5946
+ setData(resp);
5947
+ setId((i) => i + 1);
5948
+ setIsPending(false);
5949
+ return resp;
5950
+ }
5951
+ return null;
5952
+ },
5953
+ [opts?.onSuccess, requestAnnotation, requestId]
5954
+ );
5955
+ const reset = (0, import_react39.useCallback)(() => {
5956
+ setData(null);
5957
+ setIsPending(false);
5958
+ }, []);
5959
+ (0, import_react39.useEffect)(() => {
5960
+ const request = getRequestId();
5961
+ setRequestId(request.requestId);
5962
+ return () => {
5963
+ request.clear();
5964
+ };
5965
+ }, [id]);
5966
+ return {
5967
+ id,
5968
+ busy,
5969
+ isPending,
5970
+ requestAnnotation: mutateAsync,
5971
+ cancelRequest: () => requestId ? cancelRequest(requestId) : void 0,
5972
+ completeRequest: () => requestId ? completeRequest(requestId) : void 0,
5973
+ reset,
5974
+ data
5975
+ };
5976
+ }
5169
5977
  //# sourceMappingURL=index.cjs.map