@manifest-editor/shell 1.2.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.js CHANGED
@@ -5,24 +5,6 @@ var __publicField = (obj, key, value) => {
5
5
  return value;
6
6
  };
7
7
 
8
- // src/AppContext/AppContext.tsx
9
- import { createContext, useCallback, useContext, useEffect as useEffect2, useMemo } from "react";
10
-
11
- // ../../node_modules/.pnpm/tiny-invariant@1.3.3/node_modules/tiny-invariant/dist/esm/tiny-invariant.js
12
- var isProduction = false;
13
- var prefix = "Invariant failed";
14
- function invariant(condition, message) {
15
- if (condition) {
16
- return;
17
- }
18
- if (isProduction) {
19
- throw new Error(prefix);
20
- }
21
- var provided = typeof message === "function" ? message() : message;
22
- var value = provided ? "".concat(prefix, ": ").concat(provided) : prefix;
23
- throw new Error(value);
24
- }
25
-
26
8
  // ../ui/madoc/use-local-storage.ts
27
9
  import { useEffect, useRef, useState } from "react";
28
10
  import mitt from "mitt";
@@ -96,33 +78,133 @@ function useLocalStorage(key, initialValue) {
96
78
  }
97
79
 
98
80
  // src/AppContext/AppContext.tsx
81
+ import {
82
+ createContext as createContext2,
83
+ useCallback as useCallback2,
84
+ useContext as useContext2,
85
+ useEffect as useEffect2,
86
+ useMemo as useMemo2
87
+ } from "react";
88
+
89
+ // ../../node_modules/.pnpm/tiny-invariant@1.3.3/node_modules/tiny-invariant/dist/esm/tiny-invariant.js
90
+ var isProduction = false;
91
+ var prefix = "Invariant failed";
92
+ function invariant(condition, message) {
93
+ if (condition) {
94
+ return;
95
+ }
96
+ if (isProduction) {
97
+ throw new Error(prefix);
98
+ }
99
+ var provided = typeof message === "function" ? message() : message;
100
+ var value = provided ? "".concat(prefix, ": ").concat(provided) : prefix;
101
+ throw new Error(value);
102
+ }
103
+
104
+ // src/ConfigContext/ConfigContext.tsx
105
+ import { createContext, useCallback, useContext, useMemo, useState as useState2 } from "react";
99
106
  import { jsx } from "react/jsx-runtime";
100
- var PrimeAppReactContext = createContext(null);
101
- var AppReactContext = createContext(null);
102
- var AppStateReactContext = createContext({
107
+ var DEFAULT_CONFIG = {
108
+ previews: [],
109
+ behaviorPresets: [
110
+ "auto-advance",
111
+ "no-auto-advance",
112
+ "repeat",
113
+ "no-repeat",
114
+ "unordered",
115
+ "individuals",
116
+ "continuous",
117
+ "paged",
118
+ "non-paged",
119
+ "facing-pages",
120
+ "multi-part",
121
+ "together",
122
+ "sequence",
123
+ "thumbnail-nav",
124
+ "no-nav",
125
+ "hidden"
126
+ ],
127
+ defaultPreview: null,
128
+ editorConfig: {},
129
+ newTemplates: null,
130
+ i18n: {
131
+ advancedLanguageMode: false,
132
+ availableLanguages: ["en", "cy", "nl", "fr"],
133
+ defaultLanguage: "en"
134
+ },
135
+ editorFeatureFlags: {
136
+ enableMultiImageCanvases: true,
137
+ enableMultiMediaCanvases: true
138
+ },
139
+ uploadBackends: [],
140
+ export: {
141
+ baseIdentifier: null,
142
+ version: 3
143
+ }
144
+ };
145
+ var ConfigReactContext = createContext(DEFAULT_CONFIG);
146
+ var SaveConfigReactContext = createContext(() => {
147
+ });
148
+ function useConfig() {
149
+ return useContext(ConfigReactContext);
150
+ }
151
+ function useSaveConfig() {
152
+ return useContext(SaveConfigReactContext);
153
+ }
154
+ function ConfigProvider({
155
+ children,
156
+ config,
157
+ saveConfig
158
+ }) {
159
+ const [runtimeConfig, setRuntimeConfig] = useState2(null);
160
+ const resolvedConfig = useMemo(
161
+ () => ({
162
+ ...DEFAULT_CONFIG,
163
+ ...config || {},
164
+ ...runtimeConfig || {}
165
+ }),
166
+ [config, runtimeConfig]
167
+ );
168
+ const memoSaveConfig = useCallback(
169
+ (config2) => {
170
+ setRuntimeConfig(config2);
171
+ if (saveConfig) {
172
+ saveConfig(config2);
173
+ }
174
+ },
175
+ [config]
176
+ );
177
+ return /* @__PURE__ */ jsx(SaveConfigReactContext.Provider, { value: memoSaveConfig, children: /* @__PURE__ */ jsx(ConfigReactContext.Provider, { value: resolvedConfig, children }) });
178
+ }
179
+
180
+ // src/AppContext/AppContext.tsx
181
+ import { jsx as jsx2 } from "react/jsx-runtime";
182
+ var PrimeAppReactContext = createContext2(null);
183
+ var AppReactContext = createContext2(null);
184
+ var AppStateReactContext = createContext2({
103
185
  state: null,
104
186
  setState: () => {
105
187
  }
106
188
  });
107
189
  function useAppInstance() {
108
- const ctx = useContext(AppReactContext);
190
+ const ctx = useContext2(AppReactContext);
109
191
  invariant(ctx, "Hook useAppInstance must be used inside <AppProvider />");
110
192
  return ctx;
111
193
  }
112
194
  function useApp() {
113
- const app = useContext(PrimeAppReactContext);
195
+ const app = useContext2(PrimeAppReactContext);
114
196
  invariant(app, "Hook useApp must be used inside <AppProvider />");
115
197
  return app;
116
198
  }
117
199
  function useAppState() {
118
- return useContext(AppStateReactContext);
200
+ return useContext2(AppStateReactContext);
119
201
  }
120
202
  function AppStateProvider(props) {
121
203
  const [state, _setState, stateRef] = useLocalStorage(
122
204
  `app-state/${props.appId}/${props.instanceId}`,
123
205
  props.initialState || {}
124
206
  );
125
- const setState = useCallback((partial) => {
207
+ const setState = useCallback2((partial) => {
126
208
  const existing = stateRef.current ? JSON.parse(stateRef.current || "{}") : {};
127
209
  const partialState = (typeof partial === "function" ? partial(existing) : partial) || {};
128
210
  _setState({
@@ -135,8 +217,11 @@ function AppStateProvider(props) {
135
217
  setState(props.args);
136
218
  }
137
219
  }, [props.appId]);
138
- const ctx = useMemo(() => ({ state: state || {}, setState }), [setState, state]);
139
- return /* @__PURE__ */ jsx(AppStateReactContext.Provider, { value: ctx, children: props.children });
220
+ const ctx = useMemo2(
221
+ () => ({ state: state || {}, setState }),
222
+ [setState, state]
223
+ );
224
+ return /* @__PURE__ */ jsx2(AppStateReactContext.Provider, { value: ctx, children: props.children });
140
225
  }
141
226
  function AppProvider({
142
227
  instanceId,
@@ -146,17 +231,29 @@ function AppProvider({
146
231
  children,
147
232
  initialState
148
233
  }) {
149
- const ctx = useMemo(() => ({ instanceId, appId, args }), [instanceId, appId, args]);
150
- const _initialState = useMemo(() => initialState || {}, [instanceId]);
151
- return /* @__PURE__ */ jsx(PrimeAppReactContext.Provider, { value: definition, children: /* @__PURE__ */ jsx(AppReactContext.Provider, { value: ctx, children: /* @__PURE__ */ jsx(AppStateProvider, { instanceId: ctx.instanceId, appId: ctx.appId, args: ctx.args, initialState: _initialState, children }) }) });
234
+ const ctx = useMemo2(
235
+ () => ({ instanceId, appId, args }),
236
+ [instanceId, appId, args]
237
+ );
238
+ const _initialState = useMemo2(() => initialState || {}, [instanceId]);
239
+ return /* @__PURE__ */ jsx2(ConfigProvider, { config: definition.config || {}, children: /* @__PURE__ */ jsx2(PrimeAppReactContext.Provider, { value: definition, children: /* @__PURE__ */ jsx2(AppReactContext.Provider, { value: ctx, children: /* @__PURE__ */ jsx2(
240
+ AppStateProvider,
241
+ {
242
+ instanceId: ctx.instanceId,
243
+ appId: ctx.appId,
244
+ args: ctx.args,
245
+ initialState: _initialState,
246
+ children
247
+ }
248
+ ) }) }) });
152
249
  }
153
250
 
154
251
  // src/AppContext/MultiAppContext.tsx
155
- import { createContext as createContext2, useContext as useContext2, useMemo as useMemo2 } from "react";
156
- import { jsx as jsx2 } from "react/jsx-runtime";
157
- var MultiAppContext = createContext2(null);
252
+ import { createContext as createContext3, useContext as useContext3, useMemo as useMemo3 } from "react";
253
+ import { jsx as jsx3 } from "react/jsx-runtime";
254
+ var MultiAppContext = createContext3(null);
158
255
  function useApps() {
159
- const ctx = useContext2(MultiAppContext);
256
+ const ctx = useContext3(MultiAppContext);
160
257
  invariant(ctx, "Hook useApps must be used inside <MultiAppProvider />");
161
258
  return ctx;
162
259
  }
@@ -186,7 +283,7 @@ function MultiAppProvider({
186
283
  changeApp({ id: collectionApp });
187
284
  }
188
285
  };
189
- const ctx = useMemo2(
286
+ const ctx = useMemo3(
190
287
  () => ({
191
288
  currentApp: currentApp || { id: defaultApp },
192
289
  initialApp: initialApp || { id: defaultApp },
@@ -200,14 +297,14 @@ function MultiAppProvider({
200
297
  if (!currentApp || !currentFullApp) {
201
298
  return null;
202
299
  }
203
- return /* @__PURE__ */ jsx2(
300
+ return /* @__PURE__ */ jsx3(
204
301
  AppProvider,
205
302
  {
206
303
  appId: currentApp.id,
207
304
  definition: currentFullApp,
208
305
  instanceId: currentApp.id + instanceId,
209
306
  args: currentApp.args,
210
- children: /* @__PURE__ */ jsx2(MultiAppContext.Provider, { value: ctx, children })
307
+ children: /* @__PURE__ */ jsx3(MultiAppContext.Provider, { value: ctx, children })
211
308
  }
212
309
  );
213
310
  }
@@ -284,11 +381,89 @@ var ContextButton = styled.button`
284
381
  letter-spacing: -0.42px;
285
382
  `;
286
383
 
384
+ // src/PreviewButton/PreviewButton.tsx
385
+ import { DownloadButton } from "@manifest-editor/components";
386
+
387
+ // ../ui/icons/CloseIcon.tsx
388
+ import { jsx as jsx4, jsxs } from "react/jsx-runtime";
389
+ var CloseIcon = ({ height = 16 }) => /* @__PURE__ */ jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", height, viewBox: "0 0 24 24", width: "24px", fill: "#000000", children: [
390
+ /* @__PURE__ */ jsx4("path", { d: "M0 0h24v24H0z", fill: "none" }),
391
+ /* @__PURE__ */ jsx4("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" })
392
+ ] });
393
+
394
+ // ../ui/icons/DownIcon.tsx
395
+ import { jsx as jsx5 } from "react/jsx-runtime";
396
+ var DownIcon = ({ rotate = 0, ...props }) => /* @__PURE__ */ jsx5(
397
+ "svg",
398
+ {
399
+ version: "1.2",
400
+ xmlns: "http://www.w3.org/2000/svg",
401
+ overflow: "visible",
402
+ preserveAspectRatio: "none",
403
+ viewBox: "0 0 24 24",
404
+ width: "1em",
405
+ height: "1em",
406
+ style: {
407
+ fill: "rgba(0, 0, 0, 0.6)",
408
+ transform: `rotate(${rotate}deg)`,
409
+ transition: "transform 0.2s"
410
+ },
411
+ ...props,
412
+ children: /* @__PURE__ */ jsx5(
413
+ "path",
414
+ {
415
+ 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",
416
+ fill: "currentColor"
417
+ }
418
+ )
419
+ }
420
+ );
421
+
422
+ // src/PreviewButton/PreviewButton.tsx
423
+ import useDropdownMenu from "react-accessible-dropdown-menu-hook";
424
+ import { useVault as useVault2 } from "react-iiif-vault";
425
+
426
+ // src/AppResourceProvider/AppResourceProvider.tsx
427
+ import { createContext as createContext4, useContext as useContext4 } from "react";
428
+ import { CollectionContext, ManifestContext, VaultProvider, useExistingVault } from "react-iiif-vault";
429
+ import { jsx as jsx6 } from "react/jsx-runtime";
430
+ var AppResourceReactProvider = createContext4(null);
431
+ var AppResourceInstanceReactProvider = createContext4(null);
432
+ function useAppResourceInstance() {
433
+ const ctx = useContext4(AppResourceInstanceReactProvider);
434
+ const resource = useContext4(AppResourceReactProvider);
435
+ const instanceId = ctx || resource?.id;
436
+ invariant(instanceId, "useResourceInstance can only be called from inside <ResourceProvider />");
437
+ return instanceId;
438
+ }
439
+ function useAppResource() {
440
+ const ctx = useContext4(AppResourceReactProvider);
441
+ invariant(ctx, "useResource can only be called from inside <ResourceProvider />");
442
+ return ctx;
443
+ }
444
+ function AppResourceInstanceProvider({ id, children }) {
445
+ if (!id) {
446
+ return children;
447
+ }
448
+ return /* @__PURE__ */ jsx6(AppResourceInstanceReactProvider.Provider, { value: id, children });
449
+ }
450
+ function AppResourceProvider({ resource, children }) {
451
+ const vault = useExistingVault();
452
+ let inner = children;
453
+ if (resource && resource.type === "Manifest") {
454
+ inner = /* @__PURE__ */ jsx6(VaultProvider, { vault: vault || void 0, children: /* @__PURE__ */ jsx6(ManifestContext, { manifest: resource.id || "", children }) });
455
+ }
456
+ if (resource && resource.type === "Collection") {
457
+ inner = /* @__PURE__ */ jsx6(VaultProvider, { vault: vault || void 0, children: /* @__PURE__ */ jsx6(CollectionContext, { collection: resource.id || "", children }) });
458
+ }
459
+ return /* @__PURE__ */ jsx6(AppResourceReactProvider.Provider, { value: resource, children: inner });
460
+ }
461
+
287
462
  // src/PreviewContext/PreviewContext.tsx
288
- import { createContext as createContext4, memo, useContext as useContext4, useEffect as useEffect3, useMemo as useMemo4, useReducer } from "react";
463
+ import { createContext as createContext5, memo, useContext as useContext5, useEffect as useEffect3, useMemo as useMemo5, useReducer } from "react";
289
464
 
290
465
  // src/PreviewContext/PreviewContext.hooks.ts
291
- import { useMemo as useMemo3 } from "react";
466
+ import { useMemo as useMemo4 } from "react";
292
467
 
293
468
  // src/PreviewContext/previews/ExternalManifestUrlPreview.ts
294
469
  var ExternalManifestUrlPreview = class {
@@ -463,49 +638,11 @@ var IIIFPreviewService = class {
463
638
 
464
639
  // src/PreviewContext/PreviewContext.hooks.ts
465
640
  import { useVault } from "react-iiif-vault";
466
-
467
- // src/AppResourceProvider/AppResourceProvider.tsx
468
- import { createContext as createContext3, useContext as useContext3 } from "react";
469
- import { CollectionContext, ManifestContext, VaultProvider, useExistingVault } from "react-iiif-vault";
470
- import { jsx as jsx3 } from "react/jsx-runtime";
471
- var AppResourceReactProvider = createContext3(null);
472
- var AppResourceInstanceReactProvider = createContext3(null);
473
- function useAppResourceInstance() {
474
- const ctx = useContext3(AppResourceInstanceReactProvider);
475
- const resource = useContext3(AppResourceReactProvider);
476
- const instanceId = ctx || resource?.id;
477
- invariant(instanceId, "useResourceInstance can only be called from inside <ResourceProvider />");
478
- return instanceId;
479
- }
480
- function useAppResource() {
481
- const ctx = useContext3(AppResourceReactProvider);
482
- invariant(ctx, "useResource can only be called from inside <ResourceProvider />");
483
- return ctx;
484
- }
485
- function AppResourceInstanceProvider({ id, children }) {
486
- if (!id) {
487
- return children;
488
- }
489
- return /* @__PURE__ */ jsx3(AppResourceInstanceReactProvider.Provider, { value: id, children });
490
- }
491
- function AppResourceProvider({ resource, children }) {
492
- const vault = useExistingVault();
493
- let inner = children;
494
- if (resource && resource.type === "Manifest") {
495
- inner = /* @__PURE__ */ jsx3(VaultProvider, { vault: vault || void 0, children: /* @__PURE__ */ jsx3(ManifestContext, { manifest: resource.id || "", children }) });
496
- }
497
- if (resource && resource.type === "Collection") {
498
- inner = /* @__PURE__ */ jsx3(VaultProvider, { vault: vault || void 0, children: /* @__PURE__ */ jsx3(CollectionContext, { collection: resource.id || "", children }) });
499
- }
500
- return /* @__PURE__ */ jsx3(AppResourceReactProvider.Provider, { value: resource, children: inner });
501
- }
502
-
503
- // src/PreviewContext/PreviewContext.hooks.ts
504
641
  function usePreviewActions(state, dispatch, handlers, previews, setPreviews) {
505
642
  const resource = useAppResource();
506
643
  const instanceId = useAppResourceInstance();
507
644
  const vault = useVault();
508
- const previewActions = useMemo3(
645
+ const previewActions = useMemo4(
509
646
  () => ({
510
647
  setPreview: (preview) => {
511
648
  if (!preview)
@@ -518,7 +655,7 @@ function usePreviewActions(state, dispatch, handlers, previews, setPreviews) {
518
655
  }),
519
656
  [setPreviews, instanceId]
520
657
  );
521
- const [handlerMap, providesMap] = useMemo3(() => {
658
+ const [handlerMap, providesMap] = useMemo4(() => {
522
659
  const map = {};
523
660
  const providesMap2 = {};
524
661
  for (const handler of handlers) {
@@ -636,7 +773,7 @@ function usePreviewActions(state, dispatch, handlers, previews, setPreviews) {
636
773
  }
637
774
  }
638
775
  }
639
- return useMemo3(
776
+ return useMemo4(
640
777
  () => ({ selectPreview, deletePreview, focusPreview, activatePreview, updatePreviews, getPreviewLink }),
641
778
  // Dispatch has a stable identity.
642
779
  // eslint-disable-next-line react-hooks/exhaustive-deps
@@ -644,7 +781,7 @@ function usePreviewActions(state, dispatch, handlers, previews, setPreviews) {
644
781
  );
645
782
  }
646
783
  function usePreviewHandlers(configs) {
647
- return useMemo3(() => {
784
+ return useMemo4(() => {
648
785
  const handlers = [];
649
786
  for (const config of configs) {
650
787
  switch (config.type) {
@@ -697,9 +834,9 @@ function getDefaultPreviewState() {
697
834
  }
698
835
 
699
836
  // src/PreviewContext/PreviewContext.tsx
700
- import { jsx as jsx4 } from "react/jsx-runtime";
701
- var PreviewReactContext = createContext4(null);
702
- var AvailablePreviewReactContext = createContext4([]);
837
+ import { jsx as jsx7 } from "react/jsx-runtime";
838
+ var PreviewReactContext = createContext5(null);
839
+ var AvailablePreviewReactContext = createContext5([]);
703
840
  var PreviewProvider = memo(function PreviewProvider2({
704
841
  children,
705
842
  configs = []
@@ -709,7 +846,7 @@ var PreviewProvider = memo(function PreviewProvider2({
709
846
  const [previews, setPreviews] = useLocalStorage(`preview-${instanceId}`, []);
710
847
  const [state, dispatch] = useReducer(previewContextReducer, void 0, getDefaultPreviewState);
711
848
  const actions = usePreviewActions(state, dispatch, handlers, previews, setPreviews);
712
- const context = useMemo4(
849
+ const context = useMemo5(
713
850
  () => ({ configs, actions, handlers, ...state }),
714
851
  [actions, configs, handlers, state]
715
852
  );
@@ -729,13 +866,13 @@ var PreviewProvider = memo(function PreviewProvider2({
729
866
  }
730
867
  }
731
868
  }, [instanceId]);
732
- return /* @__PURE__ */ jsx4(AvailablePreviewReactContext.Provider, { value: previews, children: /* @__PURE__ */ jsx4(PreviewReactContext.Provider, { value: context, children }) });
869
+ return /* @__PURE__ */ jsx7(AvailablePreviewReactContext.Provider, { value: previews, children: /* @__PURE__ */ jsx7(PreviewReactContext.Provider, { value: context, children }) });
733
870
  });
734
871
  function usePreviews() {
735
- return useContext4(AvailablePreviewReactContext);
872
+ return useContext5(AvailablePreviewReactContext);
736
873
  }
737
874
  function usePreviewContext() {
738
- const ctx = useContext4(PreviewReactContext);
875
+ const ctx = useContext5(PreviewReactContext);
739
876
  invariant(ctx, "usePreviewContext() can only be called from inside <PreviewProvider />");
740
877
  return ctx;
741
878
  }
@@ -945,147 +1082,44 @@ var ButtonEmpty = styled3.div`
945
1082
  `;
946
1083
 
947
1084
  // src/PreviewButton/PreviewButton.tsx
948
- import useDropdownMenu from "react-accessible-dropdown-menu-hook";
949
-
950
- // ../ui/icons/DownIcon.tsx
951
- import { jsx as jsx5 } from "react/jsx-runtime";
952
- var DownIcon = ({ rotate = 0, ...props }) => /* @__PURE__ */ jsx5(
953
- "svg",
954
- {
955
- version: "1.2",
956
- xmlns: "http://www.w3.org/2000/svg",
957
- overflow: "visible",
958
- preserveAspectRatio: "none",
959
- viewBox: "0 0 24 24",
960
- width: "1em",
961
- height: "1em",
962
- style: {
963
- fill: "rgba(0, 0, 0, 0.6)",
964
- transform: `rotate(${rotate}deg)`,
965
- transition: "transform 0.2s"
966
- },
967
- ...props,
968
- children: /* @__PURE__ */ jsx5(
969
- "path",
1085
+ import { Fragment, jsx as jsx8, jsxs as jsxs2 } from "react/jsx-runtime";
1086
+ function PreviewButton({
1087
+ downloadEnabled,
1088
+ fileName
1089
+ }) {
1090
+ const { active, configs, actions, selected } = usePreviewContext();
1091
+ const vault = useVault2();
1092
+ const config = useConfig();
1093
+ const resource = useAppResource();
1094
+ const configsToShow = configs.filter(
1095
+ (c) => c.type === "external-manifest-preview"
1096
+ );
1097
+ const { isOpen, buttonProps, itemProps } = useDropdownMenu(
1098
+ configsToShow.length
1099
+ );
1100
+ if (configsToShow.length === 0) {
1101
+ return /* @__PURE__ */ jsx8(ButtonEmpty, { children: "Preview not available" });
1102
+ }
1103
+ return /* @__PURE__ */ jsxs2(Fragment, { children: [
1104
+ downloadEnabled ? /* @__PURE__ */ jsx8("div", { className: "mr-4", children: /* @__PURE__ */ jsx8(
1105
+ DownloadButton,
970
1106
  {
971
- 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",
972
- fill: "currentColor"
973
- }
974
- )
975
- }
976
- );
977
-
978
- // ../ui/icons/CloseIcon.tsx
979
- import { jsx as jsx6, jsxs } from "react/jsx-runtime";
980
- var CloseIcon = ({ height = 16 }) => /* @__PURE__ */ jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", height, viewBox: "0 0 24 24", width: "24px", fill: "#000000", children: [
981
- /* @__PURE__ */ jsx6("path", { d: "M0 0h24v24H0z", fill: "none" }),
982
- /* @__PURE__ */ jsx6("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" })
983
- ] });
984
-
985
- // src/PreviewButton/PreviewButton.tsx
986
- import { useVault as useVault2 } from "react-iiif-vault";
987
- import { DownloadButton } from "@manifest-editor/components";
988
-
989
- // src/ConfigContext/ConfigContext.tsx
990
- import { createContext as createContext5, useCallback as useCallback2, useContext as useContext5, useMemo as useMemo5, useState as useState2 } from "react";
991
- import { jsx as jsx7 } from "react/jsx-runtime";
992
- var DEFAULT_CONFIG = {
993
- previews: [],
994
- behaviorPresets: [
995
- "auto-advance",
996
- "no-auto-advance",
997
- "repeat",
998
- "no-repeat",
999
- "unordered",
1000
- "individuals",
1001
- "continuous",
1002
- "paged",
1003
- "non-paged",
1004
- "facing-pages",
1005
- "multi-part",
1006
- "together",
1007
- "sequence",
1008
- "thumbnail-nav",
1009
- "no-nav",
1010
- "hidden"
1011
- ],
1012
- defaultPreview: null,
1013
- editorConfig: {},
1014
- newTemplates: null,
1015
- i18n: {
1016
- advancedLanguageMode: false,
1017
- availableLanguages: ["en", "cy", "nl", "fr"],
1018
- defaultLanguage: "en"
1019
- },
1020
- editorFeatureFlags: {
1021
- enableMultiImageCanvases: true,
1022
- enableMultiMediaCanvases: true
1023
- },
1024
- uploadBackends: [],
1025
- export: {
1026
- baseIdentifier: null,
1027
- version: 3
1028
- }
1029
- };
1030
- var ConfigReactContext = createContext5(DEFAULT_CONFIG);
1031
- var SaveConfigReactContext = createContext5(() => {
1032
- });
1033
- function useConfig() {
1034
- return useContext5(ConfigReactContext);
1035
- }
1036
- function useSaveConfig() {
1037
- return useContext5(SaveConfigReactContext);
1038
- }
1039
- function ConfigProvider({
1040
- children,
1041
- config,
1042
- saveConfig
1043
- }) {
1044
- const [runtimeConfig, setRuntimeConfig] = useState2(null);
1045
- const resolvedConfig = useMemo5(
1046
- () => ({
1047
- ...DEFAULT_CONFIG,
1048
- ...config || {},
1049
- ...runtimeConfig || {}
1050
- }),
1051
- [config, runtimeConfig]
1052
- );
1053
- const memoSaveConfig = useCallback2(
1054
- (config2) => {
1055
- setRuntimeConfig(config2);
1056
- if (saveConfig) {
1057
- saveConfig(config2);
1058
- }
1059
- },
1060
- [config]
1061
- );
1062
- return /* @__PURE__ */ jsx7(SaveConfigReactContext.Provider, { value: memoSaveConfig, children: /* @__PURE__ */ jsx7(ConfigReactContext.Provider, { value: resolvedConfig, children }) });
1063
- }
1064
-
1065
- // src/PreviewButton/PreviewButton.tsx
1066
- import { Fragment, jsx as jsx8, jsxs as jsxs2 } from "react/jsx-runtime";
1067
- function PreviewButton({ downloadEnabled, fileName }) {
1068
- const { active, configs, actions, selected } = usePreviewContext();
1069
- const vault = useVault2();
1070
- const config = useConfig();
1071
- const resource = useAppResource();
1072
- const configsToShow = configs.filter((c) => c.type === "external-manifest-preview");
1073
- const { isOpen, buttonProps, itemProps } = useDropdownMenu(configsToShow.length);
1074
- if (configsToShow.length === 0) {
1075
- return /* @__PURE__ */ jsx8(ButtonEmpty, { children: "Preview not available" });
1076
- }
1077
- return /* @__PURE__ */ jsxs2(Fragment, { children: [
1078
- downloadEnabled ? /* @__PURE__ */ jsx8("div", { className: "mr-4", children: /* @__PURE__ */ jsx8(
1079
- DownloadButton,
1080
- {
1081
- fileName: fileName || "manifest.json",
1082
- label: "Download manifest",
1083
- getData: () => {
1084
- if (config.export && config.export.version === 2) {
1085
- return JSON.stringify(vault.toPresentation2(resource), null, 2);
1086
- }
1087
- return JSON.stringify(vault.toPresentation3(resource), null, 2);
1088
- }
1107
+ fileName: fileName || "manifest.json",
1108
+ label: "Download manifest",
1109
+ getData: () => {
1110
+ if (config.export && config.export.version === 2) {
1111
+ return JSON.stringify(
1112
+ vault.toPresentation2(resource),
1113
+ null,
1114
+ 2
1115
+ );
1116
+ }
1117
+ return JSON.stringify(
1118
+ vault.toPresentation3(resource),
1119
+ null,
1120
+ 2
1121
+ );
1122
+ }
1089
1123
  }
1090
1124
  ) }) : null,
1091
1125
  /* @__PURE__ */ jsxs2(ButtonContainer, { children: [
@@ -1098,7 +1132,6 @@ function PreviewButton({ downloadEnabled, fileName }) {
1098
1132
  if (defaultPreviewId) {
1099
1133
  const found = configs.find((c) => c.id === defaultPreviewId);
1100
1134
  if (found) {
1101
- console.log(found, { defaultPreviewId });
1102
1135
  actions.selectPreview(found.id);
1103
1136
  actions.updatePreviews();
1104
1137
  return;
@@ -1115,9 +1148,29 @@ function PreviewButton({ downloadEnabled, fileName }) {
1115
1148
  /* @__PURE__ */ jsx8(MenuContainer, { $open: isOpen, children: configsToShow.map((config2, key) => {
1116
1149
  const inactive = active.indexOf(config2.id) === -1;
1117
1150
  return /* @__PURE__ */ jsxs2(MenuItem, { ...itemProps[key], children: [
1118
- /* @__PURE__ */ jsx8(MenuItemStatus, { $status: inactive ? "available" : config2.id === selected ? "active" : "configured" }),
1119
- /* @__PURE__ */ jsx8(MenuItemLabel, { onClick: () => actions.selectPreview(config2.id), children: config2.label }),
1120
- !inactive ? /* @__PURE__ */ jsx8(MenuItemClose, { onClick: () => actions.deletePreview(config2.id), children: /* @__PURE__ */ jsx8(CloseIcon, {}) }) : null
1151
+ /* @__PURE__ */ jsx8(
1152
+ MenuItemStatus,
1153
+ {
1154
+ $status: inactive ? "available" : config2.id === selected ? "active" : "configured"
1155
+ }
1156
+ ),
1157
+ /* @__PURE__ */ jsx8(
1158
+ MenuItemLabel,
1159
+ {
1160
+ onClick: () => {
1161
+ actions.selectPreview(config2.id);
1162
+ actions.updatePreviews();
1163
+ },
1164
+ children: config2.label
1165
+ }
1166
+ ),
1167
+ !inactive ? /* @__PURE__ */ jsx8(
1168
+ MenuItemClose,
1169
+ {
1170
+ onClick: () => actions.deletePreview(config2.id),
1171
+ children: /* @__PURE__ */ jsx8(CloseIcon, {})
1172
+ }
1173
+ ) : null
1121
1174
  ] }, config2.id);
1122
1175
  }) })
1123
1176
  ] })
@@ -1158,17 +1211,432 @@ function AppMenuProvider({ children, menu }) {
1158
1211
  return /* @__PURE__ */ jsx10(ReactAppMenuContext.Provider, { value: menu, children });
1159
1212
  }
1160
1213
 
1214
+ // src/AtlasStore/AtlasStoreProvider.tsx
1215
+ import { createContext as createContext8, useContext as useContext8, useMemo as useMemo6 } from "react";
1216
+
1217
+ // src/AtlasStore/AtlasStore.ts
1218
+ import { createHelper } from "polygon-editor";
1219
+ import { createStore } from "zustand/vanilla";
1220
+
1221
+ // src/AtlasStore/polygon-to-bounding-box.ts
1222
+ function polygonToBoundingBox(polygon) {
1223
+ if (!polygon) {
1224
+ return null;
1225
+ }
1226
+ if (polygon.points.length > 2) {
1227
+ const x1 = Math.min(...polygon.points.map((p) => p[0]));
1228
+ const y1 = Math.min(...polygon.points.map((p) => p[1]));
1229
+ const x2 = Math.max(0, ...polygon.points.map((p) => p[0]));
1230
+ const y2 = Math.max(0, ...polygon.points.map((p) => p[1]));
1231
+ return {
1232
+ x: x1,
1233
+ y: y1,
1234
+ width: x2 - x1,
1235
+ height: y2 - y1
1236
+ };
1237
+ }
1238
+ return null;
1239
+ }
1240
+
1241
+ // src/AtlasStore/AtlasStore.ts
1242
+ function polygonToTarget(polygon) {
1243
+ if (!polygon)
1244
+ return null;
1245
+ return {
1246
+ type: "SvgSelector",
1247
+ 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>`
1248
+ };
1249
+ }
1250
+ function requestToAnnotationResponse(request) {
1251
+ if (request.type === "polygon") {
1252
+ return {
1253
+ polygon: {
1254
+ points: request.points || [],
1255
+ open: request.open || false
1256
+ },
1257
+ requestType: "polygon",
1258
+ boundingBox: polygonToBoundingBox({
1259
+ points: request.points || [],
1260
+ open: false
1261
+ }),
1262
+ target: polygonToTarget({ points: request.points || [], open: false })
1263
+ };
1264
+ }
1265
+ const box = request.selector;
1266
+ if (box) {
1267
+ const points = [
1268
+ [box.x, box.y],
1269
+ [box.x + box.width, box.y],
1270
+ [box.x + box.width, box.y + box.height],
1271
+ [box.x, box.y + box.height]
1272
+ ];
1273
+ return {
1274
+ polygon: {
1275
+ points,
1276
+ open: false
1277
+ },
1278
+ requestType: request.type,
1279
+ boundingBox: box,
1280
+ target: polygonToTarget({ points, open: false })
1281
+ };
1282
+ }
1283
+ return {
1284
+ polygon: { points: [], open: false },
1285
+ requestType: request.type,
1286
+ boundingBox: null,
1287
+ target: null
1288
+ };
1289
+ }
1290
+ var defaultSlowState = {
1291
+ shapeId: null,
1292
+ noShape: true,
1293
+ transitioning: false,
1294
+ actionIntentType: null,
1295
+ transitionIntentType: null,
1296
+ selectedPoints: [],
1297
+ hasClosestLine: false,
1298
+ modifiers: {
1299
+ Alt: false,
1300
+ Shift: false,
1301
+ Meta: false,
1302
+ proximity: 0
1303
+ // default value.
1304
+ },
1305
+ showBoundingBox: false,
1306
+ currentModifiers: {},
1307
+ validIntentKeys: {},
1308
+ pointerInsideShape: false,
1309
+ closestPoint: null,
1310
+ transitionModifiers: null,
1311
+ selectedStamp: null,
1312
+ lineMode: false,
1313
+ lineBoxMode: false,
1314
+ drawMode: false,
1315
+ bezierLines: [],
1316
+ boxMode: false,
1317
+ fixedAspectRatio: false
1318
+ };
1319
+ function createAtlasStore({ events: events2 }) {
1320
+ const store = createStore((set, get) => {
1321
+ let runtime = null;
1322
+ const onSave = (input) => {
1323
+ set(
1324
+ (s) => s.tool.requestId ? { polygon: { ...input, id: s.tool.requestId } } : {
1325
+ polygon: { id: void 0, points: [], open: true }
1326
+ }
1327
+ );
1328
+ };
1329
+ const polygons = createHelper(null, onSave);
1330
+ return {
1331
+ mode: "explore",
1332
+ tool: {
1333
+ enabled: false,
1334
+ requestId: null,
1335
+ canvasId: null
1336
+ },
1337
+ requestType: null,
1338
+ history: polygons.history,
1339
+ polygon: null,
1340
+ validRequestIds: [],
1341
+ stableViewport: null,
1342
+ canvasRelativePositions: {},
1343
+ canvasViewports: {},
1344
+ polygons,
1345
+ polygonState: defaultSlowState,
1346
+ setToolCanvasId: (canvasId) => {
1347
+ set((state) => ({ tool: { ...state.tool, canvasId } }));
1348
+ },
1349
+ switchTool: {
1350
+ draw() {
1351
+ set({ mode: "sketch" });
1352
+ helper.stamps.clear();
1353
+ helper.draw.enable();
1354
+ },
1355
+ polygon() {
1356
+ set({ mode: "sketch" });
1357
+ helper.stamps.clear();
1358
+ helper.draw.disable();
1359
+ helper.modes.disableLineBoxMode();
1360
+ helper.modes.disableLineMode();
1361
+ },
1362
+ line() {
1363
+ set({ mode: "sketch" });
1364
+ helper.modes.enableLineMode();
1365
+ },
1366
+ lineBox() {
1367
+ set({ mode: "sketch" });
1368
+ helper.modes.enableLineBoxMode();
1369
+ },
1370
+ square() {
1371
+ set({ mode: "sketch" });
1372
+ helper.stamps.square();
1373
+ },
1374
+ triangle() {
1375
+ set({ mode: "sketch" });
1376
+ helper.stamps.triangle();
1377
+ },
1378
+ hexagon() {
1379
+ set({ mode: "sketch" });
1380
+ helper.stamps.hexagon();
1381
+ },
1382
+ circle() {
1383
+ set({ mode: "sketch" });
1384
+ helper.stamps.circle();
1385
+ },
1386
+ remove() {
1387
+ helper.key.down("Backspace");
1388
+ }
1389
+ },
1390
+ reset: () => {
1391
+ const state = get();
1392
+ if (state.tool.requestId) {
1393
+ state.cancelRequest(state.tool.requestId);
1394
+ }
1395
+ },
1396
+ setPolygonState: (state) => set({
1397
+ polygonState: typeof state === "function" ? state(get().polygonState) : state
1398
+ }),
1399
+ getRequestId: () => {
1400
+ const requestId = Math.random().toString(36).slice(2);
1401
+ set((state) => ({
1402
+ validRequestIds: [...state.validRequestIds, requestId]
1403
+ }));
1404
+ return {
1405
+ requestId,
1406
+ clear: () => {
1407
+ if (get().tool.requestId === requestId) {
1408
+ }
1409
+ set((state) => ({
1410
+ tool: state.tool.requestId === requestId ? { enabled: false, requestId: null, canvasId: null } : state.tool,
1411
+ validRequestIds: state.validRequestIds.filter((id) => id !== requestId)
1412
+ }));
1413
+ }
1414
+ };
1415
+ },
1416
+ cancelRequest: (requestId) => {
1417
+ set((state) => ({
1418
+ mode: "explore",
1419
+ tool: state.tool.requestId === requestId ? { enabled: false, requestId: null, canvasId: null } : state.tool,
1420
+ validRequestIds: state.validRequestIds.filter((id) => id !== requestId)
1421
+ }));
1422
+ events2.emit("atlas.request-cancelled", { id: requestId });
1423
+ },
1424
+ requestAnnotation: async (request, options) => {
1425
+ const response = requestToAnnotationResponse(request);
1426
+ try {
1427
+ const { points = [], open = true } = response.polygon || {};
1428
+ const { requestId, canvasId = null, toolId } = options;
1429
+ const state = get();
1430
+ const isValid = state.validRequestIds.includes(requestId);
1431
+ if (!isValid)
1432
+ return null;
1433
+ if (state.tool.enabled)
1434
+ return null;
1435
+ polygons.setShape({ id: requestId, points, open });
1436
+ if (request.type === "box") {
1437
+ polygons.modes.enableBoxMode();
1438
+ }
1439
+ if (request.type === "target") {
1440
+ polygons.modes.enableBoxMode();
1441
+ polygons.modes.lockAspectRatio();
1442
+ }
1443
+ events2.emit("atlas.annotation-request", { id: requestId });
1444
+ set({
1445
+ polygon: { id: requestId, points, open },
1446
+ mode: "sketch",
1447
+ requestType: request.type,
1448
+ tool: {
1449
+ enabled: true,
1450
+ requestId,
1451
+ canvasId
1452
+ }
1453
+ });
1454
+ if (toolId) {
1455
+ state.switchTool[toolId]?.();
1456
+ } else if (points.length === 0) {
1457
+ state.switchTool.square();
1458
+ }
1459
+ return new Promise((resolve) => {
1460
+ const cancelHandler = (e) => {
1461
+ if (e.id !== requestId)
1462
+ return;
1463
+ set({
1464
+ mode: "explore",
1465
+ tool: {
1466
+ requestId: null,
1467
+ enabled: false,
1468
+ canvasId: null
1469
+ }
1470
+ });
1471
+ events2.off("atlas.request-cancelled", cancelHandler);
1472
+ events2.off("atlas.annotation-completed", handler);
1473
+ resolve(null);
1474
+ };
1475
+ const handler = (e) => {
1476
+ if (e.id !== requestId)
1477
+ return;
1478
+ set({
1479
+ mode: "explore",
1480
+ tool: {
1481
+ requestId: null,
1482
+ enabled: false,
1483
+ canvasId: null
1484
+ }
1485
+ });
1486
+ events2.off("atlas.annotation-completed", handler);
1487
+ events2.off("atlas.request-cancelled", cancelHandler);
1488
+ resolve(e);
1489
+ };
1490
+ events2.on("atlas.request-cancelled", cancelHandler);
1491
+ events2.on("atlas.annotation-completed", handler);
1492
+ });
1493
+ } catch (err) {
1494
+ return null;
1495
+ }
1496
+ },
1497
+ completeRequest: (requestId) => {
1498
+ if (typeof requestId === "string" && requestId) {
1499
+ if (requestId !== get().tool.requestId) {
1500
+ return;
1501
+ }
1502
+ }
1503
+ const polygon = get().polygon;
1504
+ if (!polygon)
1505
+ return;
1506
+ events2.emit("atlas.annotation-completed", {
1507
+ id: polygon.id,
1508
+ polygon,
1509
+ requestType: get().requestType,
1510
+ target: polygonToTarget(polygon),
1511
+ canvasId: get().tool.canvasId,
1512
+ boundingBox: polygonToBoundingBox(polygon)
1513
+ });
1514
+ },
1515
+ setAtlasRuntime: (newRuntime) => {
1516
+ runtime = newRuntime;
1517
+ events2.emit("atlas.ready", { runtime: newRuntime });
1518
+ runtime.world.addLayoutSubscriber((ev, data) => {
1519
+ if (ev === "event-activation" || ev === "zoom-to" || ev === "go-home") {
1520
+ if (runtime?._lastGoodScale && !Number.isNaN(runtime._lastGoodScale)) {
1521
+ helper.setScale(1 / runtime._lastGoodScale);
1522
+ }
1523
+ }
1524
+ });
1525
+ },
1526
+ clearAtlasRuntime: () => {
1527
+ runtime = null;
1528
+ set({ stableViewport: null });
1529
+ },
1530
+ setCanvasRelativePosition: (canvasId, position) => {
1531
+ set((state) => ({
1532
+ canvasRelativePositions: {
1533
+ ...state.canvasRelativePositions,
1534
+ [canvasId]: position
1535
+ }
1536
+ }));
1537
+ },
1538
+ clearCanvasRelativePosition: (canvasId) => {
1539
+ set((state) => {
1540
+ const newPositions = { ...state.canvasRelativePositions };
1541
+ delete newPositions[canvasId];
1542
+ return { canvasRelativePositions: newPositions };
1543
+ });
1544
+ },
1545
+ changeMode: (mode) => {
1546
+ set({ mode });
1547
+ },
1548
+ // Navigation controls
1549
+ nudgeLeft: () => {
1550
+ },
1551
+ nudgeRight: () => {
1552
+ },
1553
+ nudgeUp: () => {
1554
+ },
1555
+ nudgeDown: () => {
1556
+ },
1557
+ zoomIn: () => {
1558
+ runtime?.world?.zoomIn();
1559
+ },
1560
+ zoomOut: () => {
1561
+ runtime?.world?.zoomOut();
1562
+ },
1563
+ goHome: () => {
1564
+ runtime?.world?.goHome();
1565
+ }
1566
+ };
1567
+ });
1568
+ const helper = store.getState().polygons;
1569
+ events2.on("atlas.annotation-request", () => {
1570
+ helper.clock.start((state, slowState, dt) => {
1571
+ events2.emit("atlas.polygon-render", { state, slowState, dt });
1572
+ }, store.getState().setPolygonState);
1573
+ });
1574
+ events2.on("atlas.annotation-completed", () => {
1575
+ helper.clock.stop();
1576
+ });
1577
+ events2.on("atlas.request-cancelled", () => {
1578
+ helper.clock.stop();
1579
+ });
1580
+ return store;
1581
+ }
1582
+
1583
+ // src/hooks/use-event.tsx
1584
+ import mitt2 from "mitt";
1585
+ import { createContext as createContext7, useContext as useContext7, useEffect as useEffect4 } from "react";
1586
+ import { jsx as jsx11 } from "react/jsx-runtime";
1587
+ var events = mitt2();
1588
+ var ReactEmitterContext = createContext7(events);
1589
+ function EventEmitterProvider({
1590
+ children,
1591
+ emitter
1592
+ }) {
1593
+ return /* @__PURE__ */ jsx11(ReactEmitterContext.Provider, { value: emitter, children });
1594
+ }
1595
+ function useEmitter() {
1596
+ return useContext7(ReactEmitterContext);
1597
+ }
1598
+ function useEvent(key, listener, deps = []) {
1599
+ const emitter = useContext7(ReactEmitterContext);
1600
+ useEffect4(() => {
1601
+ const handler = (data) => {
1602
+ listener(data);
1603
+ };
1604
+ emitter.on(key, handler);
1605
+ return () => {
1606
+ emitter.off(key, handler);
1607
+ };
1608
+ }, [emitter, key, ...deps]);
1609
+ }
1610
+
1611
+ // src/AtlasStore/AtlasStoreProvider.tsx
1612
+ import { jsx as jsx12 } from "react/jsx-runtime";
1613
+ var AtlasStoreReactContext = createContext8(null);
1614
+ function useAtlasStore() {
1615
+ return useContext8(AtlasStoreReactContext);
1616
+ }
1617
+ function AtlasStoreProvider({
1618
+ children
1619
+ }) {
1620
+ const emitter = useEmitter();
1621
+ const value = useMemo6(() => {
1622
+ return createAtlasStore({ events: emitter });
1623
+ }, []);
1624
+ return /* @__PURE__ */ jsx12(AtlasStoreReactContext.Provider, { value, children });
1625
+ }
1626
+
1161
1627
  // src/BaseCreator/BaseCreator.tsx
1162
- import { memo as memo3, Suspense, useEffect as useEffect7, useMemo as useMemo11, useRef as useRef3, useState as useState5 } from "react";
1163
- import { useVault as useVault4 } from "react-iiif-vault";
1164
1628
  import { toRef as toRef3 } from "@iiif/parser";
1629
+ import { CreatorGrid } from "@manifest-editor/components";
1630
+ import {
1631
+ matchBasedOnResource as matchBasedOnResource2
1632
+ } from "@manifest-editor/creator-api";
1165
1633
 
1166
1634
  // ../ui/madoc/components/icons/Spinner.tsx
1167
- import { jsx as jsx11, jsxs as jsxs4 } from "react/jsx-runtime";
1635
+ import { jsx as jsx13, jsxs as jsxs4 } from "react/jsx-runtime";
1168
1636
  function Spinner(props) {
1169
- return /* @__PURE__ */ jsx11("svg", { width: "1em", height: "1em", viewBox: "0 0 42 42", xmlns: "http://www.w3.org/2000/svg", stroke: "#fff", ...props, children: /* @__PURE__ */ jsxs4("g", { transform: "translate(2 2)", strokeWidth: 5, fill: "none", fillRule: "evenodd", children: [
1170
- /* @__PURE__ */ jsx11("circle", { strokeOpacity: 0.5, cx: 18, cy: 18, r: 18 }),
1171
- /* @__PURE__ */ jsx11("path", { d: "M36 18c0-9.94-8.06-18-18-18", children: /* @__PURE__ */ jsx11(
1637
+ return /* @__PURE__ */ jsx13("svg", { width: "1em", height: "1em", viewBox: "0 0 42 42", xmlns: "http://www.w3.org/2000/svg", stroke: "#fff", ...props, children: /* @__PURE__ */ jsxs4("g", { transform: "translate(2 2)", strokeWidth: 5, fill: "none", fillRule: "evenodd", children: [
1638
+ /* @__PURE__ */ jsx13("circle", { strokeOpacity: 0.5, cx: 18, cy: 18, r: 18 }),
1639
+ /* @__PURE__ */ jsx13("path", { d: "M36 18c0-9.94-8.06-18-18-18", children: /* @__PURE__ */ jsx13(
1172
1640
  "animateTransform",
1173
1641
  {
1174
1642
  attributeName: "transform",
@@ -1182,137 +1650,19 @@ function Spinner(props) {
1182
1650
  ] }) });
1183
1651
  }
1184
1652
 
1185
- // src/highlighted-image-resources.ts
1186
- import { create } from "zustand";
1187
- import { useEffect as useEffect4, useMemo as useMemo6 } from "react";
1188
-
1189
- // src/helpers.ts
1190
- import { toRef } from "@iiif/parser";
1191
- async function getManifestNomalized(id) {
1192
- let responseData = void 0;
1193
- try {
1194
- await fetch(id).then((response) => {
1195
- return response.json().catch((err) => {
1196
- console.error(`'${err}' happened!`);
1197
- });
1198
- }).then((data) => {
1199
- responseData = { ...data };
1200
- });
1201
- } catch (error) {
1202
- console.log(error);
1203
- }
1204
- return responseData;
1205
- }
1206
- function createActionIdentity(type, property, parent) {
1207
- return `create_${type}_${property}_${toRef(parent)?.type || "unknown"}`;
1208
- }
1209
- function createDownload(data, fileName, fileType = "text/json") {
1210
- const blob = data instanceof Blob ? data : new Blob([data], { type: fileType });
1211
- const a = document.createElement("a");
1212
- a.download = fileName;
1213
- a.href = window.URL.createObjectURL(blob);
1214
- const clickEvt = new MouseEvent("click", {
1215
- view: window,
1216
- bubbles: true,
1217
- cancelable: true
1218
- });
1219
- a.dispatchEvent(clickEvt);
1220
- a.remove();
1221
- }
1222
- async function copyToClipboard(json) {
1223
- return navigator.clipboard.writeText(typeof json === "string" ? json : JSON.stringify(json, null, 2));
1224
- }
1225
- function randomId() {
1226
- return `${Math.random().toString(36).substr(2)}-${Date.now().toString(36)}`;
1227
- }
1228
- function mapApp(input, map) {
1229
- const { default: metadata, ...props } = input;
1230
- const app = {
1231
- metadata,
1232
- layout: {
1233
- leftPanels: [],
1234
- rightPanels: [],
1235
- centerPanels: [],
1236
- ...props
1237
- }
1238
- };
1239
- return map ? map(app) : app;
1240
- }
1241
-
1242
- // src/highlighted-image-resources.ts
1243
- var useHighlightedImageResource = create((set) => ({
1244
- regions: {},
1245
- resources: [],
1246
- setRegion: (id, region) => {
1247
- set((ex) => ({ ...ex.regions, regions: { [id]: region || null } }));
1248
- },
1249
- setHighlight: (id) => {
1250
- set({ resources: Array.isArray(id) ? id : [id] });
1251
- },
1252
- highlight: (id) => {
1253
- set((s) => {
1254
- if (s.resources.indexOf(id) !== -1) {
1255
- return s;
1256
- }
1257
- return { resources: [...s.resources, id] };
1258
- });
1259
- },
1260
- clearHighlight: (id) => {
1261
- set((s) => ({ resources: s.resources.filter((item) => item !== id) }));
1262
- }
1263
- }));
1264
- function useTemporaryHighlight(newValue) {
1265
- const id = useMemo6(() => randomId(), []);
1266
- const value = useHighlightedImageResource((s) => s.regions[id]);
1267
- const setRegion = useHighlightedImageResource((s) => s.setRegion);
1268
- useEffect4(() => {
1269
- if (value && newValue) {
1270
- if (value !== newValue && (value.x !== newValue.x || value.y !== newValue.y || value.width !== newValue.width || value.height !== newValue.height)) {
1271
- setRegion(id, newValue || null);
1272
- }
1273
- } else {
1274
- setRegion(id, newValue || null);
1275
- }
1276
- }, [value]);
1277
- useEffect4(() => {
1278
- return () => setRegion(id, null);
1279
- }, []);
1280
- }
1281
- function useHoverHighlightImageResource(id) {
1282
- const highlight = useHighlightedImageResource((s) => s.highlight);
1283
- const clear = useHighlightedImageResource((s) => s.clearHighlight);
1284
- useEffect4(() => {
1285
- return () => {
1286
- if (id) {
1287
- clear(id);
1288
- }
1289
- };
1290
- }, [clear, id]);
1291
- return useMemo6(() => {
1292
- return {
1293
- onMouseEnter() {
1294
- if (id) {
1295
- highlight(id);
1296
- }
1297
- },
1298
- onMouseLeave() {
1299
- if (id) {
1300
- clear(id);
1301
- }
1302
- }
1303
- };
1304
- }, [id, highlight, clear]);
1305
- }
1653
+ // src/BaseCreator/BaseCreator.tsx
1654
+ import { Suspense, memo as memo3, useEffect as useEffect8, useMemo as useMemo12, useRef as useRef3, useState as useState5 } from "react";
1655
+ import { useVault as useVault4 } from "react-iiif-vault";
1306
1656
 
1307
1657
  // src/Layout/Layout.context.tsx
1308
- import { createContext as createContext7, useContext as useContext7, useMemo as useMemo7 } from "react";
1309
- var LayoutActionsReactContext = createContext7(null);
1310
- var LayoutStateReactContext = createContext7(null);
1658
+ import { createContext as createContext9, useContext as useContext9, useMemo as useMemo7 } from "react";
1659
+ var LayoutActionsReactContext = createContext9(null);
1660
+ var LayoutStateReactContext = createContext9(null);
1311
1661
  function useLayoutState() {
1312
- return useContext7(LayoutStateReactContext);
1662
+ return useContext9(LayoutStateReactContext);
1313
1663
  }
1314
1664
  function useLayoutActions() {
1315
- return useContext7(LayoutActionsReactContext);
1665
+ return useContext9(LayoutActionsReactContext);
1316
1666
  }
1317
1667
  function useAvailableLayouts() {
1318
1668
  const app = useApp();
@@ -1321,22 +1671,22 @@ function useAvailableLayouts() {
1321
1671
  function useLayoutProvider() {
1322
1672
  const app = useApp();
1323
1673
  const layout = app.layout;
1324
- const actions = useContext7(LayoutActionsReactContext);
1325
- const state = useContext7(LayoutStateReactContext);
1674
+ const actions = useContext9(LayoutActionsReactContext);
1675
+ const state = useContext9(LayoutStateReactContext);
1326
1676
  return useMemo7(() => {
1327
1677
  return { actions, state, ...layout };
1328
1678
  }, [app, state]);
1329
1679
  }
1330
1680
 
1331
1681
  // src/Layout/components/ModularPanel.tsx
1332
- import styled8 from "styled-components";
1682
+ import styled6 from "styled-components";
1333
1683
 
1334
1684
  // ../ui/icons/StarIcon.tsx
1335
- import { jsx as jsx12, jsxs as jsxs5 } from "react/jsx-runtime";
1685
+ import { jsx as jsx14, jsxs as jsxs5 } from "react/jsx-runtime";
1336
1686
  var StarIcon = (props) => /* @__PURE__ */ jsxs5("svg", { xmlns: "http://www.w3.org/2000/svg", height: "1em", width: "1em", viewBox: "0 0 24 24", ...props, children: [
1337
- /* @__PURE__ */ jsx12("path", { d: "M0 0h24v24H0z", fill: "none" }),
1338
- /* @__PURE__ */ jsx12("path", { d: "M0 0h24v24H0z", fill: "none" }),
1339
- /* @__PURE__ */ jsx12(
1687
+ /* @__PURE__ */ jsx14("path", { d: "M0 0h24v24H0z", fill: "none" }),
1688
+ /* @__PURE__ */ jsx14("path", { d: "M0 0h24v24H0z", fill: "none" }),
1689
+ /* @__PURE__ */ jsx14(
1340
1690
  "path",
1341
1691
  {
1342
1692
  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",
@@ -1346,15 +1696,15 @@ var StarIcon = (props) => /* @__PURE__ */ jsxs5("svg", { xmlns: "http://www.w3.o
1346
1696
  ] });
1347
1697
 
1348
1698
  // ../ui/icons/BackIcon.tsx
1349
- import { jsx as jsx13, jsxs as jsxs6 } from "react/jsx-runtime";
1699
+ import { jsx as jsx15, jsxs as jsxs6 } from "react/jsx-runtime";
1350
1700
  var BackIcon = ({ style }) => /* @__PURE__ */ jsxs6("svg", { xmlns: "http://www.w3.org/2000/svg", height: "1rem", viewBox: "0 0 24 24", width: "1rem", fill: "#000000", style, children: [
1351
- /* @__PURE__ */ jsx13("path", { d: "M0 0h24v24H0z", fill: "none" }),
1352
- /* @__PURE__ */ jsx13("path", { d: "M20 11H7.83l5.59-5.59L12 4l-8 8 8 8 1.41-1.41L7.83 13H20v-2z" })
1701
+ /* @__PURE__ */ jsx15("path", { d: "M0 0h24v24H0z", fill: "none" }),
1702
+ /* @__PURE__ */ jsx15("path", { d: "M20 11H7.83l5.59-5.59L12 4l-8 8 8 8 1.41-1.41L7.83 13H20v-2z" })
1353
1703
  ] });
1354
1704
 
1355
1705
  // src/Layout/components/ModularPanel.tsx
1356
1706
  import { ErrorBoundary } from "react-error-boundary";
1357
- import { createContext as createContext8, useCallback as useCallback3, useContext as useContext8, useEffect as useEffect5, useMemo as useMemo8, useRef as useRef2, useState as useState4 } from "react";
1707
+ import { createContext as createContext10, useCallback as useCallback3, useContext as useContext10, useEffect as useEffect5, useMemo as useMemo8, useRef as useRef2, useState as useState4 } from "react";
1358
1708
 
1359
1709
  // ../ui/atoms/PaddedSidebarContainer.tsx
1360
1710
  import styled4 from "styled-components";
@@ -1365,70 +1715,16 @@ var PaddedSidebarContainer = styled4.div`
1365
1715
  overflow: visible;
1366
1716
  `;
1367
1717
 
1368
- // ../ui/madoc/components/callouts/ErrorMessage.tsx
1369
- import styled6 from "styled-components";
1370
-
1371
- // ../ui/madoc/components/callouts/BaseMessage.tsx
1372
- import styled5, { css as css2 } from "styled-components";
1373
- var BaseMessage = styled5.div`
1374
- background: #000;
1375
- color: #fff;
1376
- width: 100%;
1377
- padding: 0.5em 1em;
1378
- line-height: 1.9em;
1379
- display: flex;
1380
-
1381
- a {
1382
- color: #fff;
1383
- }
1384
-
1385
- svg {
1386
- fill: #fff;
1387
- margin: 0 0.5em;
1388
- vertical-align: text-bottom;
1389
- }
1390
-
1391
- ${(props) => props.$small && css2`
1392
- font-size: 0.75em;
1393
- padding: 0.25em 0.5em;
1394
- line-height: 1.6em;
1395
- `}
1396
-
1397
- ${(props) => props.$wide && css2`
1398
- margin-left: -2em;
1399
- margin-right: -2em;
1400
- width: auto;
1401
- svg {
1402
- height: 0.8em;
1403
- vertical-align: baseline;
1404
- }
1405
- `}
1406
-
1407
- ${(props) => props.$margin && css2`
1408
- margin-bottom: 1em;
1409
- `}
1410
-
1411
- ${(props) => props.$banner && css2`
1412
- border-radius: 5px;
1413
- box-shadow: 0 3px 15px 0 rgb(0 0 0 / 16%);
1414
- `}
1415
- `;
1416
-
1417
- // ../ui/madoc/components/callouts/ErrorMessage.tsx
1418
- var ErrorMessage = styled6(BaseMessage)`
1419
- background: #c74158;
1420
- color: #fff;
1421
- `;
1422
-
1423
1718
  // src/Layout/components/PanelError.tsx
1719
+ import { ErrorMessage } from "@manifest-editor/components";
1424
1720
  import { useState as useState3 } from "react";
1425
- import { jsx as jsx14, jsxs as jsxs7 } from "react/jsx-runtime";
1721
+ import { jsx as jsx16, jsxs as jsxs7 } from "react/jsx-runtime";
1426
1722
  function PanelError(props) {
1427
1723
  let error = props.error.toString();
1428
1724
  const [isFixing, setIsFixing] = useState3(false);
1429
1725
  return /* @__PURE__ */ jsxs7(PaddedSidebarContainer, { children: [
1430
- /* @__PURE__ */ jsx14(ErrorMessage, { $margin: true, children: error }),
1431
- /* @__PURE__ */ jsx14(CalltoButton, { onClick: props.resetErrorBoundary, children: "Try again" })
1726
+ /* @__PURE__ */ jsx16(ErrorMessage, { className: "mb-2", children: error }),
1727
+ /* @__PURE__ */ jsx16(CalltoButton, { onClick: props.resetErrorBoundary, children: "Try again" })
1432
1728
  ] });
1433
1729
  }
1434
1730
 
@@ -1455,12 +1751,12 @@ function renderHelper(htmlOrReact) {
1455
1751
  import { ReactVaultContext } from "react-iiif-vault";
1456
1752
 
1457
1753
  // ../ui/atoms/Dropdown.tsx
1458
- import styled7, { css as css3 } from "styled-components";
1459
- var Dropdown = styled7.div`
1754
+ import styled5, { css as css2 } from "styled-components";
1755
+ var Dropdown = styled5.div`
1460
1756
  position: relative;
1461
1757
  display: inline-block;
1462
1758
  `;
1463
- var DropdownContent = styled7.div`
1759
+ var DropdownContent = styled5.div`
1464
1760
  display: flex;
1465
1761
  flex-direction: column;
1466
1762
  position: absolute;
@@ -1476,7 +1772,7 @@ var DropdownContent = styled7.div`
1476
1772
  }
1477
1773
  }
1478
1774
  `;
1479
- var DropdownItem = styled7.button`
1775
+ var DropdownItem = styled5.button`
1480
1776
  padding: 0 ${(props) => props.theme.padding.small || "0.5rem"};
1481
1777
  color: ${(props) => props.theme.color.main || "none"};
1482
1778
  background-color: ${(props) => props.theme.color.white || "white"};
@@ -1495,7 +1791,7 @@ var DropdownItem = styled7.button`
1495
1791
  background-color: ${(props) => props.theme.color.lightgrey || "lightgrey"};
1496
1792
  }
1497
1793
 
1498
- ${(props) => props.$active && css3`
1794
+ ${(props) => props.$active && css2`
1499
1795
  background: #b84c74;
1500
1796
  color: #fff;
1501
1797
  &:hover {
@@ -1504,7 +1800,7 @@ var DropdownItem = styled7.button`
1504
1800
  }
1505
1801
  `}
1506
1802
  `;
1507
- var DropdownMenu = styled7.div`
1803
+ var DropdownMenu = styled5.div`
1508
1804
  display: none;
1509
1805
  flex-direction: column;
1510
1806
  position: absolute;
@@ -1528,18 +1824,18 @@ var DropdownMenu = styled7.div`
1528
1824
  }
1529
1825
  }
1530
1826
 
1531
- ${(props) => props.$open && css3`
1827
+ ${(props) => props.$open && css2`
1532
1828
  display: flex;
1533
1829
  `}
1534
1830
  `;
1535
- var DropdownLabel = styled7.div`
1831
+ var DropdownLabel = styled5.div`
1536
1832
  color: #999;
1537
1833
  text-transform: uppercase;
1538
1834
  font-weight: 600;
1539
1835
  padding: 0.7em;
1540
1836
  font-size: 0.875em;
1541
1837
  `;
1542
- var DropdownDivider = styled7.div`
1838
+ var DropdownDivider = styled5.div`
1543
1839
  height: 1px;
1544
1840
  margin: 0 0.5em;
1545
1841
  background: #eee;
@@ -1552,12 +1848,12 @@ import useDropdownMenu2 from "react-accessible-dropdown-menu-hook";
1552
1848
  var OverrideScrollbar = "ModularPanel_OverrideScrollbar";
1553
1849
 
1554
1850
  // src/Layout/components/ModularPanel.tsx
1555
- import { jsx as jsx15, jsxs as jsxs8 } from "react/jsx-runtime";
1556
- var LayoutTitleReactContext = createContext8(null);
1851
+ import { jsx as jsx17, jsxs as jsxs8 } from "react/jsx-runtime";
1852
+ var LayoutTitleReactContext = createContext10(null);
1557
1853
  function useSetCustomTitle() {
1558
- return useContext8(LayoutTitleReactContext);
1854
+ return useContext10(LayoutTitleReactContext);
1559
1855
  }
1560
- var ModularPanelWrapper = styled8.div`
1856
+ var ModularPanelWrapper = styled6.div`
1561
1857
  display: flex;
1562
1858
  flex-direction: column;
1563
1859
  position: relative;
@@ -1610,7 +1906,7 @@ var ModularPanelWrapper = styled8.div`
1610
1906
  transform: translateX(100%);
1611
1907
  }
1612
1908
  `;
1613
- var ModularPanelHeader = styled8.div`
1909
+ var ModularPanelHeader = styled6.div`
1614
1910
  background: #fff;
1615
1911
  display: flex;
1616
1912
  height: 2.8em;
@@ -1633,7 +1929,7 @@ var ModularPanelHeader = styled8.div`
1633
1929
  box-shadow: inset 0 -5px 10px 0 rgba(255, 255, 255, 0.5);
1634
1930
  }
1635
1931
  `;
1636
- var ModulePanelButton = styled8.button`
1932
+ var ModulePanelButton = styled6.button`
1637
1933
  border: none;
1638
1934
  background: transparent;
1639
1935
  padding: 0 0.4em;
@@ -1646,17 +1942,17 @@ var ModulePanelButton = styled8.button`
1646
1942
  font-size: 1.2em;
1647
1943
  }
1648
1944
  `;
1649
- var ModulePanelSpacer = styled8.div`
1945
+ var ModulePanelSpacer = styled6.div`
1650
1946
  flex: 1 1 0px;
1651
1947
  `;
1652
- var ModularPanelLabel = styled8.h2`
1948
+ var ModularPanelLabel = styled6.h2`
1653
1949
  font-size: 0.875em;
1654
1950
  flex: 1 1 0px;
1655
1951
  padding-left: 1em;
1656
1952
  text-align: center;
1657
1953
  align-self: center;
1658
1954
  `;
1659
- var ModularPanelContent = styled8.div`
1955
+ var ModularPanelContent = styled6.div`
1660
1956
  flex: 1 1 0px;
1661
1957
  display: flex;
1662
1958
 
@@ -1680,7 +1976,7 @@ function ModularPanel({
1680
1976
  style,
1681
1977
  noHeader
1682
1978
  }) {
1683
- const vault = useContext8(ReactVaultContext) || null;
1979
+ const vault = useContext10(ReactVaultContext) || null;
1684
1980
  const [didError, setDidError] = useState4(false);
1685
1981
  const appState = useAppState();
1686
1982
  const layout = useLayoutProvider();
@@ -1727,16 +2023,16 @@ function ModularPanel({
1727
2023
  if (!panel || !state.current) {
1728
2024
  return null;
1729
2025
  }
1730
- const backButton = panel.backAction || state.stack.length ? /* @__PURE__ */ jsx15(ModulePanelButton, { onClick: backAction, children: /* @__PURE__ */ jsx15(BackIcon, {}) }) : null;
1731
- const closeButton = /* @__PURE__ */ jsx15(ModulePanelButton, { onClick: close || actions.close, children: /* @__PURE__ */ jsx15(CloseIcon, {}) });
1732
- return /* @__PURE__ */ jsx15(LayoutTitleReactContext.Provider, { value: _setCustomTitle, children: /* @__PURE__ */ jsxs8(ModularPanelWrapper, { "data-state": transition, "data-flipped": isLeft, style, "data-header": !noHeader, children: [
2026
+ const backButton = panel.backAction || state.stack.length ? /* @__PURE__ */ jsx17(ModulePanelButton, { onClick: backAction, children: /* @__PURE__ */ jsx17(BackIcon, {}) }) : null;
2027
+ const closeButton = /* @__PURE__ */ jsx17(ModulePanelButton, { onClick: close || actions.close, children: /* @__PURE__ */ jsx17(CloseIcon, {}) });
2028
+ return /* @__PURE__ */ jsx17(LayoutTitleReactContext.Provider, { value: _setCustomTitle, children: /* @__PURE__ */ jsxs8(ModularPanelWrapper, { "data-state": transition, "data-flipped": isLeft, style, "data-header": !noHeader, children: [
1733
2029
  noHeader ? null : /* @__PURE__ */ jsxs8(ModularPanelHeader, { "data-tabs": !!tabs, "data-error": didError, children: [
1734
2030
  /* @__PURE__ */ jsxs8(Dropdown, { style: { display: "flex", height: "100%" }, children: [
1735
2031
  panel.renderBackAction ? panel.renderBackAction({ backAction, fallback: backButton }) : backButton,
1736
2032
  switchablePanels.length ? /* @__PURE__ */ jsxs8(DropdownMenu, { $open: isOpen, style: { left: "0.5em" }, children: [
1737
- /* @__PURE__ */ jsx15(DropdownLabel, { children: "All panels" }),
1738
- /* @__PURE__ */ jsx15(DropdownDivider, {}),
1739
- switchablePanels.map((newPanel, i) => /* @__PURE__ */ jsx15(
2033
+ /* @__PURE__ */ jsx17(DropdownLabel, { children: "All panels" }),
2034
+ /* @__PURE__ */ jsx17(DropdownDivider, {}),
2035
+ switchablePanels.map((newPanel, i) => /* @__PURE__ */ jsx17(
1740
2036
  DropdownItem,
1741
2037
  {
1742
2038
  ...itemProps[i],
@@ -1748,11 +2044,11 @@ function ModularPanel({
1748
2044
  ))
1749
2045
  ] }) : null
1750
2046
  ] }),
1751
- customTitle ? /* @__PURE__ */ jsx15(ModularPanelLabel, { children: customTitle }) : hideHeader ? /* @__PURE__ */ jsx15(ModulePanelSpacer, {}) : /* @__PURE__ */ jsx15(ModularPanelLabel, { children: panel.label }),
1752
- pinnable ? state.pinned ? /* @__PURE__ */ jsx15(ModulePanelButton, { onClick: pinActions.unpin, children: /* @__PURE__ */ jsx15(StarIcon, { fill: "orange" }) }) : /* @__PURE__ */ jsx15(ModulePanelButton, { onClick: () => pinActions.pin({ id: panel.id, state: state.state }), children: /* @__PURE__ */ jsx15(StarIcon, { fill: "#ddd" }) }) : null,
2047
+ customTitle ? /* @__PURE__ */ jsx17(ModularPanelLabel, { children: customTitle }) : hideHeader ? /* @__PURE__ */ jsx17(ModulePanelSpacer, {}) : /* @__PURE__ */ jsx17(ModularPanelLabel, { children: panel.label }),
2048
+ pinnable ? state.pinned ? /* @__PURE__ */ jsx17(ModulePanelButton, { onClick: pinActions.unpin, children: /* @__PURE__ */ jsx17(StarIcon, { fill: "orange" }) }) : /* @__PURE__ */ jsx17(ModulePanelButton, { onClick: () => pinActions.pin({ id: panel.id, state: state.state }), children: /* @__PURE__ */ jsx17(StarIcon, { fill: "#ddd" }) }) : null,
1753
2049
  panel.renderCloseAction ? panel.renderCloseAction({ closeAction: close || actions.close, fallback: closeButton }) : closeButton
1754
2050
  ] }),
1755
- /* @__PURE__ */ jsx15(ModularPanelContent, { className: OverrideScrollbar, children: /* @__PURE__ */ jsx15(
2051
+ /* @__PURE__ */ jsx17(ModularPanelContent, { className: OverrideScrollbar, children: /* @__PURE__ */ jsx17(
1756
2052
  ErrorBoundary,
1757
2053
  {
1758
2054
  onError: () => setDidError(true),
@@ -1767,18 +2063,193 @@ function ModularPanel({
1767
2063
  )
1768
2064
  )
1769
2065
  }
1770
- ) })
1771
- ] }) });
2066
+ ) })
2067
+ ] }) });
2068
+ }
2069
+
2070
+ // src/highlighted-image-resources.ts
2071
+ import { create } from "zustand";
2072
+ import { useEffect as useEffect6, useMemo as useMemo9 } from "react";
2073
+
2074
+ // src/helpers.ts
2075
+ import { toRef } from "@iiif/parser";
2076
+ async function getManifestNomalized(id) {
2077
+ let responseData = void 0;
2078
+ try {
2079
+ await fetch(id).then((response) => {
2080
+ return response.json().catch((err) => {
2081
+ console.error(`'${err}' happened!`);
2082
+ });
2083
+ }).then((data) => {
2084
+ responseData = { ...data };
2085
+ });
2086
+ } catch (error) {
2087
+ console.log(error);
2088
+ }
2089
+ return responseData;
2090
+ }
2091
+ function createActionIdentity(type, property, parent) {
2092
+ return `create_${type}_${property}_${toRef(parent)?.type || "unknown"}`;
2093
+ }
2094
+ function createDownload(data, fileName, fileType = "text/json") {
2095
+ const blob = data instanceof Blob ? data : new Blob([data], { type: fileType });
2096
+ const a = document.createElement("a");
2097
+ a.download = fileName;
2098
+ a.href = window.URL.createObjectURL(blob);
2099
+ const clickEvt = new MouseEvent("click", {
2100
+ view: window,
2101
+ bubbles: true,
2102
+ cancelable: true
2103
+ });
2104
+ a.dispatchEvent(clickEvt);
2105
+ a.remove();
2106
+ }
2107
+ async function copyToClipboard(json) {
2108
+ return navigator.clipboard.writeText(
2109
+ typeof json === "string" ? json : JSON.stringify(json, null, 2)
2110
+ );
2111
+ }
2112
+ function randomId() {
2113
+ return `${Math.random().toString(36).substr(2)}-${Date.now().toString(36)}`;
2114
+ }
2115
+ function mapApp(input, map) {
2116
+ const { default: metadata, ...props } = input;
2117
+ const app = {
2118
+ metadata,
2119
+ layout: {
2120
+ leftPanels: [],
2121
+ rightPanels: [],
2122
+ centerPanels: [],
2123
+ ...props
2124
+ }
2125
+ };
2126
+ return map ? map(app) : app;
2127
+ }
2128
+ function extendApp(app, metadata, extensions) {
2129
+ return {
2130
+ ...app,
2131
+ metadata,
2132
+ config: {
2133
+ ...app.config || {},
2134
+ ...extensions.config || {}
2135
+ },
2136
+ layout: {
2137
+ ...app.layout,
2138
+ leftPanels: [
2139
+ ...(app.layout.leftPanels || []).filter((panel) => {
2140
+ if (extensions?.leftPanelIds) {
2141
+ return extensions.leftPanelIds.includes(panel.id);
2142
+ }
2143
+ return true;
2144
+ }),
2145
+ ...extensions?.leftPanels || []
2146
+ ],
2147
+ annotations: [
2148
+ ...extensions?.annotations || [],
2149
+ ...app.layout.annotations || []
2150
+ ],
2151
+ canvasEditors: [
2152
+ ...extensions?.canvasEditors || [],
2153
+ ...app.layout.canvasEditors || []
2154
+ ],
2155
+ creators: [
2156
+ ...extensions?.creators || [],
2157
+ ...app.layout.creators || []
2158
+ ],
2159
+ editors: [
2160
+ //
2161
+ ...extensions?.editors || [],
2162
+ ...app.layout.editors || []
2163
+ ],
2164
+ rightPanels: [
2165
+ ...app.layout.rightPanels || [],
2166
+ ...extensions?.rightPanels || []
2167
+ ],
2168
+ centerPanels: [
2169
+ ...app.layout.centerPanels || [],
2170
+ ...extensions?.centerPanels || []
2171
+ ],
2172
+ modals: [
2173
+ ...app.layout.modals || [],
2174
+ ...extensions?.modalPanels || []
2175
+ ]
2176
+ }
2177
+ };
2178
+ }
2179
+
2180
+ // src/highlighted-image-resources.ts
2181
+ var useHighlightedImageResource = create((set) => ({
2182
+ regions: {},
2183
+ resources: [],
2184
+ setRegion: (id, region) => {
2185
+ set((ex) => ({ ...ex.regions, regions: { [id]: region || null } }));
2186
+ },
2187
+ setHighlight: (id) => {
2188
+ set({ resources: Array.isArray(id) ? id : [id] });
2189
+ },
2190
+ highlight: (id) => {
2191
+ set((s) => {
2192
+ if (s.resources.indexOf(id) !== -1) {
2193
+ return s;
2194
+ }
2195
+ return { resources: [...s.resources, id] };
2196
+ });
2197
+ },
2198
+ clearHighlight: (id) => {
2199
+ set((s) => ({ resources: s.resources.filter((item) => item !== id) }));
2200
+ }
2201
+ }));
2202
+ function useTemporaryHighlight(newValue) {
2203
+ const id = useMemo9(() => randomId(), []);
2204
+ const value = useHighlightedImageResource((s) => s.regions[id]);
2205
+ const setRegion = useHighlightedImageResource((s) => s.setRegion);
2206
+ useEffect6(() => {
2207
+ if (value && newValue) {
2208
+ if (value !== newValue && (value.x !== newValue.x || value.y !== newValue.y || value.width !== newValue.width || value.height !== newValue.height)) {
2209
+ setRegion(id, newValue || null);
2210
+ }
2211
+ } else {
2212
+ setRegion(id, newValue || null);
2213
+ }
2214
+ }, [value]);
2215
+ useEffect6(() => {
2216
+ return () => setRegion(id, null);
2217
+ }, []);
2218
+ }
2219
+ function useHoverHighlightImageResource(id) {
2220
+ const highlight = useHighlightedImageResource((s) => s.highlight);
2221
+ const clear = useHighlightedImageResource((s) => s.clearHighlight);
2222
+ useEffect6(() => {
2223
+ return () => {
2224
+ if (id) {
2225
+ clear(id);
2226
+ }
2227
+ };
2228
+ }, [clear, id]);
2229
+ return useMemo9(() => {
2230
+ return {
2231
+ onMouseEnter() {
2232
+ if (id) {
2233
+ highlight(id);
2234
+ }
2235
+ },
2236
+ onMouseLeave() {
2237
+ if (id) {
2238
+ clear(id);
2239
+ }
2240
+ }
2241
+ };
2242
+ }, [id, highlight, clear]);
1772
2243
  }
1773
2244
 
1774
2245
  // src/BaseCreator/BaseCreator.hooks.tsx
1775
- import { Creator } from "@manifest-editor/creator-api";
1776
- import { useCallback as useCallback4, useMemo as useMemo10 } from "react";
1777
- import { useVault as useVault3 } from "react-iiif-vault";
1778
2246
  import { toRef as toRef2 } from "@iiif/parser";
2247
+ import { Creator, matchBasedOnResource } from "@manifest-editor/creator-api";
2248
+ import { useCallback as useCallback4, useMemo as useMemo11 } from "react";
2249
+ import { useVault as useVault3 } from "react-iiif-vault";
1779
2250
 
1780
2251
  // src/PreviewVault/PreviewVault.tsx
1781
- import { createContext as createContext9, useContext as useContext9, useEffect as useEffect6, useMemo as useMemo9 } from "react";
2252
+ import { createContext as createContext11, useContext as useContext11, useEffect as useEffect7, useMemo as useMemo10 } from "react";
1782
2253
  import { Vault as Vault2 } from "@iiif/helpers/vault";
1783
2254
  import { VaultProvider as VaultProvider2 } from "react-iiif-vault";
1784
2255
 
@@ -1874,12 +2345,12 @@ function createPreviewVault(homepageCollectionId = "vault://homepage-collection.
1874
2345
  }
1875
2346
 
1876
2347
  // src/PreviewVault/PreviewVault.tsx
1877
- import { jsx as jsx16 } from "react/jsx-runtime";
2348
+ import { jsx as jsx18 } from "react/jsx-runtime";
1878
2349
  function usePreviewVault() {
1879
- return useContext9(PreviewVaultReactContext);
2350
+ return useContext11(PreviewVaultReactContext);
1880
2351
  }
1881
- var PreviewVaultReactContext = createContext9(new Vault2());
1882
- var PreviewVaultAddHistory = createContext9({
2352
+ var PreviewVaultReactContext = createContext11(new Vault2());
2353
+ var PreviewVaultAddHistory = createContext11({
1883
2354
  addHistory: (id, type) => {
1884
2355
  },
1885
2356
  clearHistory: () => {
@@ -1887,112 +2358,121 @@ var PreviewVaultAddHistory = createContext9({
1887
2358
  });
1888
2359
  var HOMEPAGE_COLLECTION = "manifest-editor://homepage-collection.json";
1889
2360
  function usePreviewHistory() {
1890
- return useContext9(PreviewVaultAddHistory);
2361
+ return useContext11(PreviewVaultAddHistory);
1891
2362
  }
1892
2363
  function PreviewVaultContext(props) {
1893
- const { vault, unsubscribe, addHistory, clearHistory } = useMemo9(() => {
2364
+ const { vault, unsubscribe, addHistory, clearHistory } = useMemo10(() => {
1894
2365
  return createPreviewVault(HOMEPAGE_COLLECTION);
1895
2366
  }, []);
1896
- useEffect6(() => {
2367
+ useEffect7(() => {
1897
2368
  return unsubscribe;
1898
2369
  }, []);
1899
- return /* @__PURE__ */ jsx16(PreviewVaultAddHistory.Provider, { value: { addHistory, clearHistory }, children: /* @__PURE__ */ jsx16(PreviewVaultReactContext.Provider, { value: vault, children: props.children }) });
2370
+ return /* @__PURE__ */ jsx18(PreviewVaultAddHistory.Provider, { value: { addHistory, clearHistory }, children: /* @__PURE__ */ jsx18(PreviewVaultReactContext.Provider, { value: vault, children: props.children }) });
1900
2371
  }
1901
2372
  function PreviewVaultBoundary({ children }) {
1902
2373
  const vault = usePreviewVault();
1903
- return /* @__PURE__ */ jsx16(VaultProvider2, { vault, children });
2374
+ return /* @__PURE__ */ jsx18(VaultProvider2, { vault, children });
1904
2375
  }
1905
2376
 
1906
2377
  // src/BaseCreator/BaseCreator.hooks.tsx
1907
- function matchBasedOnResource(resource, list, options) {
1908
- const supported = [];
1909
- if (list.length === 0) {
1910
- return [];
1911
- }
1912
- const parent = toRef2(resource.parent);
1913
- const property = resource.property;
1914
- for (const def of list) {
1915
- if (parent && property) {
1916
- if (def.supports.parentTypes) {
1917
- if (!def.supports.parentTypes.includes(parent.type)) {
1918
- continue;
1919
- }
1920
- }
1921
- if (def.supports.parentFields) {
1922
- if (!def.supports.parentFields.includes(property)) {
1923
- continue;
1924
- }
1925
- }
1926
- if (def.supports.parentFieldMap) {
1927
- const type = def.supports.parentFieldMap[parent.type];
1928
- if (!type || !type.includes(property)) {
1929
- continue;
1930
- }
1931
- }
1932
- if (def.supports.disallowPainting && resource.isPainting) {
1933
- continue;
1934
- }
1935
- if (def.supports.custom) {
1936
- const isValid = def.supports.custom({ property, resource: parent, atIndex: resource.index }, options.vault);
1937
- if (!isValid) {
1938
- continue;
1939
- }
1940
- }
1941
- if (!def.supports.initialData && Object.keys(resource.initialData || {}).length !== 0) {
1942
- continue;
1943
- }
1944
- if (def.resourceType !== resource.type) {
1945
- if (!(def.additionalTypes || []).includes(resource.type)) {
1946
- continue;
1947
- }
1948
- }
1949
- supported.push(def);
1950
- }
1951
- }
1952
- return supported;
1953
- }
1954
2378
  function useCreator(parent, property, type, target, options) {
1955
2379
  const vault = useVault3();
1956
2380
  const app = useApp();
1957
2381
  const { create: create2, edit } = useLayoutActions();
1958
- const supported = useMemo10(
1959
- () => matchBasedOnResource({ type, parent, index: 0, property }, app.layout.creators || [], { vault }),
2382
+ const supported = useMemo11(
2383
+ () => matchBasedOnResource(
2384
+ { type, parent, index: 0, property },
2385
+ app.layout.creators || [],
2386
+ { vault }
2387
+ ),
1960
2388
  [parent, property, app.layout.creators, type, vault]
1961
2389
  );
1962
2390
  const canCreate = parent && supported.length !== 0;
1963
2391
  const wrappedCreate = useCallback4(
1964
2392
  (index, initialData) => {
1965
2393
  if (parent) {
1966
- create2({ type, parent: toRef2(parent), property, index, target, initialData, ...options || {} });
2394
+ create2({
2395
+ type,
2396
+ parent: toRef2(parent),
2397
+ property,
2398
+ index,
2399
+ target,
2400
+ initialData,
2401
+ ...options || {}
2402
+ });
2403
+ }
2404
+ },
2405
+ [create2, parent, property, type, options, target]
2406
+ );
2407
+ const wrappedFilteredCreate = useCallback4(
2408
+ (filter, index, initialData) => {
2409
+ if (parent) {
2410
+ create2({
2411
+ type,
2412
+ filter,
2413
+ parent: toRef2(parent),
2414
+ property,
2415
+ index,
2416
+ target,
2417
+ initialData,
2418
+ ...options || {}
2419
+ });
1967
2420
  }
1968
2421
  },
1969
- [create2, parent, property, type]
2422
+ [create2, parent, property, type, options, target]
1970
2423
  );
1971
2424
  const wrappedEdit = useCallback4(
1972
2425
  (resource, index) => {
1973
- edit(resource, parent ? { parent: toRef2(parent), property, index } : void 0);
2426
+ edit(
2427
+ resource,
2428
+ parent ? { parent: toRef2(parent), property, index } : void 0
2429
+ );
1974
2430
  },
1975
2431
  [edit, parent, property]
1976
2432
  );
1977
- const buttonProps = useMemo10(() => {
2433
+ const wrappedCreator = useCallback4(
2434
+ (initialCreator, initialData) => {
2435
+ if (parent) {
2436
+ create2({
2437
+ type,
2438
+ initialCreator,
2439
+ parent: toRef2(parent),
2440
+ property,
2441
+ target,
2442
+ initialData,
2443
+ ...options || {}
2444
+ });
2445
+ }
2446
+ },
2447
+ [type, property, parent, target, create2, options]
2448
+ );
2449
+ const buttonProps = useMemo11(() => {
1978
2450
  return {
1979
2451
  "data-action-id": createActionIdentity(type, property, parent)
1980
2452
  };
1981
- }, []);
1982
- return [canCreate, { create: wrappedCreate, edit: wrappedEdit, buttonProps }];
2453
+ }, [type, property, parent]);
2454
+ return [
2455
+ canCreate,
2456
+ {
2457
+ create: wrappedCreate,
2458
+ edit: wrappedEdit,
2459
+ createFiltered: wrappedFilteredCreate,
2460
+ creator: wrappedCreator,
2461
+ buttonProps
2462
+ }
2463
+ ];
1983
2464
  }
1984
2465
  function useInlineCreator() {
1985
2466
  const vault = useVault3();
1986
2467
  const previewVault = usePreviewVault();
1987
2468
  const app = useApp();
1988
- return useMemo10(() => {
2469
+ return useMemo11(() => {
1989
2470
  return new Creator(vault, app.layout.creators || [], previewVault);
1990
2471
  }, [app.layout.creators, vault]);
1991
2472
  }
1992
2473
 
1993
2474
  // src/BaseCreator/BaseCreator.tsx
1994
- import { CreatorGrid } from "@manifest-editor/components";
1995
- import { Fragment as Fragment2, jsx as jsx17, jsxs as jsxs9 } from "react/jsx-runtime";
2475
+ import { Fragment as Fragment2, jsx as jsx19, jsxs as jsxs9 } from "react/jsx-runtime";
1996
2476
  var RenderCreator = memo3(function RenderCreator2(props) {
1997
2477
  const vault = useVault4();
1998
2478
  const { edit, modal } = useLayoutActions();
@@ -2028,12 +2508,12 @@ var RenderCreator = memo3(function RenderCreator2(props) {
2028
2508
  const validate = async () => {
2029
2509
  return true;
2030
2510
  };
2031
- useEffect7(() => {
2511
+ useEffect8(() => {
2032
2512
  if (!props.creator.render && !isCreating) {
2033
2513
  runCreate({});
2034
2514
  }
2035
2515
  }, [props.creator]);
2036
- useEffect7(() => {
2516
+ useEffect8(() => {
2037
2517
  if (isCreating) {
2038
2518
  modal.popStack();
2039
2519
  modal.close();
@@ -2043,9 +2523,9 @@ var RenderCreator = memo3(function RenderCreator2(props) {
2043
2523
  return null;
2044
2524
  }
2045
2525
  if (!props.creator.render) {
2046
- return /* @__PURE__ */ jsx17("div", { children: /* @__PURE__ */ jsx17(Button, { onClick: () => runCreate({}), children: "Create" }) });
2526
+ return /* @__PURE__ */ jsx19("div", { children: /* @__PURE__ */ jsx19(Button, { onClick: () => runCreate({}), children: "Create" }) });
2047
2527
  }
2048
- return /* @__PURE__ */ jsx17(Fragment2, { children: /* @__PURE__ */ jsx17(Suspense, { fallback: /* @__PURE__ */ jsx17(Spinner, {}), children: props.creator.render({
2528
+ return /* @__PURE__ */ jsx19(Fragment2, { children: /* @__PURE__ */ jsx19(Suspense, { fallback: /* @__PURE__ */ jsx19(Spinner, {}), children: props.creator.render({
2049
2529
  vault,
2050
2530
  runCreate,
2051
2531
  validate,
@@ -2055,31 +2535,39 @@ var RenderCreator = memo3(function RenderCreator2(props) {
2055
2535
  function BaseCreator(props) {
2056
2536
  const app = useApp();
2057
2537
  const vault = useVault4();
2058
- const [currentId, setCurrentId] = useState5("");
2538
+ const [currentId, setCurrentId] = useState5(
2539
+ props.resource.initialCreator || ""
2540
+ );
2059
2541
  const set = useSetCustomTitle();
2060
- const supported = useMemo11(
2061
- () => matchBasedOnResource(props.resource, app.layout.creators || [], { vault }),
2542
+ const supported = useMemo12(
2543
+ () => matchBasedOnResource2(props.resource, app.layout.creators || [], {
2544
+ vault
2545
+ }),
2062
2546
  [props.resource, app.layout.creators, vault]
2063
2547
  );
2064
2548
  if (supported.length === 1 && !currentId) {
2065
2549
  setCurrentId(supported[0].id);
2066
2550
  }
2067
2551
  const current = supported.find((t) => t.id === currentId);
2068
- useEffect7(() => {
2552
+ useEffect8(() => {
2069
2553
  if (current) {
2070
- set && set(current.label);
2554
+ set?.(current.label);
2071
2555
  }
2072
2556
  });
2073
2557
  if (supported.length === 0) {
2074
- return /* @__PURE__ */ jsx17("div", { children: "Not currently supported" });
2558
+ return /* @__PURE__ */ jsx19("div", { children: "Not currently supported" });
2075
2559
  }
2076
2560
  if (current) {
2561
+ const shouldHideModal = current.hiddenModal;
2562
+ if (shouldHideModal) {
2563
+ return /* @__PURE__ */ jsx19(RenderCreator, { creator: current, resource: props.resource });
2564
+ }
2077
2565
  return /* @__PURE__ */ jsxs9("div", { children: [
2078
- /* @__PURE__ */ jsx17("div", { className: "bg-me-gray-100 p-2", children: /* @__PURE__ */ jsx17(Button, { onClick: () => setCurrentId(""), children: "Back" }) }),
2079
- /* @__PURE__ */ jsx17("div", { className: "p-2 py-6", children: /* @__PURE__ */ jsx17(RenderCreator, { creator: current, resource: props.resource }) })
2566
+ /* @__PURE__ */ jsx19("div", { className: "bg-me-gray-100 p-2", children: /* @__PURE__ */ jsx19(Button, { onClick: () => setCurrentId(""), children: "Back" }) }),
2567
+ /* @__PURE__ */ jsx19("div", { className: "p-2 py-6", children: /* @__PURE__ */ jsx19(RenderCreator, { creator: current, resource: props.resource }) })
2080
2568
  ] });
2081
2569
  }
2082
- return /* @__PURE__ */ jsx17(
2570
+ return /* @__PURE__ */ jsx19(
2083
2571
  CreatorGrid,
2084
2572
  {
2085
2573
  label: "Select a type",
@@ -2095,22 +2583,23 @@ function BaseCreator(props) {
2095
2583
  }
2096
2584
 
2097
2585
  // src/BaseCreator/index.tsx
2098
- import { jsx as jsx18 } from "react/jsx-runtime";
2586
+ import { jsx as jsx20 } from "react/jsx-runtime";
2099
2587
  var baseCreator = {
2100
2588
  id: "@manifest-editor/creator",
2101
2589
  label: "Add content",
2102
2590
  options: { hideHeader: true, tabs: false },
2103
2591
  render(state) {
2104
- return /* @__PURE__ */ jsx18(BaseCreator, { resource: state });
2592
+ return /* @__PURE__ */ jsx20(BaseCreator, { resource: state });
2105
2593
  }
2106
2594
  };
2107
2595
 
2108
2596
  // src/BaseEditor/BaseEditor.tsx
2109
- import { useMemo as useMemo13, useEffect as useEffect9 } from "react";
2110
- import { useVault as useVault6 } from "react-iiif-vault";
2597
+ import { SidebarTabs } from "@manifest-editor/components";
2598
+ import { useContext as useContext13, useEffect as useEffect10, useMemo as useMemo14 } from "react";
2599
+ import { ResourceReactContext, useVault as useVault6 } from "react-iiif-vault";
2111
2600
 
2112
2601
  // src/EditingStack/EditingStack.tsx
2113
- import { createContext as createContext10, useCallback as useCallback5, useContext as useContext10, useEffect as useEffect8, useMemo as useMemo12, useReducer as useReducer2 } from "react";
2602
+ import { createContext as createContext12, useCallback as useCallback5, useContext as useContext12, useEffect as useEffect9, useMemo as useMemo13, useReducer as useReducer2 } from "react";
2114
2603
 
2115
2604
  // src/EditingStack/EditingStack.reducer.ts
2116
2605
  import { toRef as toRef4 } from "@iiif/parser";
@@ -2207,10 +2696,10 @@ function filterStack(newStackWithDuplicates, current) {
2207
2696
  import { EditorInstance } from "@manifest-editor/editor-api";
2208
2697
  import { useResourceContext, useVault as useVault5 } from "react-iiif-vault";
2209
2698
  import { toRef as toRef5 } from "@iiif/parser";
2210
- import { jsx as jsx19 } from "react/jsx-runtime";
2699
+ import { jsx as jsx21 } from "react/jsx-runtime";
2211
2700
  var defaultState = { stack: [], current: null, create: null };
2212
- var EditingStackContext = createContext10(defaultState);
2213
- var EditingStackActionsContext = createContext10({
2701
+ var EditingStackContext = createContext12(defaultState);
2702
+ var EditingStackActionsContext = createContext12({
2214
2703
  edit() {
2215
2704
  },
2216
2705
  close() {
@@ -2225,29 +2714,29 @@ var EditingStackActionsContext = createContext10({
2225
2714
  }
2226
2715
  });
2227
2716
  function useEditingStack() {
2228
- return useContext10(EditingStackActionsContext);
2717
+ return useContext12(EditingStackActionsContext);
2229
2718
  }
2230
2719
  function useEditingResource() {
2231
- return useContext10(EditingStackContext).current;
2720
+ return useContext12(EditingStackContext).current;
2232
2721
  }
2233
2722
  function useEditingResourceStack() {
2234
- return useContext10(EditingStackContext).stack;
2723
+ return useContext12(EditingStackContext).stack;
2235
2724
  }
2236
2725
  function useCreatingResource() {
2237
- return useContext10(EditingStackContext).create;
2726
+ return useContext12(EditingStackContext).create;
2238
2727
  }
2239
2728
  function useManifestEditor() {
2240
2729
  const { manifest } = useResourceContext();
2241
2730
  const vault = useVault5();
2242
2731
  const [key, invalidate] = useReducer2((i) => i + 1, 0);
2243
2732
  invariant(manifest, "Manifest not found");
2244
- const editor = useMemo12(() => {
2733
+ const editor = useMemo13(() => {
2245
2734
  return new EditorInstance({
2246
2735
  reference: { id: manifest, type: "Manifest" },
2247
2736
  vault
2248
2737
  });
2249
2738
  }, [manifest, vault]);
2250
- useEffect8(() => {
2739
+ useEffect9(() => {
2251
2740
  return editor.observe.start(invalidate);
2252
2741
  }, [editor]);
2253
2742
  editor.observe.key = `${key}`;
@@ -2259,13 +2748,13 @@ function useCollectionEditor() {
2259
2748
  const vault = useVault5();
2260
2749
  const [key, invalidate] = useReducer2((i) => i + 1, 0);
2261
2750
  invariant(collection, "Collection not found");
2262
- const editor = useMemo12(() => {
2751
+ const editor = useMemo13(() => {
2263
2752
  return new EditorInstance({
2264
2753
  reference: { id: collection, type: "Collection" },
2265
2754
  vault
2266
2755
  });
2267
2756
  }, [collection, vault]);
2268
- useEffect8(() => {
2757
+ useEffect9(() => {
2269
2758
  return editor.observe.start(invalidate);
2270
2759
  }, [editor]);
2271
2760
  editor.observe.key = `${key}`;
@@ -2276,14 +2765,14 @@ function useGenericEditor(ref, ctx = {}) {
2276
2765
  const vault = useVault5();
2277
2766
  const [key, invalidate] = useReducer2((i) => i + 1, 0);
2278
2767
  invariant(ref, "Resource not found");
2279
- const editor = useMemo12(() => {
2768
+ const editor = useMemo13(() => {
2280
2769
  return new EditorInstance({
2281
2770
  reference: toRef5(ref),
2282
2771
  vault,
2283
2772
  context: { resource: ref, parent: ctx.parent, index: ctx.index, parentProperty: ctx.parentProperty }
2284
2773
  });
2285
2774
  }, [ref, vault]);
2286
- useEffect8(() => {
2775
+ useEffect9(() => {
2287
2776
  return editor.observe.start(invalidate);
2288
2777
  }, [editor]);
2289
2778
  editor.observe.key = `${key}`;
@@ -2300,13 +2789,13 @@ function useEditor() {
2300
2789
  const vault = useVault5();
2301
2790
  const [key, invalidate] = useReducer2((i) => i + 1, 0);
2302
2791
  invariant(resource, "No resource selected");
2303
- const editor = useMemo12(() => {
2792
+ const editor = useMemo13(() => {
2304
2793
  return new EditorInstance({
2305
2794
  reference: resource.resource.source || resource.resource,
2306
2795
  vault
2307
2796
  });
2308
2797
  }, [resource, vault]);
2309
- useEffect8(() => {
2798
+ useEffect9(() => {
2310
2799
  return editor.observe.start(invalidate);
2311
2800
  }, [editor]);
2312
2801
  editor.observe.key = `${key}`;
@@ -2319,7 +2808,7 @@ function EditingStack(props) {
2319
2808
  const dispatch = useCallback5((action) => {
2320
2809
  _dispatch(action);
2321
2810
  }, []);
2322
- useEffect8(() => {
2811
+ useEffect9(() => {
2323
2812
  return vault.on("@iiif/REMOVE_REFERENCE", (payload) => {
2324
2813
  const action = payload.action;
2325
2814
  const parent = { id: action.payload.id, type: action.payload.type };
@@ -2343,21 +2832,20 @@ function EditingStack(props) {
2343
2832
  dispatch({ type: "create", payload: { resource: null } });
2344
2833
  };
2345
2834
  }, []);
2346
- const actions = useMemo12(() => {
2835
+ const actions = useMemo13(() => {
2347
2836
  return { edit, updateCurrent, close, back, create: create2 };
2348
2837
  }, []);
2349
2838
  const { instanceId } = useAppInstance();
2350
- return /* @__PURE__ */ jsx19(EditingStackActionsContext.Provider, { value: actions, children: /* @__PURE__ */ jsx19(EditingStackContext.Provider, { value: state, children: props.children }) }, instanceId);
2839
+ return /* @__PURE__ */ jsx21(EditingStackActionsContext.Provider, { value: actions, children: /* @__PURE__ */ jsx21(EditingStackContext.Provider, { value: state, children: props.children }) }, instanceId);
2351
2840
  }
2352
2841
 
2353
2842
  // src/BaseEditor/BaseEditor.tsx
2354
- import { SidebarTabs } from "@manifest-editor/components";
2355
- import { jsx as jsx20 } from "react/jsx-runtime";
2843
+ import { jsx as jsx22 } from "react/jsx-runtime";
2356
2844
  function BaseEditorBackButton({ fallback, backAction }) {
2357
2845
  const stack = useEditingResourceStack();
2358
2846
  const { back } = useEditingStack();
2359
2847
  if (stack.length) {
2360
- return /* @__PURE__ */ jsx20(ModulePanelButton, { onClick: back, children: /* @__PURE__ */ jsx20(BackIcon, {}) });
2848
+ return /* @__PURE__ */ jsx22(ModulePanelButton, { onClick: back, children: /* @__PURE__ */ jsx22(BackIcon, {}) });
2361
2849
  }
2362
2850
  return fallback;
2363
2851
  }
@@ -2365,20 +2853,22 @@ function BaseEditorCloseButton({ closeAction, fallback }) {
2365
2853
  const stack = useEditingResourceStack();
2366
2854
  const current = useEditingResource();
2367
2855
  if (current || stack.length) {
2368
- return /* @__PURE__ */ jsx20(
2856
+ return /* @__PURE__ */ jsx22(
2369
2857
  ModulePanelButton,
2370
2858
  {
2371
2859
  onClick: () => {
2372
2860
  closeAction();
2373
2861
  },
2374
- children: /* @__PURE__ */ jsx20(CloseIcon, {})
2862
+ children: /* @__PURE__ */ jsx22(CloseIcon, {})
2375
2863
  }
2376
2864
  );
2377
2865
  }
2378
2866
  return fallback;
2379
2867
  }
2380
2868
  function editBasedOnResource(resource, list, options, config) {
2381
- const filteredList = list.filter((l) => l.resourceType === resource.resource.source.type);
2869
+ const filteredList = list.filter(
2870
+ (l) => l.resourceType === resource.resource.source.type
2871
+ );
2382
2872
  if (filteredList.length === 0) {
2383
2873
  return null;
2384
2874
  }
@@ -2426,74 +2916,124 @@ function editBasedOnResource(resource, list, options, config) {
2426
2916
  }
2427
2917
  return null;
2428
2918
  }
2429
- function BaseEditor({ currentTab = void 0 }) {
2919
+ function BaseEditor({
2920
+ currentTab = void 0
2921
+ }) {
2430
2922
  const resource = useEditingResource();
2923
+ const currentResourceContext = useContext13(ResourceReactContext);
2431
2924
  const app = useApp();
2432
2925
  const vault = useVault6();
2433
2926
  const { change } = useLayoutActions();
2434
2927
  const set = useSetCustomTitle();
2435
2928
  const { editorConfig } = useConfig();
2436
2929
  const resourceConfig = (resource?.resource.source?.type ? editorConfig[resource?.resource.source?.type] : editorConfig.All) || {};
2437
- const match = useMemo13(() => {
2930
+ const newResourceContext = useMemo14(() => {
2931
+ const newCtx = { ...currentResourceContext };
2932
+ const id = resource?.resource.source.id;
2933
+ const type = resource?.resource.source.type;
2934
+ const mapping = {
2935
+ Collection: "collection",
2936
+ Manifest: "manifest",
2937
+ Range: "range",
2938
+ Canvas: "canvas",
2939
+ Annotation: "annotation",
2940
+ AnnotationPage: "annotationPage"
2941
+ };
2942
+ if (type && mapping[type]) {
2943
+ newCtx[mapping[type]] = id;
2944
+ }
2945
+ return newCtx;
2946
+ }, [resource, currentResourceContext]);
2947
+ function wrap(children) {
2948
+ if (!resource) {
2949
+ return children;
2950
+ }
2951
+ return /* @__PURE__ */ jsx22(ResourceReactContext.Provider, { value: newResourceContext, children });
2952
+ }
2953
+ const match = useMemo14(() => {
2438
2954
  if (!resource) {
2439
2955
  return null;
2440
2956
  }
2441
2957
  const editors = app.layout.editors || [];
2442
2958
  const resources = app.layout.resources || [];
2443
- const mappedResources = resources.map((resource2) => {
2444
- if (typeof resource2 === "string") {
2445
- return {
2446
- id: "@default/" + resource2,
2447
- label: resource2,
2448
- resourceType: resource2,
2449
- auto: true,
2450
- editors: editors.filter((e) => e.supports.resourceTypes.includes(resource2))
2451
- };
2959
+ const mappedResources = resources.map(
2960
+ (resource2) => {
2961
+ if (typeof resource2 === "string") {
2962
+ return {
2963
+ id: "@default/" + resource2,
2964
+ label: resource2,
2965
+ resourceType: resource2,
2966
+ auto: true,
2967
+ editors: editors.filter(
2968
+ (e) => e.supports.resourceTypes.includes(resource2)
2969
+ )
2970
+ };
2971
+ }
2972
+ return resource2;
2452
2973
  }
2453
- return resource2;
2454
- });
2455
- return editBasedOnResource(resource, mappedResources, { edit: true, vault }, resourceConfig);
2974
+ );
2975
+ return editBasedOnResource(
2976
+ resource,
2977
+ mappedResources,
2978
+ { edit: true, vault },
2979
+ resourceConfig
2980
+ );
2456
2981
  }, [resource, app]);
2457
- useEffect9(() => {
2982
+ useEffect10(() => {
2458
2983
  set(match?.label || "");
2459
2984
  });
2985
+ useEffect10(() => {
2986
+ const availableKeys = match?.editors.map((editor, key) => editor.id + key) || [];
2987
+ const currentKey = availableKeys.find((key) => key === currentTab);
2988
+ if (!currentKey) {
2989
+ change("@manifest-editor/editor", { currentTab: availableKeys[0] });
2990
+ }
2991
+ }, [match?.editors, currentTab, change]);
2460
2992
  if (!resource || !match) {
2461
2993
  return null;
2462
2994
  }
2463
2995
  if (resourceConfig.singleTab) {
2464
- const first = (match?.editors || []).find((editor) => editor.id === resourceConfig.singleTab);
2996
+ const first = (match?.editors || []).find(
2997
+ (editor) => editor.id === resourceConfig.singleTab
2998
+ );
2465
2999
  if (first) {
2466
- return /* @__PURE__ */ jsx20("div", { className: "w-full", children: first.component(resourceConfig) });
3000
+ return wrap(
3001
+ /* @__PURE__ */ jsx22("div", { className: "w-full", children: first.component(resourceConfig) })
3002
+ );
2467
3003
  }
2468
3004
  }
2469
- return /* @__PURE__ */ jsx20(
2470
- SidebarTabs,
2471
- {
2472
- menuId: resource.resource.source.id,
2473
- menu: (match?.editors || []).map((editor, key) => {
2474
- return {
2475
- id: editor.id + key,
2476
- label: editor.label,
2477
- renderComponent: () => editor.component(resourceConfig)
2478
- };
2479
- }),
2480
- selectedKey: currentTab,
2481
- onSelectionChange: (p) => change("@manifest-editor/editor", { currentTab: p })
2482
- },
2483
- resource.resource.source?.id
3005
+ return wrap(
3006
+ /* @__PURE__ */ jsx22(
3007
+ SidebarTabs,
3008
+ {
3009
+ menuId: resource.resource.source.id,
3010
+ menu: (match?.editors || []).map((editor, key) => {
3011
+ return {
3012
+ id: editor.id + key,
3013
+ label: editor.label,
3014
+ renderComponent: () => editor.component(resourceConfig)
3015
+ };
3016
+ }),
3017
+ selectedKey: currentTab,
3018
+ onSelectionChange: (p) => {
3019
+ change("@manifest-editor/editor", { currentTab: p });
3020
+ }
3021
+ },
3022
+ resource.resource.source?.id
3023
+ )
2484
3024
  );
2485
3025
  }
2486
3026
 
2487
3027
  // src/BaseEditor/index.tsx
2488
- import { jsx as jsx21 } from "react/jsx-runtime";
3028
+ import { jsx as jsx23 } from "react/jsx-runtime";
2489
3029
  var baseEditor = {
2490
3030
  id: "@manifest-editor/editor",
2491
3031
  label: "Editor",
2492
3032
  options: { hideHeader: true, tabs: true, minWidth: 400 },
2493
- renderBackAction: ({ backAction, fallback }) => /* @__PURE__ */ jsx21(BaseEditorBackButton, { backAction, fallback }),
2494
- renderCloseAction: ({ closeAction, fallback }) => /* @__PURE__ */ jsx21(BaseEditorCloseButton, { closeAction, fallback }),
3033
+ renderBackAction: ({ backAction, fallback }) => /* @__PURE__ */ jsx23(BaseEditorBackButton, { backAction, fallback }),
3034
+ renderCloseAction: ({ closeAction, fallback }) => /* @__PURE__ */ jsx23(BaseEditorCloseButton, { closeAction, fallback }),
2495
3035
  render({ currentTab }) {
2496
- return /* @__PURE__ */ jsx21(BaseEditor, { currentTab });
3036
+ return /* @__PURE__ */ jsx23(BaseEditor, { currentTab });
2497
3037
  }
2498
3038
  };
2499
3039
 
@@ -2501,7 +3041,7 @@ var baseEditor = {
2501
3041
  import { Sidebar, SidebarHeader, SidebarContent, Form, ActionButton } from "@manifest-editor/components";
2502
3042
 
2503
3043
  // src/hooks/use-decay-state.ts
2504
- import { useMemo as useMemo14, useRef as useRef4, useState as useState6 } from "react";
3044
+ import { useMemo as useMemo15, useRef as useRef4, useState as useState6 } from "react";
2505
3045
  function useDecayState(time) {
2506
3046
  const [active, _setActive] = useState6(false);
2507
3047
  const lastTimeout = useRef4();
@@ -2526,11 +3066,11 @@ function useDecayState(time) {
2526
3066
  }
2527
3067
  _setActive(true);
2528
3068
  }
2529
- return useMemo14(() => [active, { set, clear }], [active]);
3069
+ return useMemo15(() => [active, { set, clear }], [active]);
2530
3070
  }
2531
3071
 
2532
3072
  // src/ConfigContext/ConfigEditor.tsx
2533
- import { jsx as jsx22, jsxs as jsxs10 } from "react/jsx-runtime";
3073
+ import { jsx as jsx24, jsxs as jsxs10 } from "react/jsx-runtime";
2534
3074
  function ConfigEditor() {
2535
3075
  const previews = usePreviewContext();
2536
3076
  const config = useConfig();
@@ -2558,12 +3098,12 @@ function ConfigEditor() {
2558
3098
  saveState.clear();
2559
3099
  }
2560
3100
  return /* @__PURE__ */ jsxs10(Sidebar, { children: [
2561
- /* @__PURE__ */ jsx22(SidebarHeader, { title: "Workspace configuration" }),
2562
- isSaved ? /* @__PURE__ */ jsx22("div", { className: "bg-me-primary-500 text-white p-3 text-sm", children: "Changes saved" }) : null,
2563
- /* @__PURE__ */ jsx22(SidebarContent, { className: "p-4", children: /* @__PURE__ */ jsxs10(Form.Form, { onSubmit, className: "flex flex-col gap-3", children: [
3101
+ /* @__PURE__ */ jsx24(SidebarHeader, { title: "Workspace configuration" }),
3102
+ isSaved ? /* @__PURE__ */ jsx24("div", { className: "bg-me-primary-500 text-white p-3 text-sm", children: "Changes saved" }) : null,
3103
+ /* @__PURE__ */ jsx24(SidebarContent, { className: "p-4", children: /* @__PURE__ */ jsxs10(Form.Form, { onSubmit, className: "flex flex-col gap-3", children: [
2564
3104
  /* @__PURE__ */ jsxs10(Form.InputContainer, { children: [
2565
- /* @__PURE__ */ jsx22(Form.Label, { htmlFor: "defaultLanguage", children: "Default Language" }),
2566
- /* @__PURE__ */ jsx22(
3105
+ /* @__PURE__ */ jsx24(Form.Label, { htmlFor: "defaultLanguage", children: "Default Language" }),
3106
+ /* @__PURE__ */ jsx24(
2567
3107
  Form.Input,
2568
3108
  {
2569
3109
  type: "text",
@@ -2574,8 +3114,8 @@ function ConfigEditor() {
2574
3114
  )
2575
3115
  ] }),
2576
3116
  /* @__PURE__ */ jsxs10(Form.InputContainer, { children: [
2577
- /* @__PURE__ */ jsx22(Form.Label, { htmlFor: "availableLanguages", children: "Available Languages" }),
2578
- /* @__PURE__ */ jsx22(
3117
+ /* @__PURE__ */ jsx24(Form.Label, { htmlFor: "availableLanguages", children: "Available Languages" }),
3118
+ /* @__PURE__ */ jsx24(
2579
3119
  Form.Input,
2580
3120
  {
2581
3121
  type: "text",
@@ -2586,7 +3126,7 @@ function ConfigEditor() {
2586
3126
  )
2587
3127
  ] }),
2588
3128
  /* @__PURE__ */ jsxs10(Form.InputContainer, { horizontal: true, className: "my-3", children: [
2589
- /* @__PURE__ */ jsx22(
3129
+ /* @__PURE__ */ jsx24(
2590
3130
  Form.Input,
2591
3131
  {
2592
3132
  type: "checkbox",
@@ -2595,10 +3135,22 @@ function ConfigEditor() {
2595
3135
  defaultChecked: config.i18n?.advancedLanguageMode || false
2596
3136
  }
2597
3137
  ),
2598
- /* @__PURE__ */ jsx22(Form.Label, { htmlFor: "advancedLanguageMode", children: "Advanced Language Mode" })
3138
+ /* @__PURE__ */ jsx24(Form.Label, { htmlFor: "advancedLanguageMode", children: "Advanced Language Mode" })
2599
3139
  ] }),
2600
3140
  /* @__PURE__ */ jsxs10(Form.InputContainer, { horizontal: true, className: "my-3", children: [
2601
- /* @__PURE__ */ jsx22(
3141
+ /* @__PURE__ */ jsx24(
3142
+ Form.Input,
3143
+ {
3144
+ type: "checkbox",
3145
+ name: "textGranularityEnabled",
3146
+ id: "textGranularityEnabled",
3147
+ defaultChecked: config.i18n?.textGranularityEnabled || false
3148
+ }
3149
+ ),
3150
+ /* @__PURE__ */ jsx24(Form.Label, { htmlFor: "textGranularityEnabled", children: "Enable text granularity" })
3151
+ ] }),
3152
+ /* @__PURE__ */ jsxs10(Form.InputContainer, { horizontal: true, className: "my-3", children: [
3153
+ /* @__PURE__ */ jsx24(
2602
3154
  Form.Input,
2603
3155
  {
2604
3156
  type: "checkbox",
@@ -2607,16 +3159,16 @@ function ConfigEditor() {
2607
3159
  defaultChecked: config.export?.version === 2
2608
3160
  }
2609
3161
  ),
2610
- /* @__PURE__ */ jsx22(Form.Label, { htmlFor: "isVersion2", children: "Export Presentation 2 Manifests" })
3162
+ /* @__PURE__ */ jsx24(Form.Label, { htmlFor: "isVersion2", children: "Export Presentation 2 Manifests" })
2611
3163
  ] }),
2612
3164
  /* @__PURE__ */ jsxs10(Form.InputContainer, { children: [
2613
- /* @__PURE__ */ jsx22(Form.Label, { htmlFor: "defaultPreview", children: "Default preview" }),
2614
- /* @__PURE__ */ jsx22("div", { children: previews.configs.map((preview, key) => {
3165
+ /* @__PURE__ */ jsx24(Form.Label, { htmlFor: "defaultPreview", children: "Default preview" }),
3166
+ /* @__PURE__ */ jsx24("div", { children: previews.configs.map((preview, key) => {
2615
3167
  if (preview.type === "iiif-preview-service") {
2616
3168
  return null;
2617
3169
  }
2618
3170
  return /* @__PURE__ */ jsxs10(Form.InputContainer, { horizontal: true, children: [
2619
- /* @__PURE__ */ jsx22(
3171
+ /* @__PURE__ */ jsx24(
2620
3172
  Form.Input,
2621
3173
  {
2622
3174
  type: "radio",
@@ -2626,17 +3178,25 @@ function ConfigEditor() {
2626
3178
  defaultChecked: !config.defaultPreview ? key === 0 : config.defaultPreview === preview.id
2627
3179
  }
2628
3180
  ),
2629
- /* @__PURE__ */ jsx22("label", { htmlFor: preview.id, children: preview.label })
3181
+ /* @__PURE__ */ jsx24("label", { htmlFor: preview.id, children: preview.label })
2630
3182
  ] }, preview.id);
2631
3183
  }) })
2632
3184
  ] }),
2633
- /* @__PURE__ */ jsx22("div", { className: "mt-5", children: /* @__PURE__ */ jsx22(ActionButton, { type: "submit", children: "Save changes" }) })
3185
+ /* @__PURE__ */ jsx24(
3186
+ "a",
3187
+ {
3188
+ className: "text-sm text-me-primary-500 hover:underline hover:text-me-primary-600",
3189
+ href: window.location.pathname.includes("/exhibition") ? window.location.pathname.replace("/exhibition", "") || "/" : `${window.location.pathname}/exhibition`,
3190
+ children: window.location.pathname.includes("/exhibition") ? "Return to Manifest Editor" : "Go to Exhibition Editor"
3191
+ }
3192
+ ),
3193
+ /* @__PURE__ */ jsx24("div", { className: "mt-5", children: /* @__PURE__ */ jsx24(ActionButton, { type: "submit", children: "Save changes" }) })
2634
3194
  ] }) })
2635
3195
  ] });
2636
3196
  }
2637
3197
 
2638
3198
  // src/ExportPanel/ExportPanel.tsx
2639
- import { useMemo as useMemo16 } from "react";
3199
+ import { useMemo as useMemo17 } from "react";
2640
3200
  import { useManifest, useVault as useVault7 } from "react-iiif-vault";
2641
3201
 
2642
3202
  // ../ui/ui/CenterPanelContainer/CenterPanelContainer.module.css
@@ -2648,37 +3208,37 @@ var CenterPanelContainer_default = {
2648
3208
  };
2649
3209
 
2650
3210
  // ../ui/ui/CenterPanelContainer/CenterPanelContainer.tsx
2651
- import { jsx as jsx23, jsxs as jsxs11 } from "react/jsx-runtime";
3211
+ import { jsx as jsx25, jsxs as jsxs11 } from "react/jsx-runtime";
2652
3212
  function CenterPanelContainer(props) {
2653
3213
  return /* @__PURE__ */ jsxs11("div", { className: CenterPanelContainer_default.CenterPanelContainer, children: [
2654
3214
  props.title || props.close ? /* @__PURE__ */ jsxs11("div", { className: CenterPanelContainer_default.CenterPanelHeader, children: [
2655
- props.title ? /* @__PURE__ */ jsx23("h2", { className: CenterPanelContainer_default.CenterPanelTitle, children: props.title }) : null,
2656
- props.close ? /* @__PURE__ */ jsx23(Button, { className: CenterPanelContainer_default.CenterPanelClose, onClick: props.close, children: /* @__PURE__ */ jsx23(CloseIcon, {}) }) : null
3215
+ props.title ? /* @__PURE__ */ jsx25("h2", { className: CenterPanelContainer_default.CenterPanelTitle, children: props.title }) : null,
3216
+ props.close ? /* @__PURE__ */ jsx25(Button, { className: CenterPanelContainer_default.CenterPanelClose, onClick: props.close, children: /* @__PURE__ */ jsx25(CloseIcon, {}) }) : null
2657
3217
  ] }) : null,
2658
3218
  props.children
2659
3219
  ] });
2660
3220
  }
2661
3221
 
2662
3222
  // ../ui/atoms/Accordion.tsx
2663
- import styled9 from "styled-components";
3223
+ import styled7 from "styled-components";
2664
3224
  import {
2665
3225
  createRef,
2666
3226
  forwardRef,
2667
- useEffect as useEffect10,
3227
+ useEffect as useEffect11,
2668
3228
  useImperativeHandle,
2669
- useMemo as useMemo15,
3229
+ useMemo as useMemo16,
2670
3230
  useRef as useRef5,
2671
3231
  useState as useState7
2672
3232
  } from "react";
2673
- import { jsx as jsx24, jsxs as jsxs12 } from "react/jsx-runtime";
2674
- var AccordionContainer = styled9.div`
3233
+ import { jsx as jsx26, jsxs as jsxs12 } from "react/jsx-runtime";
3234
+ var AccordionContainer = styled7.div`
2675
3235
  flex: 1;
2676
3236
  display: flex;
2677
3237
  width: 100%;
2678
3238
  flex-direction: column;
2679
3239
  position: relative;
2680
3240
  `;
2681
- var ItemRow = styled9.div`
3241
+ var ItemRow = styled7.div`
2682
3242
  background: #fff;
2683
3243
  position: relative;
2684
3244
  border-bottom: 1px solid #d0d0d0;
@@ -2697,12 +3257,12 @@ var ItemRow = styled9.div`
2697
3257
  //justify-content: center;
2698
3258
  }
2699
3259
  `;
2700
- var ItemDescription = styled9.p`
3260
+ var ItemDescription = styled7.p`
2701
3261
  font-size: 0.9em;
2702
3262
  color: #777;
2703
3263
  font-weight: 400;
2704
3264
  `;
2705
- var ItemLabel = styled9.button`
3265
+ var ItemLabel = styled7.button`
2706
3266
  color: inherit;
2707
3267
  text-rendering: geometricPrecision;
2708
3268
  border: none;
@@ -2745,7 +3305,7 @@ var ItemLabel = styled9.button`
2745
3305
  }
2746
3306
  }
2747
3307
  `;
2748
- var ItemCollapse = styled9.div`
3308
+ var ItemCollapse = styled7.div`
2749
3309
  font-size: 1.4em;
2750
3310
  padding-right: 0.3em;
2751
3311
  display: flex;
@@ -2755,7 +3315,7 @@ var ItemCollapse = styled9.div`
2755
3315
  font-size: 2em;
2756
3316
  }
2757
3317
  `;
2758
- var ItemIcon = styled9.div`
3318
+ var ItemIcon = styled7.div`
2759
3319
  width: 2em;
2760
3320
  align-items: center;
2761
3321
  //padding-top: 0.5em;
@@ -2769,12 +3329,12 @@ var ItemIcon = styled9.div`
2769
3329
  color: #999;
2770
3330
  }
2771
3331
  `;
2772
- var ItemBodyInner = styled9.div`
3332
+ var ItemBodyInner = styled7.div`
2773
3333
  min-height: 0;
2774
3334
  overflow: visible;
2775
3335
  display: flex;
2776
3336
  `;
2777
- var ItemBodyPadding = styled9.div`
3337
+ var ItemBodyPadding = styled7.div`
2778
3338
  min-height: 0;
2779
3339
  overflow: visible;
2780
3340
  flex: 1;
@@ -2788,7 +3348,7 @@ var ItemBodyPadding = styled9.div`
2788
3348
  overflow-y: auto;
2789
3349
  }
2790
3350
  `;
2791
- var ItemBody = styled9.section`
3351
+ var ItemBody = styled7.section`
2792
3352
  display: grid;
2793
3353
  grid-template-rows: 0fr;
2794
3354
  overflow: hidden;
@@ -2817,7 +3377,7 @@ var ItemBody = styled9.section`
2817
3377
  box-shadow: inset 0px 2px 0px 0 rgba(0, 0, 0, 0.1);
2818
3378
  }
2819
3379
  `;
2820
- var ItemHeading = styled9.div`
3380
+ var ItemHeading = styled7.div`
2821
3381
  position: sticky;
2822
3382
  display: flex;
2823
3383
  top: 0;
@@ -2857,7 +3417,7 @@ var ItemHeading = styled9.div`
2857
3417
  var noop = () => void 0;
2858
3418
  var keyIdIndex = 0;
2859
3419
  function useId() {
2860
- return useMemo15(() => keyIdIndex++, []);
3420
+ return useMemo16(() => keyIdIndex++, []);
2861
3421
  }
2862
3422
  function useAccordionItems(itemsLength, singleMode = false) {
2863
3423
  const [elRefs, setElRefs] = useState7([]);
@@ -2929,7 +3489,7 @@ function useAccordionItems(itemsLength, singleMode = false) {
2929
3489
  }
2930
3490
  }
2931
3491
  };
2932
- useEffect10(() => {
3492
+ useEffect11(() => {
2933
3493
  setElRefs(
2934
3494
  (elRefs_) => Array(itemsLength).fill(0).map((_, i) => elRefs_[i] || createRef())
2935
3495
  );
@@ -3027,14 +3587,14 @@ var AccordionItem = forwardRef(function AccordionItem2(props, ref) {
3027
3587
  };
3028
3588
  return /* @__PURE__ */ jsxs12(ItemRow, { "data-large": props.large, "data-open": open, children: [
3029
3589
  /* @__PURE__ */ jsxs12(ItemHeading, { "data-open": open, children: [
3030
- props.icon ? /* @__PURE__ */ jsx24(ItemIcon, { onClick: toggle, children: props.icon }) : null,
3590
+ props.icon ? /* @__PURE__ */ jsx26(ItemIcon, { onClick: toggle, children: props.icon }) : null,
3031
3591
  /* @__PURE__ */ jsxs12(ItemLabel, { ref: btn, onClick: toggle, "aria-expanded": open, "aria-controls": `accordion-${id}`, children: [
3032
3592
  props.label,
3033
- props.description ? /* @__PURE__ */ jsx24(ItemDescription, { children: props.description }) : null
3593
+ props.description ? /* @__PURE__ */ jsx26(ItemDescription, { children: props.description }) : null
3034
3594
  ] }),
3035
- /* @__PURE__ */ jsx24(ItemCollapse, { onClick: toggle, children: /* @__PURE__ */ jsx24(DownIcon, { width: "1em", height: "1em", rotate: open ? 0 : 180 }) })
3595
+ /* @__PURE__ */ jsx26(ItemCollapse, { onClick: toggle, children: /* @__PURE__ */ jsx26(DownIcon, { width: "1em", height: "1em", rotate: open ? 0 : 180 }) })
3036
3596
  ] }),
3037
- /* @__PURE__ */ jsx24(
3597
+ /* @__PURE__ */ jsx26(
3038
3598
  ItemBody,
3039
3599
  {
3040
3600
  "aria-labelledby": `accordion-${id}`,
@@ -3046,7 +3606,7 @@ var AccordionItem = forwardRef(function AccordionItem2(props, ref) {
3046
3606
  $initial: !open,
3047
3607
  "data-scrolled": scrolled,
3048
3608
  hidden: !open,
3049
- children: /* @__PURE__ */ jsx24(ItemBodyInner, { children: /* @__PURE__ */ jsx24(
3609
+ children: /* @__PURE__ */ jsx26(ItemBodyInner, { children: /* @__PURE__ */ jsx26(
3050
3610
  ItemBodyPadding,
3051
3611
  {
3052
3612
  "data-max-height": !!maxHeight,
@@ -3061,18 +3621,18 @@ var AccordionItem = forwardRef(function AccordionItem2(props, ref) {
3061
3621
  });
3062
3622
  function Accordion(props) {
3063
3623
  const { getItemProps, onKeyDown } = useAccordionItems(props.items.length, props.singleMode);
3064
- return /* @__PURE__ */ jsx24(AccordionContainer, { onKeyDown, children: props.items.map((item, key) => /* @__PURE__ */ jsx24(AccordionItem, { overflow: props.overflow, maxHeight: props.maxHeight, ...item, ...getItemProps(key), children: item.children }, key)) });
3624
+ return /* @__PURE__ */ jsx26(AccordionContainer, { onKeyDown, children: props.items.map((item, key) => /* @__PURE__ */ jsx26(AccordionItem, { overflow: props.overflow, maxHeight: props.maxHeight, ...item, ...getItemProps(key), children: item.children }, key)) });
3065
3625
  }
3066
3626
 
3067
3627
  // ../ui/icons/DownloadIcon.tsx
3068
- import { jsx as jsx25 } from "react/jsx-runtime";
3628
+ import { jsx as jsx27 } from "react/jsx-runtime";
3069
3629
  function DownloadIcon() {
3070
- return /* @__PURE__ */ jsx25("svg", { xmlns: "http://www.w3.org/2000/svg", height: "48", viewBox: "0 -960 960 960", width: "48", children: /* @__PURE__ */ jsx25("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" }) });
3630
+ return /* @__PURE__ */ jsx27("svg", { xmlns: "http://www.w3.org/2000/svg", height: "48", viewBox: "0 -960 960 960", width: "48", children: /* @__PURE__ */ jsx27("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" }) });
3071
3631
  }
3072
3632
 
3073
3633
  // ../ui/atoms/ButtonRow.tsx
3074
- import styled10 from "styled-components";
3075
- var ButtonRow = styled10.div`
3634
+ import styled8 from "styled-components";
3635
+ var ButtonRow = styled8.div`
3076
3636
  padding: 0.3em;
3077
3637
 
3078
3638
  display: flex;
@@ -3097,18 +3657,18 @@ var ButtonRow = styled10.div`
3097
3657
  `;
3098
3658
 
3099
3659
  // src/ExportPanel/ExportPanel.tsx
3100
- import { jsx as jsx26, jsxs as jsxs13 } from "react/jsx-runtime";
3660
+ import { jsx as jsx28, jsxs as jsxs13 } from "react/jsx-runtime";
3101
3661
  function ExportPanel(props) {
3102
3662
  const manifest = useManifest();
3103
3663
  const vault = useVault7();
3104
3664
  const actions = useLayoutActions();
3105
- const version3 = useMemo16(() => {
3665
+ const version3 = useMemo17(() => {
3106
3666
  return JSON.stringify(vault.toPresentation3(manifest), null, 2);
3107
3667
  }, [manifest, vault]);
3108
- const version2 = useMemo16(() => {
3668
+ const version2 = useMemo17(() => {
3109
3669
  return JSON.stringify(vault.toPresentation2(manifest), null, 2);
3110
3670
  }, [manifest, vault]);
3111
- return /* @__PURE__ */ jsx26(CenterPanelContainer, { title: "Export manifest", close: actions.centerPanel.popStack, children: /* @__PURE__ */ jsx26("div", { style: { flex: 1, overflowY: "auto" }, children: /* @__PURE__ */ jsx26(
3671
+ return /* @__PURE__ */ jsx28(CenterPanelContainer, { title: "Export manifest", close: actions.centerPanel.popStack, children: /* @__PURE__ */ jsx28("div", { style: { flex: 1, overflowY: "auto" }, children: /* @__PURE__ */ jsx28(
3112
3672
  Accordion,
3113
3673
  {
3114
3674
  items: [
@@ -3119,12 +3679,12 @@ function ExportPanel(props) {
3119
3679
  large: true,
3120
3680
  initialOpen: true,
3121
3681
  overflow: true,
3122
- icon: /* @__PURE__ */ jsx26(Button, { onClick: () => createDownload(version3, "manifest.json"), children: /* @__PURE__ */ jsx26(DownloadIcon, {}) }),
3682
+ icon: /* @__PURE__ */ jsx28(Button, { onClick: () => createDownload(version3, "manifest.json"), children: /* @__PURE__ */ jsx28(DownloadIcon, {}) }),
3123
3683
  children: /* @__PURE__ */ jsxs13("div", { style: { maxWidth: "100%" }, children: [
3124
- /* @__PURE__ */ jsx26("pre", { style: { whiteSpace: "pre-wrap" }, children: JSON.stringify(vault.toPresentation3(manifest), null, 2) }),
3684
+ /* @__PURE__ */ jsx28("pre", { style: { whiteSpace: "pre-wrap" }, children: JSON.stringify(vault.toPresentation3(manifest), null, 2) }),
3125
3685
  /* @__PURE__ */ jsxs13(ButtonRow, { "data-sticky": "true", children: [
3126
- /* @__PURE__ */ jsx26(Button, { onClick: () => copyToClipboard(version3), children: "Copy to clipboard" }),
3127
- /* @__PURE__ */ jsx26(Button, { onClick: () => createDownload(version3, "manifest.json"), children: "Download" })
3686
+ /* @__PURE__ */ jsx28(Button, { onClick: () => copyToClipboard(version3), children: "Copy to clipboard" }),
3687
+ /* @__PURE__ */ jsx28(Button, { onClick: () => createDownload(version3, "manifest.json"), children: "Download" })
3128
3688
  ] })
3129
3689
  ] })
3130
3690
  },
@@ -3133,12 +3693,12 @@ function ExportPanel(props) {
3133
3693
  description: 'Download this version by clicking the "Download" button.',
3134
3694
  maxHeight: 400,
3135
3695
  large: true,
3136
- icon: /* @__PURE__ */ jsx26(Button, { onClick: () => createDownload(version2, "manifest.json"), children: /* @__PURE__ */ jsx26(DownloadIcon, {}) }),
3696
+ icon: /* @__PURE__ */ jsx28(Button, { onClick: () => createDownload(version2, "manifest.json"), children: /* @__PURE__ */ jsx28(DownloadIcon, {}) }),
3137
3697
  children: /* @__PURE__ */ jsxs13("div", { style: { maxWidth: "100%" }, children: [
3138
- /* @__PURE__ */ jsx26("pre", { style: { whiteSpace: "pre-wrap" }, children: JSON.stringify(vault.toPresentation2(manifest), null, 2) }),
3698
+ /* @__PURE__ */ jsx28("pre", { style: { whiteSpace: "pre-wrap" }, children: JSON.stringify(vault.toPresentation2(manifest), null, 2) }),
3139
3699
  /* @__PURE__ */ jsxs13(ButtonRow, { "data-sticky": "true", children: [
3140
- /* @__PURE__ */ jsx26(Button, { onClick: () => copyToClipboard(version2), children: "Copy to clipboard" }),
3141
- /* @__PURE__ */ jsx26(Button, { onClick: () => createDownload(version2, "manifest.json"), children: "Download" })
3700
+ /* @__PURE__ */ jsx28(Button, { onClick: () => copyToClipboard(version2), children: "Copy to clipboard" }),
3701
+ /* @__PURE__ */ jsx28(Button, { onClick: () => createDownload(version2, "manifest.json"), children: "Download" })
3142
3702
  ] })
3143
3703
  ] })
3144
3704
  }
@@ -3147,6 +3707,9 @@ function ExportPanel(props) {
3147
3707
  ) }) });
3148
3708
  }
3149
3709
 
3710
+ // src/Layout/Layout.tsx
3711
+ import { Modal, PanelSideMenu as PanelSideMenu2 } from "@manifest-editor/components";
3712
+
3150
3713
  // ../ui/ui/GhostBlocks/GhostBlocks.module.css
3151
3714
  var GhostBlocks_default = {
3152
3715
  ghostLoadingBlock: "GhostBlocks_ghostLoadingBlock",
@@ -3155,40 +3718,60 @@ var GhostBlocks_default = {
3155
3718
  };
3156
3719
 
3157
3720
  // ../ui/ui/GhostBlocks/GhostBlocks.tsx
3158
- import { Fragment as Fragment3, jsx as jsx27, jsxs as jsxs14 } from "react/jsx-runtime";
3721
+ import { Fragment as Fragment3, jsx as jsx29, jsxs as jsxs14 } from "react/jsx-runtime";
3159
3722
  function GhostBlocks() {
3160
3723
  return /* @__PURE__ */ jsxs14(Fragment3, { children: [
3161
- /* @__PURE__ */ jsx27("div", { "data-header": "true", className: GhostBlocks_default.ghostLoadingBlock }),
3724
+ /* @__PURE__ */ jsx29("div", { "data-header": "true", className: GhostBlocks_default.ghostLoadingBlock }),
3162
3725
  /* @__PURE__ */ jsxs14("div", { className: GhostBlocks_default.ghostBlockList, children: [
3163
- /* @__PURE__ */ jsx27("div", { className: GhostBlocks_default.ghostLoadingBlock }),
3164
- /* @__PURE__ */ jsx27("div", { className: GhostBlocks_default.ghostLoadingBlock }),
3165
- /* @__PURE__ */ jsx27("div", { className: GhostBlocks_default.ghostLoadingBlock }),
3166
- /* @__PURE__ */ jsx27("div", { className: GhostBlocks_default.ghostLoadingBlock })
3726
+ /* @__PURE__ */ jsx29("div", { className: GhostBlocks_default.ghostLoadingBlock }),
3727
+ /* @__PURE__ */ jsx29("div", { className: GhostBlocks_default.ghostLoadingBlock }),
3728
+ /* @__PURE__ */ jsx29("div", { className: GhostBlocks_default.ghostLoadingBlock }),
3729
+ /* @__PURE__ */ jsx29("div", { className: GhostBlocks_default.ghostLoadingBlock })
3167
3730
  ] })
3168
3731
  ] });
3169
3732
  }
3170
3733
 
3171
3734
  // src/Layout/Layout.tsx
3172
- import { memo as memo4, useContext as useContext11, useLayoutEffect as useLayoutEffect3 } from "react";
3735
+ import { memo as memo4, useContext as useContext14, useLayoutEffect as useLayoutEffect3 } from "react";
3173
3736
  import { ReactVaultContext as ReactVaultContext2 } from "react-iiif-vault";
3174
3737
  import { Transition } from "react-transition-group";
3175
3738
  import equal from "shallowequal";
3176
3739
 
3740
+ // src/hooks/use-match-media.ts
3741
+ import { useState as useState8, useLayoutEffect } from "react";
3742
+ function useMatchMedia(queries, defaultValues = []) {
3743
+ const initialValues = defaultValues.length ? defaultValues : Array(queries.length).fill(false);
3744
+ if (typeof window === "undefined")
3745
+ return initialValues;
3746
+ const mediaQueryLists = queries.map((q) => window.matchMedia(q));
3747
+ const getValue2 = () => {
3748
+ const matchedQueries = mediaQueryLists.map((mql) => mql.matches);
3749
+ return matchedQueries;
3750
+ };
3751
+ const [value, setValue] = useState8(getValue2);
3752
+ useLayoutEffect(() => {
3753
+ const handler = () => setValue(getValue2);
3754
+ mediaQueryLists.forEach((mql) => mql.addListener(handler));
3755
+ return () => mediaQueryLists.forEach((mql) => mql.removeListener(handler));
3756
+ }, []);
3757
+ return value;
3758
+ }
3759
+
3177
3760
  // src/Layout/Layout.mobile.tsx
3178
- import styled11, { css as css5 } from "styled-components";
3179
- var Container2 = styled11.div`
3761
+ import styled9, { css as css4 } from "styled-components";
3762
+ var Container2 = styled9.div`
3180
3763
  position: relative;
3181
3764
  display: flex;
3182
3765
  flex: 1;
3183
3766
  overflow: hidden;
3184
3767
  flex-direction: column;
3185
3768
  `;
3186
- var CenterPanel = styled11.div`
3769
+ var CenterPanel = styled9.div`
3187
3770
  flex: 1;
3188
3771
  position: relative;
3189
3772
  z-index: 7;
3190
3773
  `;
3191
- var MobileBar = styled11.div`
3774
+ var MobileBar = styled9.div`
3192
3775
  display: flex;
3193
3776
  justify-content: space-around;
3194
3777
  width: 100%;
@@ -3197,7 +3780,7 @@ var MobileBar = styled11.div`
3197
3780
  padding: 0.5em;
3198
3781
  height: 3.4rem;
3199
3782
  `;
3200
- var LeftBarButton = styled11.button`
3783
+ var LeftBarButton = styled9.button`
3201
3784
  //background: red;
3202
3785
  padding: 0.5em 1em;
3203
3786
  width: 32%;
@@ -3206,7 +3789,7 @@ var LeftBarButton = styled11.button`
3206
3789
  border: none;
3207
3790
  background: #ffffff;
3208
3791
  `;
3209
- var PreviewBarButton = styled11.button`
3792
+ var PreviewBarButton = styled9.button`
3210
3793
  padding: 0.5em 1em;
3211
3794
  width: 32%;
3212
3795
 
@@ -3216,13 +3799,13 @@ var PreviewBarButton = styled11.button`
3216
3799
  border: 1px solid rgba(0, 0, 0, 0.21);
3217
3800
  color: #ffffff;
3218
3801
  `;
3219
- var DrawerContainer = styled11.div`
3802
+ var DrawerContainer = styled9.div`
3220
3803
  position: relative;
3221
3804
  width: 32%;
3222
3805
  margin: 0 0.75em;
3223
3806
  z-index: 9;
3224
3807
  `;
3225
- var DrawerButton = styled11.button`
3808
+ var DrawerButton = styled9.button`
3226
3809
  padding: 0.4em 1em 0.65em;
3227
3810
  position: absolute;
3228
3811
  width: 100%;
@@ -3242,7 +3825,7 @@ var DrawerButton = styled11.button`
3242
3825
  font-size: 1.8em;
3243
3826
  }
3244
3827
  `;
3245
- var DrawerBody = styled11.div`
3828
+ var DrawerBody = styled9.div`
3246
3829
  background: #fff;
3247
3830
  display: flex;
3248
3831
  position: absolute;
@@ -3259,7 +3842,7 @@ var DrawerBody = styled11.div`
3259
3842
  transition:
3260
3843
  0.3s transform ease-in-out,
3261
3844
  0.3s box-shadow;
3262
- ${(props) => props.$open && css5`
3845
+ ${(props) => props.$open && css4`
3263
3846
  box-shadow:
3264
3847
  0 -5px 15px 0 rgba(0, 0, 0, 0.1),
3265
3848
  0 -3px 5px 0 rgba(0, 0, 0, 0.1);
@@ -3273,7 +3856,7 @@ var DrawerBody = styled11.div`
3273
3856
  font-size: 1.1em;
3274
3857
  }
3275
3858
  `;
3276
- var LeftPanel = styled11.div`
3859
+ var LeftPanel = styled9.div`
3277
3860
  position: absolute;
3278
3861
  transform: translateX(-100%);
3279
3862
  background: #fff;
@@ -3283,11 +3866,11 @@ var LeftPanel = styled11.div`
3283
3866
  z-index: 10;
3284
3867
  overflow-y: auto;
3285
3868
  transition: 0.5s transform;
3286
- ${(props) => props.$open && css5`
3869
+ ${(props) => props.$open && css4`
3287
3870
  transform: translateX(0);
3288
3871
  `}
3289
3872
  `;
3290
- var Lightbox = styled11.div`
3873
+ var Lightbox = styled9.div`
3291
3874
  background: rgba(0, 0, 0, 0.4);
3292
3875
  pointer-events: none;
3293
3876
  position: absolute;
@@ -3299,15 +3882,15 @@ var Lightbox = styled11.div`
3299
3882
  opacity: 0;
3300
3883
  transition: opacity 0.5s;
3301
3884
 
3302
- ${(props) => props.$open && css5`
3885
+ ${(props) => props.$open && css4`
3303
3886
  pointer-events: visible;
3304
3887
  opacity: 1;
3305
3888
  `}
3306
3889
  `;
3307
3890
 
3308
3891
  // src/Layout/Layout.styles.ts
3309
- import styled12, { css as css6 } from "styled-components";
3310
- var OuterWrapper = styled12.div`
3892
+ import styled10, { css as css5 } from "styled-components";
3893
+ var OuterWrapper = styled10.div`
3311
3894
  display: flex;
3312
3895
  flex-direction: column;
3313
3896
  flex: 1;
@@ -3317,19 +3900,19 @@ var OuterWrapper = styled12.div`
3317
3900
  min-width: 0;
3318
3901
  overflow: hidden;
3319
3902
  `;
3320
- var Header2 = styled12.header`
3903
+ var Header2 = styled10.header`
3321
3904
  //box-shadow: 0 3px 2px 0 rgba(0, 0, 0, 0.04), 0 1px 0 0 rgba(0, 0, 0, 0.17);
3322
3905
  z-index: 200;
3323
3906
  `;
3324
- var Footer = styled12.div`
3907
+ var Footer = styled10.div`
3325
3908
  background: #fff;
3326
3909
  `;
3327
- var Main = styled12.div`
3910
+ var Main = styled10.div`
3328
3911
  display: flex;
3329
3912
  flex: 1 1 0;
3330
3913
  min-height: 0;
3331
3914
  `;
3332
- var LeftPanel2 = styled12.div`
3915
+ var LeftPanel2 = styled10.div`
3333
3916
  background: #fff;
3334
3917
  display: flex;
3335
3918
  flex-direction: column;
@@ -3337,29 +3920,29 @@ var LeftPanel2 = styled12.div`
3337
3920
  max-width: 720px;
3338
3921
  align-items: flex-end;
3339
3922
 
3340
- ${(props) => props.$motion ? css6`
3923
+ ${(props) => props.$motion ? css5`
3341
3924
  transition: max-width 400ms;
3342
3925
  ` : ""}
3343
3926
 
3344
3927
  ${(props) => {
3345
3928
  switch (props.$state) {
3346
3929
  case "entering":
3347
- return css6`
3930
+ return css5`
3348
3931
  max-width: ${props.$width};
3349
3932
  `;
3350
3933
  case "exiting":
3351
- return css6`
3934
+ return css5`
3352
3935
  max-width: 0;
3353
3936
  `;
3354
3937
  case "unmounted":
3355
3938
  case "exited":
3356
- return css6`
3939
+ return css5`
3357
3940
  max-width: 0;
3358
3941
  `;
3359
3942
  }
3360
3943
  }}
3361
3944
  `;
3362
- var CenterPanel2 = styled12.div`
3945
+ var CenterPanel2 = styled10.div`
3363
3946
  flex: 1 1 0;
3364
3947
  background: #e3e7f0;
3365
3948
  // background: #efefef;
@@ -3379,7 +3962,7 @@ var CenterPanel2 = styled12.div`
3379
3962
  min-width: 0;
3380
3963
  }
3381
3964
  `;
3382
- var RightPanel = styled12.div`
3965
+ var RightPanel = styled10.div`
3383
3966
  background: #fff;
3384
3967
  display: flex;
3385
3968
  flex-direction: column;
@@ -3391,22 +3974,22 @@ var RightPanel = styled12.div`
3391
3974
  ${(props) => {
3392
3975
  switch (props.$state) {
3393
3976
  case "entering":
3394
- return css6`
3977
+ return css5`
3395
3978
  max-width: ${props.$width};
3396
3979
  `;
3397
3980
  case "exiting":
3398
- return css6`
3981
+ return css5`
3399
3982
  max-width: 0;
3400
3983
  `;
3401
3984
  case "unmounted":
3402
3985
  case "exited":
3403
- return css6`
3986
+ return css5`
3404
3987
  max-width: 0;
3405
3988
  `;
3406
3989
  }
3407
3990
  }}
3408
3991
  `;
3409
- var PanelContainer = styled12.div`
3992
+ var PanelContainer = styled10.div`
3410
3993
  display: flex;
3411
3994
  flex: 1;
3412
3995
  height: 100%;
@@ -3417,14 +4000,14 @@ var PanelContainer = styled12.div`
3417
4000
  ${(props) => {
3418
4001
  switch (props.$menu) {
3419
4002
  case "top":
3420
- return css6`
4003
+ return css5`
3421
4004
  flex-direction: column;
3422
4005
  ${PanelMenu} {
3423
4006
  flex-direction: column;
3424
4007
  }
3425
4008
  `;
3426
4009
  case "left":
3427
- return css6`
4010
+ return css5`
3428
4011
  flex-direction: row;
3429
4012
  ${PanelMenu} {
3430
4013
  flex-direction: row;
@@ -3432,14 +4015,14 @@ var PanelContainer = styled12.div`
3432
4015
  `;
3433
4016
  default:
3434
4017
  case "bottom":
3435
- return css6`
4018
+ return css5`
3436
4019
  flex-direction: column-reverse;
3437
4020
  ${PanelMenu} {
3438
4021
  flex-direction: column;
3439
4022
  }
3440
4023
  `;
3441
4024
  case "right":
3442
- return css6`
4025
+ return css5`
3443
4026
  flex-direction: row-reverse;
3444
4027
  ${PanelMenu} {
3445
4028
  flex-direction: row;
@@ -3448,7 +4031,7 @@ var PanelContainer = styled12.div`
3448
4031
  }
3449
4032
  }}
3450
4033
  `;
3451
- var PanelSideMenu = styled12.div`
4034
+ var PanelSideMenu = styled10.div`
3452
4035
  background: #fff;
3453
4036
  border-top: 1px solid #e3e7f0;
3454
4037
  border-right: 1px solid #e3e7f0;
@@ -3459,7 +4042,7 @@ var PanelSideMenu = styled12.div`
3459
4042
  padding: 0.3em;
3460
4043
  gap: 0.3em; */
3461
4044
  `;
3462
- var PanelSideMenuItem = styled12.button`
4045
+ var PanelSideMenuItem = styled10.button`
3463
4046
  cursor: pointer;
3464
4047
  aspect-ratio: 1;
3465
4048
  width: 3em;
@@ -3487,17 +4070,17 @@ var PanelSideMenuItem = styled12.button`
3487
4070
  color: #999;
3488
4071
  }
3489
4072
  `;
3490
- var PanelMenu = styled12.div`
4073
+ var PanelMenu = styled10.div`
3491
4074
  display: flex;
3492
4075
  box-shadow:
3493
4076
  0 -3px 2px 0 rgba(0, 0, 0, 0.04),
3494
4077
  0 -1px 0 0 rgba(0, 0, 0, 0.17);
3495
4078
 
3496
- ${(props) => !props.$open && (props.$position === "top" || props.$position === "bottom") ? css6`
4079
+ ${(props) => !props.$open && (props.$position === "top" || props.$position === "bottom") ? css5`
3497
4080
  display: none;
3498
4081
  ` : ""}
3499
4082
  `;
3500
- var PanelContent = styled12.div`
4083
+ var PanelContent = styled10.div`
3501
4084
  display: flex;
3502
4085
  flex-direction: column;
3503
4086
  flex: 1;
@@ -3506,25 +4089,25 @@ var PanelContent = styled12.div`
3506
4089
  `;
3507
4090
 
3508
4091
  // src/Layout/components/HandleControls.tsx
3509
- import styled13 from "styled-components";
4092
+ import styled11 from "styled-components";
3510
4093
  import { forwardRef as forwardRef2 } from "react";
3511
4094
 
3512
4095
  // ../ui/icons/ResetIcon.tsx
3513
- import { jsx as jsx28, jsxs as jsxs15 } from "react/jsx-runtime";
4096
+ import { jsx as jsx30, jsxs as jsxs15 } from "react/jsx-runtime";
3514
4097
  var ResetIcon = (props) => /* @__PURE__ */ jsxs15("svg", { xmlns: "http://www.w3.org/2000/svg", height: "1em", width: "1em", viewBox: "0 0 24 24", ...props, children: [
3515
- /* @__PURE__ */ jsx28("path", { d: "M0 0h24v24H0V0z", fill: "none" }),
3516
- /* @__PURE__ */ jsx28("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" })
4098
+ /* @__PURE__ */ jsx30("path", { d: "M0 0h24v24H0V0z", fill: "none" }),
4099
+ /* @__PURE__ */ jsx30("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" })
3517
4100
  ] });
3518
4101
 
3519
4102
  // src/Layout/components/HandleControls.tsx
3520
- import { jsx as jsx29, jsxs as jsxs16 } from "react/jsx-runtime";
3521
- var HandleContainer = styled13.div`
4103
+ import { jsx as jsx31, jsxs as jsxs16 } from "react/jsx-runtime";
4104
+ var HandleContainer = styled11.div`
3522
4105
  position: relative;
3523
4106
  width: 1px;
3524
4107
  background: rgba(0, 0, 0, 0.2);
3525
4108
  z-index: 50;
3526
4109
  `;
3527
- var HandleControl = styled13(ButtonReset)`
4110
+ var HandleControl = styled11(ButtonReset)`
3528
4111
  transition:
3529
4112
  opacity 300ms,
3530
4113
  transform 300ms;
@@ -3537,7 +4120,7 @@ var HandleControl = styled13(ButtonReset)`
3537
4120
  outline: 2px solid salmon;
3538
4121
  }
3539
4122
  `;
3540
- var ResizeHandle = styled13(HandleControl)`
4123
+ var ResizeHandle = styled11(HandleControl)`
3541
4124
  position: relative;
3542
4125
  background: #fff;
3543
4126
  height: 40px;
@@ -3546,7 +4129,7 @@ var ResizeHandle = styled13(HandleControl)`
3546
4129
  box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2);
3547
4130
  user-select: none;
3548
4131
  `;
3549
- var IconControl = styled13(HandleControl)`
4132
+ var IconControl = styled11(HandleControl)`
3550
4133
  background: #fff;
3551
4134
  width: 30px;
3552
4135
  height: 30px;
@@ -3561,7 +4144,7 @@ var IconControl = styled13(HandleControl)`
3561
4144
  fill: #9999;
3562
4145
  }
3563
4146
  `;
3564
- var OpenControl = styled13(HandleControl)`
4147
+ var OpenControl = styled11(HandleControl)`
3565
4148
  position: relative;
3566
4149
  display: flex;
3567
4150
  opacity: 1;
@@ -3589,7 +4172,7 @@ var OpenControl = styled13(HandleControl)`
3589
4172
  font-size: 1.5em;
3590
4173
  }
3591
4174
  `;
3592
- var InnerHandleContainer = styled13.div`
4175
+ var InnerHandleContainer = styled11.div`
3593
4176
  background: rgba(0, 0, 0, 0);
3594
4177
  position: absolute;
3595
4178
  width: 21px;
@@ -3618,7 +4201,7 @@ var InnerHandleContainer = styled13.div`
3618
4201
  }
3619
4202
  }
3620
4203
  `;
3621
- var UnscaledContainer = styled13.div`
4204
+ var UnscaledContainer = styled11.div`
3622
4205
  background: rgba(0, 0, 0, 0);
3623
4206
  position: absolute;
3624
4207
  pointer-events: none;
@@ -3630,7 +4213,7 @@ var UnscaledContainer = styled13.div`
3630
4213
  `;
3631
4214
  var HandleControls = forwardRef2(function HandleControls2({ dir, open, actions, reset }, ref) {
3632
4215
  return /* @__PURE__ */ jsxs16(HandleContainer, { onClick: () => actions.open(), children: [
3633
- /* @__PURE__ */ jsx29(UnscaledContainer, { $open: open, $dir: dir, children: !open ? /* @__PURE__ */ jsx29(
4216
+ /* @__PURE__ */ jsx31(UnscaledContainer, { $open: open, $dir: dir, children: !open ? /* @__PURE__ */ jsx31(
3634
4217
  OpenControl,
3635
4218
  {
3636
4219
  $dir: dir,
@@ -3638,42 +4221,42 @@ var HandleControls = forwardRef2(function HandleControls2({ dir, open, actions,
3638
4221
  e.stopPropagation();
3639
4222
  actions.open();
3640
4223
  },
3641
- children: /* @__PURE__ */ jsx29(DownIcon, { rotate: dir === "right" ? 90 : 270 })
4224
+ children: /* @__PURE__ */ jsx31(DownIcon, { rotate: dir === "right" ? 90 : 270 })
3642
4225
  }
3643
4226
  ) : null }),
3644
4227
  /* @__PURE__ */ jsxs16(InnerHandleContainer, { ref, $open: open, $dir: dir, children: [
3645
- open ? /* @__PURE__ */ jsx29(
4228
+ open ? /* @__PURE__ */ jsx31(
3646
4229
  IconControl,
3647
4230
  {
3648
4231
  onClick: (e) => {
3649
4232
  e.stopPropagation();
3650
4233
  actions.close();
3651
4234
  },
3652
- children: /* @__PURE__ */ jsx29(CloseIcon, {})
4235
+ children: /* @__PURE__ */ jsx31(CloseIcon, {})
3653
4236
  }
3654
4237
  ) : null,
3655
- reset && open ? /* @__PURE__ */ jsx29(
4238
+ reset && open ? /* @__PURE__ */ jsx31(
3656
4239
  IconControl,
3657
4240
  {
3658
4241
  onClick: (e) => {
3659
4242
  e.stopPropagation();
3660
4243
  reset();
3661
4244
  },
3662
- children: /* @__PURE__ */ jsx29(ResetIcon, {})
4245
+ children: /* @__PURE__ */ jsx31(ResetIcon, {})
3663
4246
  }
3664
4247
  ) : null,
3665
- open ? /* @__PURE__ */ jsx29(ResizeHandle, {}) : null
4248
+ open ? /* @__PURE__ */ jsx31(ResizeHandle, {}) : null
3666
4249
  ] })
3667
4250
  ] });
3668
4251
  });
3669
4252
 
3670
4253
  // src/Layout/components/use-resize-layouts.tsx
3671
- import { useRef as useRef6, useState as useState8 } from "react";
4254
+ import { useRef as useRef6, useState as useState9 } from "react";
3672
4255
 
3673
4256
  // ../ui/madoc/use-event-handler.ts
3674
- import { useLayoutEffect } from "react";
4257
+ import { useLayoutEffect as useLayoutEffect2 } from "react";
3675
4258
  function useEventHandler(ref, name, callback, deps = []) {
3676
- useLayoutEffect(() => {
4259
+ useLayoutEffect2(() => {
3677
4260
  const current = ref.current;
3678
4261
  if (current) {
3679
4262
  current.addEventListener(name, callback);
@@ -3703,7 +4286,7 @@ function useResizeLayout(name, options = {}) {
3703
4286
  const otherDiv = useRef6(null);
3704
4287
  const resizer = useRef6(null);
3705
4288
  const newPct = useRef6(0.5);
3706
- const [isDragging, setIsDragging] = useState8(false);
4289
+ const [isDragging, setIsDragging] = useState9(false);
3707
4290
  const isEventDragging = useRef6(false);
3708
4291
  const isEventTimeout = useRef6(0);
3709
4292
  const startPos = useRef6({ x: 0, y: 0 });
@@ -3811,39 +4394,34 @@ function useResizeLayout(name, options = {}) {
3811
4394
  };
3812
4395
  }
3813
4396
 
3814
- // src/hooks/use-match-media.ts
3815
- import { useState as useState9, useLayoutEffect as useLayoutEffect2 } from "react";
3816
- function useMatchMedia(queries, defaultValues = []) {
3817
- const initialValues = defaultValues.length ? defaultValues : Array(queries.length).fill(false);
3818
- if (typeof window === "undefined")
3819
- return initialValues;
3820
- const mediaQueryLists = queries.map((q) => window.matchMedia(q));
3821
- const getValue2 = () => {
3822
- const matchedQueries = mediaQueryLists.map((mql) => mql.matches);
3823
- return matchedQueries;
3824
- };
3825
- const [value, setValue] = useState9(getValue2);
3826
- useLayoutEffect2(() => {
3827
- const handler = () => setValue(getValue2);
3828
- mediaQueryLists.forEach((mql) => mql.addListener(handler));
3829
- return () => mediaQueryLists.forEach((mql) => mql.removeListener(handler));
3830
- }, []);
3831
- return value;
3832
- }
3833
-
3834
4397
  // src/Layout/Layout.tsx
3835
- import { Modal, PanelSideMenu as PanelSideMenu2 } from "@manifest-editor/components";
3836
- import { Fragment as Fragment4, jsx as jsx30, jsxs as jsxs17 } from "react/jsx-runtime";
4398
+ import { Fragment as Fragment4, jsx as jsx32, jsxs as jsxs17 } from "react/jsx-runtime";
3837
4399
  var Layout = memo4(function Layout2(props) {
3838
4400
  const appState = useAppState();
3839
4401
  const layout = useLayoutProvider();
3840
- const { vault: _vault } = useContext11(ReactVaultContext2);
4402
+ const { vault: _vault } = useContext14(ReactVaultContext2);
3841
4403
  const vault = _vault || void 0;
3842
- const { loading, state, leftPanels, centerPanels, rightPanels, modals = [], actions } = layout;
3843
- const leftPanel = leftPanels.find((panel) => panel.id === state.leftPanel.current);
3844
- const rightPanel = rightPanels.find((panel) => panel.id === state.rightPanel.current);
3845
- const centerPanel = centerPanels.find((panel) => panel.id === state.centerPanel.current);
3846
- const modalToRender = modals.find((panel) => panel.id === state.modal.current);
4404
+ const {
4405
+ loading,
4406
+ state,
4407
+ leftPanels,
4408
+ centerPanels,
4409
+ rightPanels,
4410
+ modals = [],
4411
+ actions
4412
+ } = layout;
4413
+ const leftPanel = leftPanels.find(
4414
+ (panel) => panel.id === state.leftPanel.current
4415
+ );
4416
+ const rightPanel = rightPanels.find(
4417
+ (panel) => panel.id === state.rightPanel.current
4418
+ );
4419
+ const centerPanel = centerPanels.find(
4420
+ (panel) => panel.id === state.centerPanel.current
4421
+ );
4422
+ const modalToRender = modals.find(
4423
+ (panel) => panel.id === state.modal.current
4424
+ );
3847
4425
  const enableMotion = true;
3848
4426
  const pinnedRightPanel = state.pinnedRightPanel.pinned ? rightPanels.find((panel) => panel.id === state.pinnedRightPanel.current) : void 0;
3849
4427
  const [mobile] = useMatchMedia(["(max-width: 1020px)"]);
@@ -3898,7 +4476,7 @@ var Layout = memo4(function Layout2(props) {
3898
4476
  if (loading) {
3899
4477
  return null;
3900
4478
  }
3901
- const renderLeftPanel = (transition) => /* @__PURE__ */ jsx30(
4479
+ const renderLeftPanel = (transition) => /* @__PURE__ */ jsx32(
3902
4480
  PanelContainer,
3903
4481
  {
3904
4482
  $menu: props.leftPanelMenuPosition || "bottom",
@@ -3908,8 +4486,8 @@ var Layout = memo4(function Layout2(props) {
3908
4486
  width: state.leftPanel.open || transition !== "exited" ? leftPanelResizer.widthB : void 0,
3909
4487
  minWidth: leftPanel?.options?.minWidth
3910
4488
  },
3911
- children: isLoading ? /* @__PURE__ */ jsx30(PanelContent, { children: /* @__PURE__ */ jsx30(GhostBlocks, {}) }) : /* @__PURE__ */ jsxs17(Fragment4, { children: [
3912
- props.leftPanelMenu ? /* @__PURE__ */ jsx30(
4489
+ children: isLoading ? /* @__PURE__ */ jsx32(PanelContent, { children: /* @__PURE__ */ jsx32(GhostBlocks, {}) }) : /* @__PURE__ */ jsxs17(Fragment4, { children: [
4490
+ props.leftPanelMenu ? /* @__PURE__ */ jsx32(
3913
4491
  PanelMenu,
3914
4492
  {
3915
4493
  $open: state.leftPanel.open && transition !== "exited",
@@ -3917,7 +4495,7 @@ var Layout = memo4(function Layout2(props) {
3917
4495
  children: props.leftPanelMenu
3918
4496
  }
3919
4497
  ) : null,
3920
- /* @__PURE__ */ jsx30(PanelContent, { children: state.leftPanel.open || transition !== "exited" ? /* @__PURE__ */ jsx30(Fragment4, { children: leftPanel ? /* @__PURE__ */ jsx30(
4498
+ /* @__PURE__ */ jsx32(PanelContent, { children: state.leftPanel.open || transition !== "exited" ? /* @__PURE__ */ jsx32(Fragment4, { children: leftPanel ? /* @__PURE__ */ jsx32(
3921
4499
  ModularPanel,
3922
4500
  {
3923
4501
  isLeft: true,
@@ -3935,7 +4513,7 @@ var Layout = memo4(function Layout2(props) {
3935
4513
  if (!modalToRender || state.modal.open === false) {
3936
4514
  return null;
3937
4515
  }
3938
- return /* @__PURE__ */ jsx30(Modal, { title: modalToRender.label, onClose: () => actions.modal.close(), children: renderHelper(
4516
+ return /* @__PURE__ */ jsx32(Modal, { title: modalToRender.label, onClose: () => actions.modal.close(), children: renderHelper(
3939
4517
  modalToRender.render(
3940
4518
  state.modal.state || modalToRender.defaultState || {},
3941
4519
  { ...layout, current: actions.modal, vault },
@@ -3944,8 +4522,26 @@ var Layout = memo4(function Layout2(props) {
3944
4522
  ) });
3945
4523
  };
3946
4524
  const renderCenterPanel = () => /* @__PURE__ */ jsxs17(PanelContainer, { $menu: props.centerPanelMenuPosition || "top", children: [
3947
- props.centerPanelMenu ? /* @__PURE__ */ jsx30(PanelMenu, { $open: state.centerPanel.open, $position: props.centerPanelMenuPosition || "top", children: props.centerPanelMenu }) : null,
3948
- /* @__PURE__ */ jsx30(PanelContent, { children: isLoading ? /* @__PURE__ */ jsx30("div", { style: { display: "flex", flex: 1, justifyContent: "center", alignItems: "center" }, children: /* @__PURE__ */ jsx30(Spinner, { stroke: "rgba(0,0,0,.3)", fontSize: "2em" }) }) : state.centerPanel.open ? centerPanel ? renderHelper(
4525
+ props.centerPanelMenu ? /* @__PURE__ */ jsx32(
4526
+ PanelMenu,
4527
+ {
4528
+ $open: state.centerPanel.open,
4529
+ $position: props.centerPanelMenuPosition || "top",
4530
+ children: props.centerPanelMenu
4531
+ }
4532
+ ) : null,
4533
+ /* @__PURE__ */ jsx32(PanelContent, { children: isLoading ? /* @__PURE__ */ jsx32(
4534
+ "div",
4535
+ {
4536
+ style: {
4537
+ display: "flex",
4538
+ flex: 1,
4539
+ justifyContent: "center",
4540
+ alignItems: "center"
4541
+ },
4542
+ children: /* @__PURE__ */ jsx32(Spinner, { stroke: "rgba(0,0,0,.3)", fontSize: "2em" })
4543
+ }
4544
+ ) : state.centerPanel.open ? centerPanel ? renderHelper(
3949
4545
  centerPanel.render(
3950
4546
  state.centerPanel.state || centerPanel.defaultState || {},
3951
4547
  { ...layout, current: actions.centerPanel, vault },
@@ -3953,7 +4549,7 @@ var Layout = memo4(function Layout2(props) {
3953
4549
  )
3954
4550
  ) : null : null })
3955
4551
  ] });
3956
- const renderRightPanel = (transition) => /* @__PURE__ */ jsx30(
4552
+ const renderRightPanel = (transition) => /* @__PURE__ */ jsx32(
3957
4553
  PanelContainer,
3958
4554
  {
3959
4555
  $menu: props.rightPanelMenuPosition || "bottom",
@@ -3963,10 +4559,17 @@ var Layout = memo4(function Layout2(props) {
3963
4559
  width: state.rightPanel.open || transition !== "exited" ? rightPanelResizer.widthB : void 0,
3964
4560
  minWidth: rightPanel?.options?.minWidth
3965
4561
  },
3966
- children: isLoading ? /* @__PURE__ */ jsx30(PanelContent, { children: /* @__PURE__ */ jsx30(GhostBlocks, {}) }) : /* @__PURE__ */ jsxs17(Fragment4, { children: [
3967
- props.rightPanelMenu ? /* @__PURE__ */ jsx30(PanelMenu, { $open: state.rightPanel.open, $position: props.rightPanelMenuPosition || "bottom", children: props.rightPanelMenu }) : null,
3968
- /* @__PURE__ */ jsx30(PanelContent, { children: state.rightPanel.open || transition !== "exited" ? /* @__PURE__ */ jsxs17(Fragment4, { children: [
3969
- showRightPanel ? /* @__PURE__ */ jsx30(
4562
+ children: isLoading ? /* @__PURE__ */ jsx32(PanelContent, { children: /* @__PURE__ */ jsx32(GhostBlocks, {}) }) : /* @__PURE__ */ jsxs17(Fragment4, { children: [
4563
+ props.rightPanelMenu ? /* @__PURE__ */ jsx32(
4564
+ PanelMenu,
4565
+ {
4566
+ $open: state.rightPanel.open,
4567
+ $position: props.rightPanelMenuPosition || "bottom",
4568
+ children: props.rightPanelMenu
4569
+ }
4570
+ ) : null,
4571
+ /* @__PURE__ */ jsx32(PanelContent, { children: state.rightPanel.open || transition !== "exited" ? /* @__PURE__ */ jsxs17(Fragment4, { children: [
4572
+ showRightPanel ? /* @__PURE__ */ jsx32(
3970
4573
  ModularPanel,
3971
4574
  {
3972
4575
  panel: rightPanel,
@@ -3976,7 +4579,7 @@ var Layout = memo4(function Layout2(props) {
3976
4579
  available: rightPanels
3977
4580
  }
3978
4581
  ) : null,
3979
- pinnedRightPanel ? /* @__PURE__ */ jsx30(
4582
+ pinnedRightPanel ? /* @__PURE__ */ jsx32(
3980
4583
  ModularPanel,
3981
4584
  {
3982
4585
  panel: pinnedRightPanel,
@@ -3993,21 +4596,21 @@ var Layout = memo4(function Layout2(props) {
3993
4596
  return /* @__PURE__ */ jsxs17(OuterWrapper, { children: [
3994
4597
  props.hideHeader ? null : /* @__PURE__ */ jsxs17(Header2, { children: [
3995
4598
  props.header || null,
3996
- props.menu ? /* @__PURE__ */ jsx30("menu", { children: props.menu }) : null
4599
+ props.menu ? /* @__PURE__ */ jsx32("menu", { children: props.menu }) : null
3997
4600
  ] }),
3998
- /* @__PURE__ */ jsx30(Main, { children: /* @__PURE__ */ jsxs17(Container2, { children: [
3999
- /* @__PURE__ */ jsx30(CenterPanel, { children: renderCenterPanel() }),
4601
+ /* @__PURE__ */ jsx32(Main, { children: /* @__PURE__ */ jsxs17(Container2, { children: [
4602
+ /* @__PURE__ */ jsx32(CenterPanel, { children: renderCenterPanel() }),
4000
4603
  /* @__PURE__ */ jsxs17(MobileBar, { children: [
4001
- leftPanels.length > 0 ? /* @__PURE__ */ jsx30(LeftBarButton, { onClick: actions.leftPanel.toggle, children: leftPanel?.label }) : null,
4002
- rightPanels.length > 0 ? /* @__PURE__ */ jsx30(DrawerContainer, { children: /* @__PURE__ */ jsxs17(DrawerButton, { onClick: actions.rightPanel.toggle, children: [
4003
- /* @__PURE__ */ jsx30(DownIcon, { rotate: 180 }),
4604
+ leftPanels.length > 0 ? /* @__PURE__ */ jsx32(LeftBarButton, { onClick: actions.leftPanel.toggle, children: leftPanel?.label }) : null,
4605
+ rightPanels.length > 0 ? /* @__PURE__ */ jsx32(DrawerContainer, { children: /* @__PURE__ */ jsxs17(DrawerButton, { onClick: actions.rightPanel.toggle, children: [
4606
+ /* @__PURE__ */ jsx32(DownIcon, { rotate: 180 }),
4004
4607
  rightPanel?.label
4005
4608
  ] }) }) : null,
4006
- /* @__PURE__ */ jsx30(PreviewBarButton, { children: "Preview" })
4609
+ /* @__PURE__ */ jsx32(PreviewBarButton, { children: "Preview" })
4007
4610
  ] }),
4008
- rightPanels.length > 0 ? /* @__PURE__ */ jsx30(DrawerBody, { $open: state.rightPanel.open, children: renderRightPanel() }) : null,
4009
- leftPanels.length > 0 ? /* @__PURE__ */ jsx30(LeftPanel, { $open: state.leftPanel.open, children: renderLeftPanel() }) : null,
4010
- leftPanels.length > 0 || rightPanels.length > 0 ? /* @__PURE__ */ jsx30(
4611
+ rightPanels.length > 0 ? /* @__PURE__ */ jsx32(DrawerBody, { $open: state.rightPanel.open, children: renderRightPanel() }) : null,
4612
+ leftPanels.length > 0 ? /* @__PURE__ */ jsx32(LeftPanel, { $open: state.leftPanel.open, children: renderLeftPanel() }) : null,
4613
+ leftPanels.length > 0 || rightPanels.length > 0 ? /* @__PURE__ */ jsx32(
4011
4614
  Lightbox,
4012
4615
  {
4013
4616
  $open: state.leftPanel.open || state.rightPanel.open,
@@ -4023,7 +4626,7 @@ var Layout = memo4(function Layout2(props) {
4023
4626
  return /* @__PURE__ */ jsxs17(OuterWrapper, { className: `manifest-editor ${props.className}`, children: [
4024
4627
  props.hideHeader ? null : /* @__PURE__ */ jsxs17(Header2, { children: [
4025
4628
  props.header || null,
4026
- props.menu ? /* @__PURE__ */ jsx30("menu", { children: props.menu }) : null
4629
+ props.menu ? /* @__PURE__ */ jsx32("menu", { children: props.menu }) : null
4027
4630
  ] }),
4028
4631
  /* @__PURE__ */ jsxs17(
4029
4632
  Main,
@@ -4033,7 +4636,7 @@ var Layout = memo4(function Layout2(props) {
4033
4636
  rightPanelResizer.refs.container.current = div;
4034
4637
  },
4035
4638
  children: [
4036
- leftPanels.length > 0 ? /* @__PURE__ */ jsx30(
4639
+ leftPanels.length > 0 ? /* @__PURE__ */ jsx32(
4037
4640
  PanelSideMenu2,
4038
4641
  {
4039
4642
  current: state.leftPanel.current,
@@ -4053,44 +4656,76 @@ var Layout = memo4(function Layout2(props) {
4053
4656
  open: state.leftPanel.open
4054
4657
  }
4055
4658
  ) : null,
4056
- leftPanels.length > 0 ? /* @__PURE__ */ jsx30(Transition, { in: state.leftPanel.open, timeout: enableMotion ? 400 : 0, unmountOnExit: false, children: (transition) => /* @__PURE__ */ jsxs17(Fragment4, { children: [
4057
- /* @__PURE__ */ jsx30(LeftPanel2, { $width: leftPanelResizer.widthB, $state: transition, $motion: enableMotion, children: renderLeftPanel(transition) }),
4058
- /* @__PURE__ */ jsx30(
4059
- HandleControls,
4060
- {
4061
- ref: leftPanelResizer.refs.resizer,
4062
- reset: resetLeftPanel,
4063
- dir: "left",
4064
- transition,
4065
- open: state.leftPanel.open || transition !== "exited",
4066
- actions: actions.leftPanel
4067
- }
4068
- )
4069
- ] }) }) : null,
4070
- /* @__PURE__ */ jsx30(CenterPanel2, { children: renderCenterPanel() }),
4071
- rightPanels.length > 0 ? /* @__PURE__ */ jsx30(Transition, { in: state.rightPanel.open, timeout: enableMotion ? 400 : 0, unmountOnExit: false, children: (transition) => /* @__PURE__ */ jsxs17(Fragment4, { children: [
4072
- /* @__PURE__ */ jsx30(
4073
- HandleControls,
4074
- {
4075
- ref: rightPanelResizer.refs.resizer,
4076
- dir: "right",
4077
- reset: resetRightPanel,
4078
- open: state.rightPanel.open,
4079
- actions: actions.rightPanel
4080
- }
4081
- ),
4082
- /* @__PURE__ */ jsx30(RightPanel, { $width: rightPanelResizer.widthB, $state: transition, $motion: enableMotion, children: renderRightPanel(transition) })
4083
- ] }) }) : null
4659
+ leftPanels.length > 0 ? /* @__PURE__ */ jsx32(
4660
+ Transition,
4661
+ {
4662
+ in: state.leftPanel.open,
4663
+ timeout: enableMotion ? 400 : 0,
4664
+ unmountOnExit: false,
4665
+ children: (transition) => /* @__PURE__ */ jsxs17(Fragment4, { children: [
4666
+ /* @__PURE__ */ jsx32(
4667
+ LeftPanel2,
4668
+ {
4669
+ $width: leftPanelResizer.widthB,
4670
+ $state: transition,
4671
+ $motion: enableMotion,
4672
+ children: renderLeftPanel(transition)
4673
+ }
4674
+ ),
4675
+ /* @__PURE__ */ jsx32(
4676
+ HandleControls,
4677
+ {
4678
+ ref: leftPanelResizer.refs.resizer,
4679
+ reset: resetLeftPanel,
4680
+ dir: "left",
4681
+ transition,
4682
+ open: state.leftPanel.open || transition !== "exited",
4683
+ actions: actions.leftPanel
4684
+ }
4685
+ )
4686
+ ] })
4687
+ }
4688
+ ) : null,
4689
+ /* @__PURE__ */ jsx32(CenterPanel2, { children: renderCenterPanel() }),
4690
+ rightPanels.length > 0 ? /* @__PURE__ */ jsx32(
4691
+ Transition,
4692
+ {
4693
+ in: state.rightPanel.open,
4694
+ timeout: enableMotion ? 400 : 0,
4695
+ unmountOnExit: false,
4696
+ children: (transition) => /* @__PURE__ */ jsxs17(Fragment4, { children: [
4697
+ /* @__PURE__ */ jsx32(
4698
+ HandleControls,
4699
+ {
4700
+ ref: rightPanelResizer.refs.resizer,
4701
+ dir: "right",
4702
+ reset: resetRightPanel,
4703
+ open: state.rightPanel.open,
4704
+ actions: actions.rightPanel
4705
+ }
4706
+ ),
4707
+ /* @__PURE__ */ jsx32(
4708
+ RightPanel,
4709
+ {
4710
+ $width: rightPanelResizer.widthB,
4711
+ $state: transition,
4712
+ $motion: enableMotion,
4713
+ children: renderRightPanel(transition)
4714
+ }
4715
+ )
4716
+ ] })
4717
+ }
4718
+ ) : null
4084
4719
  ]
4085
4720
  }
4086
4721
  ),
4087
- /* @__PURE__ */ jsx30(Footer, { children: props.footer || null }),
4088
- /* @__PURE__ */ jsx30(Fragment4, { children: renderModal() })
4722
+ /* @__PURE__ */ jsx32(Footer, { children: props.footer || null }),
4723
+ /* @__PURE__ */ jsx32(Fragment4, { children: renderModal() })
4089
4724
  ] });
4090
4725
  });
4091
4726
 
4092
4727
  // src/Layout/Layout.hooks.ts
4093
- import { useMemo as useMemo17 } from "react";
4728
+ import { useMemo as useMemo18 } from "react";
4094
4729
  function usePanelActions(panel, dispatch) {
4095
4730
  function popStack() {
4096
4731
  dispatch({ type: "popStack", panel, payload: void 0 });
@@ -4125,7 +4760,7 @@ function usePanelActions(panel, dispatch) {
4125
4760
  function unpin() {
4126
4761
  dispatch({ type: "unpin", panel, payload: void 0 });
4127
4762
  }
4128
- return useMemo17(
4763
+ return useMemo18(
4129
4764
  () => ({
4130
4765
  popStack,
4131
4766
  change,
@@ -4291,14 +4926,14 @@ function getDefaultLayoutState() {
4291
4926
  }
4292
4927
 
4293
4928
  // src/ResourceEditingContext/ResourceEditingContext.tsx
4294
- import { createContext as createContext11, useContext as useContext12, useMemo as useMemo18 } from "react";
4929
+ import { createContext as createContext13, useContext as useContext15, useMemo as useMemo19 } from "react";
4295
4930
  import { useVault as useVault8, useVaultSelector } from "react-iiif-vault";
4296
- import { jsx as jsx31 } from "react/jsx-runtime";
4297
- var ResourceEditingReactContext = createContext11({
4931
+ import { jsx as jsx33 } from "react/jsx-runtime";
4932
+ var ResourceEditingReactContext = createContext13({
4298
4933
  resource: null
4299
4934
  });
4300
4935
  function useEditingContext() {
4301
- return useContext12(ResourceEditingReactContext);
4936
+ return useContext15(ResourceEditingReactContext);
4302
4937
  }
4303
4938
  function useResource() {
4304
4939
  const vault = useVault8();
@@ -4319,10 +4954,10 @@ function ResourceEditingProvider({
4319
4954
  children
4320
4955
  }) {
4321
4956
  const { id, type } = resource || {};
4322
- return /* @__PURE__ */ jsx31(
4957
+ return /* @__PURE__ */ jsx33(
4323
4958
  ResourceEditingReactContext.Provider,
4324
4959
  {
4325
- value: useMemo18(
4960
+ value: useMemo19(
4326
4961
  () => ({
4327
4962
  // Current resource.
4328
4963
  resource: id && type ? { id, type } : null
@@ -4334,9 +4969,12 @@ function ResourceEditingProvider({
4334
4969
  );
4335
4970
  }
4336
4971
 
4972
+ // src/ShellContext/ShellContext.tsx
4973
+ import { ImageServiceLoader } from "@atlas-viewer/iiif-image-api";
4974
+
4337
4975
  // ../ui/atoms/ErrorBoundary.tsx
4338
4976
  import { Component } from "react";
4339
- import { jsx as jsx32 } from "react/jsx-runtime";
4977
+ import { jsx as jsx34 } from "react/jsx-runtime";
4340
4978
  var ErrorBoundary2 = class extends Component {
4341
4979
  constructor() {
4342
4980
  super(...arguments);
@@ -4353,19 +4991,21 @@ var ErrorBoundary2 = class extends Component {
4353
4991
  }
4354
4992
  render() {
4355
4993
  if (this.state.hasError) {
4356
- return /* @__PURE__ */ jsx32("h1", { children: "Sorry.. there was an error" });
4994
+ return /* @__PURE__ */ jsx34("h1", { children: "Sorry.. there was an error" });
4357
4995
  }
4358
4996
  return this.props.children;
4359
4997
  }
4360
4998
  };
4361
4999
 
4362
5000
  // src/ShellContext/ShellContext.tsx
5001
+ import { useMemo as useMemo21 } from "react";
5002
+ import { ImageServiceLoaderContext } from "react-iiif-vault";
4363
5003
  import { ThemeProvider } from "styled-components";
4364
5004
 
4365
5005
  // src/Layout/Layout.context-internal.tsx
4366
5006
  import { isSpecificResource } from "@iiif/parser";
4367
- import { memo as memo5, useMemo as useMemo19, useReducer as useReducer3 } from "react";
4368
- import { jsx as jsx33 } from "react/jsx-runtime";
5007
+ import { memo as memo5, useMemo as useMemo20, useReducer as useReducer3 } from "react";
5008
+ import { jsx as jsx35 } from "react/jsx-runtime";
4369
5009
  function parse(args, _state) {
4370
5010
  if (typeof args === "string") {
4371
5011
  return { id: args, state: _state };
@@ -4375,12 +5015,19 @@ function parse(args, _state) {
4375
5015
  var LayoutProvider = memo5(function LayoutProvider2(props) {
4376
5016
  const app = useApp();
4377
5017
  const available = app.layout;
4378
- const [state, dispatch] = useReducer3(layoutReducer, void 0, getDefaultLayoutState);
5018
+ const [state, dispatch] = useReducer3(
5019
+ layoutReducer,
5020
+ void 0,
5021
+ getDefaultLayoutState
5022
+ );
4379
5023
  const actions = {
4380
5024
  centerPanel: usePanelActions("centerPanel", dispatch),
4381
5025
  leftPanel: usePanelActions("leftPanel", dispatch),
4382
5026
  rightPanel: usePanelActions("rightPanel", dispatch),
4383
- pinnedRightPanel: usePanelActions("pinnedRightPanel", dispatch),
5027
+ pinnedRightPanel: usePanelActions(
5028
+ "pinnedRightPanel",
5029
+ dispatch
5030
+ ),
4384
5031
  modal: usePanelActions("modal", dispatch),
4385
5032
  editingStack: useEditingStack()
4386
5033
  };
@@ -4403,7 +5050,10 @@ var LayoutProvider = memo5(function LayoutProvider2(props) {
4403
5050
  const { id, state: state2, stacked } = parse(args, _state);
4404
5051
  const [found, actions2, pinnable] = find(id);
4405
5052
  if (pinnable && found.options?.openPinned) {
4406
- pinnable.pin({ id, state: { ...found.defaultState || {}, ...state2 || {} } });
5053
+ pinnable.pin({
5054
+ id,
5055
+ state: { ...found.defaultState || {}, ...state2 || {} }
5056
+ });
4407
5057
  } else {
4408
5058
  actions2.open({
4409
5059
  id,
@@ -4440,7 +5090,11 @@ var LayoutProvider = memo5(function LayoutProvider2(props) {
4440
5090
  const [, actions2] = find(id);
4441
5091
  actions2.toggle();
4442
5092
  }
4443
- function edit(resource, context = {}, { reset, property, stacked } = {}) {
5093
+ function edit(resource, context = {}, {
5094
+ reset,
5095
+ property,
5096
+ stacked
5097
+ } = {}) {
4444
5098
  const toEdit = {
4445
5099
  resource: isSpecificResource(resource) ? resource : {
4446
5100
  type: "SpecificResource",
@@ -4460,7 +5114,7 @@ var LayoutProvider = memo5(function LayoutProvider2(props) {
4460
5114
  }
4461
5115
  function create2(resource) {
4462
5116
  actions.editingStack.create(resource, {});
4463
- if (available.modals && available.modals.find((e) => e.id === "@manifest-editor/creator")) {
5117
+ if (available.modals?.find((e) => e.id === "@manifest-editor/creator")) {
4464
5118
  actions.modal.open({
4465
5119
  id: "@manifest-editor/creator",
4466
5120
  stacked: true,
@@ -4485,7 +5139,13 @@ var LayoutProvider = memo5(function LayoutProvider2(props) {
4485
5139
  edit,
4486
5140
  create: create2
4487
5141
  };
4488
- return /* @__PURE__ */ jsx33(LayoutActionsReactContext.Provider, { value: useMemo19(() => ({ ...actions, ...otherActions }), [available]), children: /* @__PURE__ */ jsx33(LayoutStateReactContext.Provider, { value: state, children: props.children }) });
5142
+ return /* @__PURE__ */ jsx35(
5143
+ LayoutActionsReactContext.Provider,
5144
+ {
5145
+ value: useMemo20(() => ({ ...actions, ...otherActions }), [available]),
5146
+ children: /* @__PURE__ */ jsx35(LayoutStateReactContext.Provider, { value: state, children: props.children })
5147
+ }
5148
+ );
4489
5149
  });
4490
5150
 
4491
5151
  // src/ShellContext/default-theme.ts
@@ -4534,13 +5194,11 @@ var defaultTheme = {
4534
5194
  };
4535
5195
 
4536
5196
  // src/ShellContext/ShellContext.tsx
4537
- import { ImageServiceLoaderContext } from "react-iiif-vault";
4538
- import { ImageServiceLoader } from "@atlas-viewer/iiif-image-api";
4539
- import { jsx as jsx34 } from "react/jsx-runtime";
5197
+ import { jsx as jsx36 } from "react/jsx-runtime";
4540
5198
  var previewConfigs = [
4541
5199
  {
4542
5200
  id: "universal-viewer",
4543
- config: { url: "https://uv-v4.netlify.app/#?iiifManifestId={manifestId}" },
5201
+ config: { url: "https://universalviewer.dev/#?iiifManifestId={manifestId}" },
4544
5202
  type: "external-manifest-preview",
4545
5203
  label: "Universal viewer"
4546
5204
  },
@@ -4581,17 +5239,32 @@ function ShellProvider({
4581
5239
  resource,
4582
5240
  editing
4583
5241
  }) {
4584
- return /* @__PURE__ */ jsx34(ErrorBoundary2, { children: /* @__PURE__ */ jsx34(ImageServiceLoaderContext.Provider, { value: imageServiceLoader, children: /* @__PURE__ */ jsx34(AppResourceProvider, { resource, children: /* @__PURE__ */ jsx34(PreviewVaultContext, { children: /* @__PURE__ */ jsx34(ThemeProvider, { theme: theme || defaultTheme, children: /* @__PURE__ */ jsx34(ConfigProvider, { config, saveConfig, children: /* @__PURE__ */ jsx34(EditingStack, { children: /* @__PURE__ */ jsx34(LayoutProvider, { children: /* @__PURE__ */ jsx34(PreviewProvider, { previews: previews || [], configs: config?.previews || previewConfigs, children }) }) }) }) }) }) }) }) });
5242
+ const existingConfig = useConfig();
5243
+ const mergedConfig = useMemo21(() => {
5244
+ return {
5245
+ ...existingConfig,
5246
+ ...config,
5247
+ previews: config?.previews || existingConfig.previews || previewConfigs
5248
+ };
5249
+ }, [existingConfig, config]);
5250
+ return /* @__PURE__ */ jsx36(ErrorBoundary2, { children: /* @__PURE__ */ jsx36(ImageServiceLoaderContext.Provider, { value: imageServiceLoader, children: /* @__PURE__ */ jsx36(AppResourceProvider, { resource, children: /* @__PURE__ */ jsx36(PreviewVaultContext, { children: /* @__PURE__ */ jsx36(ThemeProvider, { theme: theme || defaultTheme, children: /* @__PURE__ */ jsx36(ConfigProvider, { config: mergedConfig, saveConfig, children: /* @__PURE__ */ jsx36(EditingStack, { children: /* @__PURE__ */ jsx36(LayoutProvider, { children: /* @__PURE__ */ jsx36(
5251
+ PreviewProvider,
5252
+ {
5253
+ previews: previews || [],
5254
+ configs: mergedConfig.previews,
5255
+ children: /* @__PURE__ */ jsx36(AtlasStoreProvider, { children })
5256
+ }
5257
+ ) }) }) }) }) }) }) }) });
4585
5258
  }
4586
5259
 
4587
5260
  // src/TaskBridge/TaskBridge.tsx
4588
- import mitt2 from "mitt";
4589
- import { createContext as createContext12, useCallback as useCallback6, useContext as useContext13, useEffect as useEffect12, useMemo as useMemo20, useReducer as useReducer4 } from "react";
4590
- import { jsx as jsx35 } from "react/jsx-runtime";
5261
+ import mitt3 from "mitt";
5262
+ import { createContext as createContext14, useCallback as useCallback6, useContext as useContext16, useEffect as useEffect13, useMemo as useMemo22, useReducer as useReducer4 } from "react";
5263
+ import { jsx as jsx37 } from "react/jsx-runtime";
4591
5264
  var tempGlobalState = {};
4592
- var DispatchReactContext = createContext12("global");
5265
+ var DispatchReactContext = createContext14("global");
4593
5266
  function useCurrentDispatchId() {
4594
- return useContext13(DispatchReactContext);
5267
+ return useContext16(DispatchReactContext);
4595
5268
  }
4596
5269
  function createDeferred() {
4597
5270
  let res = void 0;
@@ -4605,14 +5278,14 @@ function createDeferred() {
4605
5278
  function useTask(name) {
4606
5279
  const id = useCurrentDispatchId();
4607
5280
  const [, invalidate] = useReducer4((r) => r + 1, 0);
4608
- const task = useMemo20(() => {
5281
+ const task = useMemo22(() => {
4609
5282
  if (!tempGlobalState[id]) {
4610
5283
  tempGlobalState[id] = {};
4611
5284
  }
4612
5285
  if (!tempGlobalState[id][name]) {
4613
5286
  tempGlobalState[id][name] = {
4614
5287
  name,
4615
- emitter: mitt2(),
5288
+ emitter: mitt3(),
4616
5289
  status: "idle",
4617
5290
  promise: Promise.resolve(),
4618
5291
  abort: new AbortController(),
@@ -4630,7 +5303,7 @@ function useTask(name) {
4630
5303
  }
4631
5304
  function useTaskEvent(task, name, _cb) {
4632
5305
  const cb = useCallback6(() => _cb(task), [_cb]);
4633
- useEffect12(() => {
5306
+ useEffect13(() => {
4634
5307
  const em = task.emitter;
4635
5308
  em.on(name, cb);
4636
5309
  return () => em.off(name, cb);
@@ -4679,12 +5352,12 @@ function useTaskRunner(name, onRun) {
4679
5352
  return [completeTask, taskDetails, rejectTask];
4680
5353
  }
4681
5354
  function TaskBridge({ children }) {
4682
- return /* @__PURE__ */ jsx35(DispatchReactContext.Provider, { value: useMemo20(() => `id-${Date.now()}`, []), children });
5355
+ return /* @__PURE__ */ jsx37(DispatchReactContext.Provider, { value: useMemo22(() => `id-${Date.now()}`, []), children });
4683
5356
  }
4684
5357
 
4685
5358
  // src/Universal/UniversalCopyPaste.tsx
4686
- import { useCallback as useCallback7, useMemo as useMemo21 } from "react";
4687
- import { jsx as jsx36 } from "react/jsx-runtime";
5359
+ import { useCallback as useCallback7, useMemo as useMemo23 } from "react";
5360
+ import { jsx as jsx38 } from "react/jsx-runtime";
4688
5361
  function analyse(t) {
4689
5362
  return false;
4690
5363
  }
@@ -4709,7 +5382,7 @@ function UniversalCopyTarget({
4709
5382
  const onPasteReference = _onPasteReference || onReference;
4710
5383
  const onPasteLink = _onPasteLink || onLink;
4711
5384
  const onPasteAnalysis = _onPasteAnalysis || onAnalysis;
4712
- const reference = useMemo21(() => {
5385
+ const reference = useMemo23(() => {
4713
5386
  return _ref;
4714
5387
  }, [_ref?.id, _ref?.type]);
4715
5388
  const onCopy = useCallback7(
@@ -4830,7 +5503,7 @@ function UniversalCopyTarget({
4830
5503
  e.dataTransfer.dropEffect = "copy";
4831
5504
  }
4832
5505
  }, []);
4833
- return /* @__PURE__ */ jsx36(
5506
+ return /* @__PURE__ */ jsx38(
4834
5507
  Component2,
4835
5508
  {
4836
5509
  onCopy,
@@ -5030,11 +5703,11 @@ async function getImageDimensions(url) {
5030
5703
  }
5031
5704
 
5032
5705
  // src/hooks/use-save-vault.ts
5033
- import { useEffect as useEffect13 } from "react";
5706
+ import { useEffect as useEffect14 } from "react";
5034
5707
  import { useDebounce } from "tiny-use-debounce";
5035
5708
  function useSaveVault(vault, saveChanges, saveInterval, enabled = true) {
5036
5709
  const debounceSaveChanges = useDebounce(saveChanges, saveInterval);
5037
- useEffect13(() => {
5710
+ useEffect14(() => {
5038
5711
  if (typeof window === "undefined") {
5039
5712
  return () => void 0;
5040
5713
  }
@@ -5044,24 +5717,156 @@ function useSaveVault(vault, saveChanges, saveInterval, enabled = true) {
5044
5717
  window.removeEventListener("beforeunload", saveChanges);
5045
5718
  };
5046
5719
  }, [saveChanges]);
5047
- useEffect13(() => {
5720
+ useEffect14(() => {
5048
5721
  if (vault && enabled) {
5049
5722
  return vault.subscribe(debounceSaveChanges, true);
5050
5723
  }
5051
5724
  }, [debounceSaveChanges, vault, enabled]);
5052
5725
  }
5726
+
5727
+ // src/hooks/use-svg-tools.tsx
5728
+ import { useMemo as useMemo24 } from "react";
5729
+ import { useStore } from "zustand";
5730
+ function useSvgTools() {
5731
+ const store = useAtlasStore();
5732
+ const switchTool = useStore(store, (s) => s.switchTool);
5733
+ const state = useStore(store, (s) => s.polygons.state.slowState);
5734
+ return useMemo24(
5735
+ () => ({
5736
+ // Draw tool.
5737
+ draw: {
5738
+ active: !state.lineMode && !state.selectedStamp && state.drawMode,
5739
+ enable: switchTool.draw
5740
+ },
5741
+ // Polygon.
5742
+ polygon: {
5743
+ active: !state.lineMode && !state.selectedStamp && !state.drawMode,
5744
+ enable: switchTool.polygon
5745
+ },
5746
+ // Line
5747
+ line: {
5748
+ active: state.lineMode && !state.lineBoxMode,
5749
+ enable: switchTool.line
5750
+ },
5751
+ // Line box.
5752
+ lineBox: {
5753
+ active: state.lineBoxMode,
5754
+ enable: switchTool.lineBox
5755
+ },
5756
+ // Square.
5757
+ square: {
5758
+ active: state.selectedStamp?.id === "square",
5759
+ enable: switchTool.square
5760
+ },
5761
+ // Triangle.
5762
+ triangle: {
5763
+ active: state.selectedStamp?.id === "triangle",
5764
+ enable: switchTool.triangle
5765
+ },
5766
+ // Hexagon.
5767
+ hexagon: {
5768
+ active: state.selectedStamp?.id === "hexagon",
5769
+ enable: switchTool.hexagon
5770
+ },
5771
+ // Circle
5772
+ circle: {
5773
+ active: state.selectedStamp?.id === "circle40",
5774
+ enable: switchTool.circle
5775
+ },
5776
+ // Delete
5777
+ remove: {
5778
+ active: state.showBoundingBox,
5779
+ enable: switchTool.remove
5780
+ }
5781
+ }),
5782
+ [state, switchTool]
5783
+ );
5784
+ }
5785
+
5786
+ // src/hooks/use-request-annotation.ts
5787
+ import { useCallback as useCallback8, useEffect as useEffect15, useState as useState10 } from "react";
5788
+ import { useStore as useStore2 } from "zustand";
5789
+ function useRequestAnnotation(opts) {
5790
+ const [id, setId] = useState10(0);
5791
+ const store = useAtlasStore();
5792
+ const { tool, getRequestId, requestAnnotation, completeRequest, cancelRequest } = useStore2(store, (s) => ({
5793
+ getRequestId: s.getRequestId,
5794
+ requestAnnotation: s.requestAnnotation,
5795
+ completeRequest: s.completeRequest,
5796
+ cancelRequest: s.cancelRequest,
5797
+ tool: s.tool
5798
+ }));
5799
+ const [isPending, setIsPending] = useState10(false);
5800
+ const [data, setData] = useState10(null);
5801
+ const [requestId, setRequestId] = useState10(null);
5802
+ const busy = tool.enabled && tool.requestId !== requestId;
5803
+ const mutateAsync = useCallback8(
5804
+ async (request, options) => {
5805
+ if (requestId) {
5806
+ setIsPending(true);
5807
+ const response = await requestAnnotation(request, {
5808
+ ...options,
5809
+ requestId
5810
+ });
5811
+ if (response) {
5812
+ opts?.onSuccess?.(response);
5813
+ setId((i) => i + 1);
5814
+ setIsPending(false);
5815
+ setData(response);
5816
+ return response;
5817
+ }
5818
+ const resp = {
5819
+ id: requestId,
5820
+ cancelled: true,
5821
+ ...requestToAnnotationResponse(request)
5822
+ };
5823
+ opts?.onSuccess?.(resp);
5824
+ setData(resp);
5825
+ setId((i) => i + 1);
5826
+ setIsPending(false);
5827
+ return resp;
5828
+ }
5829
+ return null;
5830
+ },
5831
+ [opts?.onSuccess, requestAnnotation, requestId]
5832
+ );
5833
+ const reset = useCallback8(() => {
5834
+ setData(null);
5835
+ setIsPending(false);
5836
+ }, []);
5837
+ useEffect15(() => {
5838
+ const request = getRequestId();
5839
+ setRequestId(request.requestId);
5840
+ return () => {
5841
+ request.clear();
5842
+ };
5843
+ }, [id]);
5844
+ return {
5845
+ id,
5846
+ busy,
5847
+ isPending,
5848
+ requestAnnotation: mutateAsync,
5849
+ cancelRequest: () => requestId ? cancelRequest(requestId) : void 0,
5850
+ completeRequest: () => requestId ? completeRequest(requestId) : void 0,
5851
+ reset,
5852
+ data
5853
+ };
5854
+ }
5053
5855
  export {
5054
5856
  AppHeader,
5055
5857
  AppMenuProvider,
5056
5858
  AppProvider,
5057
5859
  AppResourceInstanceProvider,
5058
5860
  AppResourceProvider,
5861
+ AtlasStoreProvider,
5862
+ AtlasStoreReactContext,
5059
5863
  BaseEditor,
5060
5864
  BaseEditorBackButton,
5061
5865
  BaseEditorCloseButton,
5062
5866
  ConfigEditor,
5063
5867
  ConfigProvider,
5064
5868
  EditingStack,
5869
+ EventEmitterProvider,
5065
5870
  ExportPanel,
5066
5871
  HOMEPAGE_COLLECTION,
5067
5872
  HandleContainer,
@@ -5079,7 +5884,9 @@ export {
5079
5884
  PreviewVaultBoundary,
5080
5885
  PreviewVaultContext,
5081
5886
  PrimeAppReactContext,
5887
+ ReactEmitterContext,
5082
5888
  ResourceEditingProvider,
5889
+ ResourceEditingReactContext,
5083
5890
  ShellProvider,
5084
5891
  TaskBridge,
5085
5892
  UniversalCopyTarget,
@@ -5089,10 +5896,12 @@ export {
5089
5896
  baseEditor,
5090
5897
  copyToClipboard,
5091
5898
  createActionIdentity,
5899
+ createAtlasStore,
5092
5900
  createDownload,
5093
5901
  createPreviewVault,
5094
5902
  detectMedia,
5095
5903
  editBasedOnResource,
5904
+ extendApp,
5096
5905
  getDefaultLayoutState,
5097
5906
  getDefaultPanelState,
5098
5907
  getFormat,
@@ -5101,10 +5910,11 @@ export {
5101
5910
  isPinnableState,
5102
5911
  layoutReducer,
5103
5912
  mapApp,
5104
- matchBasedOnResource,
5105
5913
  panelSizing,
5914
+ polygonToBoundingBox,
5106
5915
  randomId,
5107
5916
  renderHelper,
5917
+ requestToAnnotationResponse,
5108
5918
  useAnnotationPageEditor,
5109
5919
  useApp,
5110
5920
  useAppInstance,
@@ -5114,6 +5924,7 @@ export {
5114
5924
  useAppResourceInstance,
5115
5925
  useAppState,
5116
5926
  useApps,
5927
+ useAtlasStore,
5117
5928
  useAvailableLayouts,
5118
5929
  useCollectionEditor,
5119
5930
  useConfig,
@@ -5125,6 +5936,8 @@ export {
5125
5936
  useEditingResourceStack,
5126
5937
  useEditingStack,
5127
5938
  useEditor,
5939
+ useEmitter,
5940
+ useEvent,
5128
5941
  useGenericEditor,
5129
5942
  useHighlightedImageResource,
5130
5943
  useHoverHighlightImageResource,
@@ -5133,16 +5946,19 @@ export {
5133
5946
  useLayoutProvider,
5134
5947
  useLayoutState,
5135
5948
  useManifestEditor,
5949
+ useMatchMedia,
5136
5950
  useOptionalResource,
5137
5951
  usePanelActions,
5138
5952
  usePreviewContext,
5139
5953
  usePreviewHistory,
5140
5954
  usePreviewVault,
5141
5955
  usePreviews,
5956
+ useRequestAnnotation,
5142
5957
  useResource,
5143
5958
  useSaveConfig,
5144
5959
  useSaveVault,
5145
5960
  useSetCustomTitle,
5961
+ useSvgTools,
5146
5962
  useTask,
5147
5963
  useTaskDispatch,
5148
5964
  useTaskEvent,