@manifest-editor/creators 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/iiif-browser-form.lazy-3EZNJN4M.js +21 -0
- package/dist/iiif-browser-form.lazy-3YUQOIEL.js +21 -0
- package/dist/iiif-browser-form.lazy-4CDWA6JD.js +47 -0
- package/dist/iiif-browser-form.lazy-B2RXVKR5.js +21 -0
- package/dist/iiif-browser-form.lazy-DCCYGD42.js +35 -0
- package/dist/iiif-browser-form.lazy-DU2NJUCE.js +46 -0
- package/dist/iiif-browser-form.lazy-DUTUHLUT.js +50 -0
- package/dist/iiif-browser-form.lazy-EJZ754MG.js +42 -0
- package/dist/iiif-browser-form.lazy-ENQRBLTJ.js +21 -0
- package/dist/iiif-browser-form.lazy-FMKQQWDE.js +33 -0
- package/dist/iiif-browser-form.lazy-FOIWPPI7.js +47 -0
- package/dist/iiif-browser-form.lazy-G7XAQYYG.js +51 -0
- package/dist/iiif-browser-form.lazy-GO6U6NE5.js +32 -0
- package/dist/iiif-browser-form.lazy-GVEEZX37.js +33 -0
- package/dist/iiif-browser-form.lazy-HBWB7QGF.js +31 -0
- package/dist/iiif-browser-form.lazy-I7ZNZHID.js +48 -0
- package/dist/iiif-browser-form.lazy-IX5DFVDG.js +47 -0
- package/dist/iiif-browser-form.lazy-KPB57B25.js +21 -0
- package/dist/iiif-browser-form.lazy-KYOKLDRV.js +47 -0
- package/dist/iiif-browser-form.lazy-NDPLPCQQ.js +43 -0
- package/dist/iiif-browser-form.lazy-OQLU6NDJ.js +51 -0
- package/dist/iiif-browser-form.lazy-OZNQO2OO.js +21 -0
- package/dist/iiif-browser-form.lazy-QR55LXI4.js +21 -0
- package/dist/iiif-browser-form.lazy-R5TMXUBV.js +19 -0
- package/dist/iiif-browser-form.lazy-RWEJWTIW.js +21 -0
- package/dist/iiif-browser-form.lazy-T6LT6BJD.js +48 -0
- package/dist/iiif-browser-form.lazy-TWQYATEG.js +21 -0
- package/dist/iiif-browser-form.lazy-UPZXU6JB.js +51 -0
- package/dist/iiif-browser-form.lazy-W42LJ6X2.js +47 -0
- package/dist/iiif-browser-form.lazy-WAK45BLF.js +42 -0
- package/dist/iiif-browser-form.lazy-WVCVE6XK.js +21 -0
- package/dist/index.cjs +1550 -1378
- package/dist/index.d.cts +18 -16
- package/dist/index.d.ts +18 -16
- package/dist/index.js +1451 -1283
- package/package.json +13 -12
- package/dist/chunk-YSQDPG26.js +0 -30
- package/dist/iiif-browser-form.lazy-C3VAAY7I.js +0 -34
- package/dist/iiif-browser-form.lazy-QLO62DFA.js +0 -32
- package/dist/iiif-browser-form.lazy-ZADCSMAN.js +0 -32
- package/dist/manifest-browser-form.lazy-FLU4HSPW.js +0 -7
package/dist/index.js
CHANGED
|
@@ -2,52 +2,298 @@ import {
|
|
|
2
2
|
ManifestBrowserCreatorForm
|
|
3
3
|
} from "./chunk-7FSKLOVQ.js";
|
|
4
4
|
|
|
5
|
-
// src/
|
|
6
|
-
import {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
5
|
+
// src/Annotation/AudioAnnotation/create-audio-annotation.tsx
|
|
6
|
+
import { useEffect as useEffect2, useState as useState2 } from "react";
|
|
7
|
+
|
|
8
|
+
// ../ui/atoms/PaddedSidebarContainer.tsx
|
|
9
|
+
import styled from "styled-components";
|
|
10
|
+
var PaddedSidebarContainer = styled.div`
|
|
11
|
+
padding: 0 0.7em;
|
|
12
|
+
margin: 0.7em 0;
|
|
13
|
+
flex: 1;
|
|
14
|
+
overflow: visible;
|
|
15
|
+
`;
|
|
16
|
+
|
|
17
|
+
// src/Annotation/AudioAnnotation/create-audio-annotation.tsx
|
|
18
|
+
import { ErrorMessage } from "@manifest-editor/components";
|
|
19
|
+
|
|
20
|
+
// ../ui/ui/MediaControls/MediaControls.tsx
|
|
21
|
+
import { formatTime, useMediaActions, useMediaElements, useMediaState } from "react-iiif-vault";
|
|
22
|
+
import { useLayoutEffect, useState } from "react";
|
|
23
|
+
|
|
24
|
+
// ../ui/ui/MediaControls/MediaControls.icons.tsx
|
|
25
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
26
|
+
var PlayIcon = (props) => /* @__PURE__ */ jsxs("svg", { ...props, viewBox: "4 4 16 16", xmlns: "http://www.w3.org/2000/svg", height: "1em", width: "1em", children: [
|
|
27
|
+
props.title ? /* @__PURE__ */ jsx("title", { children: props.title }) : null,
|
|
28
|
+
/* @__PURE__ */ jsx("path", { d: "M0 0h24v24H0z", fill: "none" }),
|
|
29
|
+
/* @__PURE__ */ jsx("path", { d: "M8 5v14l11-7z", fill: "currentColor" })
|
|
30
|
+
] });
|
|
31
|
+
var PauseIcon = (props) => /* @__PURE__ */ jsxs("svg", { ...props, viewBox: "4 4 16 16", xmlns: "http://www.w3.org/2000/svg", height: "1em", width: "1em", children: [
|
|
32
|
+
props.title ? /* @__PURE__ */ jsx("title", { children: props.title }) : null,
|
|
33
|
+
/* @__PURE__ */ jsx("path", { d: "M0 0h24v24H0z", fill: "none" }),
|
|
34
|
+
/* @__PURE__ */ jsx("path", { fill: "currentColor", d: "M6 19h4V5H6v14zm8-14v14h4V5h-4z" })
|
|
35
|
+
] });
|
|
36
|
+
var VolumeUpIcon = ({ title, ...props }) => /* @__PURE__ */ jsxs("svg", { ...props, xmlns: "http://www.w3.org/2000/svg", height: "1em", width: "1em", viewBox: "2 2 20 20", children: [
|
|
37
|
+
title ? /* @__PURE__ */ jsx("title", { children: title }) : null,
|
|
38
|
+
/* @__PURE__ */ jsx("path", { d: "M0 0h24v24H0z", fill: "none" }),
|
|
39
|
+
/* @__PURE__ */ jsx(
|
|
40
|
+
"path",
|
|
41
|
+
{
|
|
42
|
+
fill: "currentColor",
|
|
43
|
+
d: "M3 9v6h4l5 5V4L7 9H3zm13.5 3A4.5 4.5 0 0 0 14 7.97v8.05c1.48-.73 2.5-2.25 2.5-4.02zM14 3.23v2.06c2.89.86 5 3.54 5 6.71s-2.11 5.85-5 6.71v2.06c4.01-.91 7-4.49 7-8.77s-2.99-7.86-7-8.77z"
|
|
44
|
+
}
|
|
45
|
+
)
|
|
46
|
+
] });
|
|
47
|
+
var VolumeDownIcon = ({ title, ...props }) => /* @__PURE__ */ jsxs("svg", { ...props, xmlns: "http://www.w3.org/2000/svg", height: "1em", width: "1em", viewBox: "2 2 20 20", children: [
|
|
48
|
+
title ? /* @__PURE__ */ jsx("title", { children: title }) : null,
|
|
49
|
+
/* @__PURE__ */ jsx("path", { d: "M0 0h24v24H0z", fill: "none" }),
|
|
50
|
+
/* @__PURE__ */ jsx(
|
|
51
|
+
"path",
|
|
52
|
+
{
|
|
53
|
+
fill: "currentColor",
|
|
54
|
+
d: "M18.5 12c0-1.77-1.02-3.29-2.5-4.03v8.05c1.48-.73 2.5-2.25 2.5-4.02zM5 9v6h4l5 5V4L9 9H5z"
|
|
55
|
+
}
|
|
56
|
+
)
|
|
57
|
+
] });
|
|
58
|
+
var VolumeOffIcon = ({ title, ...props }) => /* @__PURE__ */ jsxs("svg", { ...props, xmlns: "http://www.w3.org/2000/svg", height: "1em", width: "1em", viewBox: "2 2 20 20", children: [
|
|
59
|
+
title ? /* @__PURE__ */ jsx("title", { children: title }) : null,
|
|
60
|
+
/* @__PURE__ */ jsx("path", { d: "M0 0h24v24H0z", fill: "none" }),
|
|
61
|
+
/* @__PURE__ */ jsx(
|
|
62
|
+
"path",
|
|
63
|
+
{
|
|
64
|
+
fill: "currentColor",
|
|
65
|
+
d: "M16.5 12A4.5 4.5 0 0 0 14 7.97v2.21l2.45 2.45c.03-.2.05-.41.05-.63zm2.5 0c0 .94-.2 1.82-.54 2.64l1.51 1.51A8.796 8.796 0 0 0 21 12c0-4.28-2.99-7.86-7-8.77v2.06c2.89.86 5 3.54 5 6.71zM4.27 3 3 4.27 7.73 9H3v6h4l5 5v-6.73l4.25 4.25c-.67.52-1.42.93-2.25 1.18v2.06a8.99 8.99 0 0 0 3.69-1.81L19.73 21 21 19.73l-9-9L4.27 3zM12 4 9.91 6.09 12 8.18V4z"
|
|
66
|
+
}
|
|
67
|
+
)
|
|
68
|
+
] });
|
|
69
|
+
|
|
70
|
+
// ../ui/ui/MediaControls/MediaControls.styles.ts
|
|
71
|
+
import styled2, { css } from "styled-components";
|
|
72
|
+
var AudioPlayerContainer = styled2.div`
|
|
73
|
+
background: #ededed; // Not in variable.
|
|
74
|
+
display: flex;
|
|
75
|
+
padding: 0.5em;
|
|
76
|
+
align-items: center;
|
|
77
|
+
`;
|
|
78
|
+
var BaseButton = styled2.button`
|
|
79
|
+
cursor: pointer;
|
|
80
|
+
padding: 0.75em 1.5em;
|
|
81
|
+
font-size: 0.938em;
|
|
82
|
+
background: none;
|
|
83
|
+
color: inherit;
|
|
84
|
+
border: none;
|
|
85
|
+
text-decoration: none;
|
|
86
|
+
display: inline-block;
|
|
87
|
+
vertical-align: top;
|
|
88
|
+
white-space: nowrap;
|
|
89
|
+
`;
|
|
90
|
+
var PlayButton = styled2(BaseButton)`
|
|
91
|
+
width: 2em;
|
|
92
|
+
height: 2em;
|
|
93
|
+
overflow: hidden;
|
|
94
|
+
font-size: 1.1em;
|
|
95
|
+
background: #fff;
|
|
96
|
+
border-radius: 3px;
|
|
97
|
+
padding: 0;
|
|
98
|
+
margin: 0;
|
|
99
|
+
color: #000; // Not in colours
|
|
100
|
+
|
|
101
|
+
&:disabled {
|
|
102
|
+
color: #999;
|
|
19
103
|
}
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
104
|
+
`;
|
|
105
|
+
var TimeDisplay = styled2.div`
|
|
106
|
+
margin: 0 1em;
|
|
107
|
+
font-size: 0.85em;
|
|
108
|
+
color: #000;
|
|
109
|
+
`;
|
|
110
|
+
var ProgressContainer = styled2.div`
|
|
111
|
+
flex: 1 1 0px;
|
|
112
|
+
height: 6px;
|
|
113
|
+
display: flex;
|
|
114
|
+
position: relative;
|
|
115
|
+
padding: 15px 0;
|
|
116
|
+
`;
|
|
117
|
+
var ProgressCurrent = styled2.div`
|
|
118
|
+
background: #d85680;
|
|
119
|
+
height: 6px;
|
|
120
|
+
pointer-events: none;
|
|
121
|
+
position: absolute;
|
|
122
|
+
top: 13px;
|
|
123
|
+
left: 0;
|
|
124
|
+
border-radius: 3px;
|
|
125
|
+
transition: width 200ms;
|
|
126
|
+
`;
|
|
127
|
+
var ProgressBackground = styled2.div`
|
|
128
|
+
position: absolute;
|
|
129
|
+
top: 13px;
|
|
130
|
+
left: 0;
|
|
131
|
+
height: 6px;
|
|
132
|
+
border-radius: 3px;
|
|
133
|
+
width: 100%;
|
|
134
|
+
pointer-events: none;
|
|
135
|
+
background: #fff;
|
|
136
|
+
`;
|
|
137
|
+
var SoundButton = styled2(BaseButton)`
|
|
138
|
+
width: 2em;
|
|
139
|
+
height: 2em;
|
|
140
|
+
overflow: hidden;
|
|
141
|
+
font-size: 1.1em;
|
|
142
|
+
background: transparent;
|
|
143
|
+
border-radius: 3px;
|
|
144
|
+
padding: 0;
|
|
145
|
+
margin: 0;
|
|
146
|
+
`;
|
|
147
|
+
var SoundContainer = styled2.div`
|
|
148
|
+
display: flex;
|
|
149
|
+
align-items: center;
|
|
150
|
+
`;
|
|
151
|
+
var VolumeContainer = styled2.div`
|
|
152
|
+
width: 0;
|
|
153
|
+
overflow: hidden;
|
|
154
|
+
transition: width 500ms;
|
|
155
|
+
color: #4a473f; // Not in colours
|
|
156
|
+
|
|
157
|
+
${(props) => props.$isOpen && css`
|
|
158
|
+
width: 150px;
|
|
159
|
+
`}
|
|
160
|
+
`;
|
|
161
|
+
var VolumeSlider = styled2.input.attrs({ type: "range" })`
|
|
162
|
+
width: 120px;
|
|
163
|
+
margin: 0 15px;
|
|
164
|
+
`;
|
|
165
|
+
|
|
166
|
+
// ../ui/madoc/components/icons/Spinner.tsx
|
|
167
|
+
import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
168
|
+
function Spinner(props) {
|
|
169
|
+
return /* @__PURE__ */ jsx2("svg", { width: "1em", height: "1em", viewBox: "0 0 42 42", xmlns: "http://www.w3.org/2000/svg", stroke: "#fff", ...props, children: /* @__PURE__ */ jsxs2("g", { transform: "translate(2 2)", strokeWidth: 5, fill: "none", fillRule: "evenodd", children: [
|
|
170
|
+
/* @__PURE__ */ jsx2("circle", { strokeOpacity: 0.5, cx: 18, cy: 18, r: 18 }),
|
|
171
|
+
/* @__PURE__ */ jsx2("path", { d: "M36 18c0-9.94-8.06-18-18-18", children: /* @__PURE__ */ jsx2(
|
|
172
|
+
"animateTransform",
|
|
173
|
+
{
|
|
174
|
+
attributeName: "transform",
|
|
175
|
+
type: "rotate",
|
|
176
|
+
from: "0 18 18",
|
|
177
|
+
to: "360 18 18",
|
|
178
|
+
dur: "1s",
|
|
179
|
+
repeatCount: "indefinite"
|
|
180
|
+
}
|
|
181
|
+
) })
|
|
182
|
+
] }) });
|
|
36
183
|
}
|
|
37
184
|
|
|
38
|
-
// ../ui/
|
|
39
|
-
import {
|
|
40
|
-
var
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
185
|
+
// ../ui/atoms/VisuallHidden/VisuallHidden.tsx
|
|
186
|
+
import styled3, { css as css2 } from "styled-components";
|
|
187
|
+
var visuallyHidden = css2`
|
|
188
|
+
clip: rect(1px, 1px, 1px, 1px);
|
|
189
|
+
clip-path: inset(50%);
|
|
190
|
+
height: 1px;
|
|
191
|
+
width: 1px;
|
|
192
|
+
margin: -1px;
|
|
193
|
+
overflow: hidden;
|
|
194
|
+
padding: 0;
|
|
195
|
+
position: absolute;
|
|
196
|
+
`;
|
|
197
|
+
var VisuallyHiddenLabel = styled3.label`
|
|
198
|
+
${visuallyHidden}
|
|
199
|
+
`;
|
|
44
200
|
|
|
45
|
-
//
|
|
46
|
-
import {
|
|
201
|
+
// ../ui/ui/MediaControls/MediaControls.tsx
|
|
202
|
+
import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
203
|
+
function MediaControls(props) {
|
|
204
|
+
const [isVolumeOpen, setIsVolumeOpen] = useState(false);
|
|
205
|
+
const { progress, currentTime, element } = useMediaElements();
|
|
206
|
+
const { duration, isMuted, volume, isPlaying, playRequested } = useMediaState();
|
|
207
|
+
const { setVolume, toggleMute, play, pause, setDurationPercent } = useMediaActions();
|
|
208
|
+
const Volume = isMuted || volume === 0 ? VolumeOffIcon : volume > 50 ? VolumeUpIcon : VolumeDownIcon;
|
|
209
|
+
useLayoutEffect(() => {
|
|
210
|
+
if (element.current) {
|
|
211
|
+
const $el = element.current;
|
|
212
|
+
if ($el.error && props.onError) {
|
|
213
|
+
props.onError($el.error?.message || "Unknown error");
|
|
214
|
+
return;
|
|
215
|
+
}
|
|
216
|
+
const onError = () => {
|
|
217
|
+
if (props.onError) {
|
|
218
|
+
props.onError($el.error?.message || "Unknown error");
|
|
219
|
+
}
|
|
220
|
+
};
|
|
221
|
+
const loadedMetadata = () => {
|
|
222
|
+
if ($el.duration && props.onDuration) {
|
|
223
|
+
props.onDuration($el.duration);
|
|
224
|
+
}
|
|
225
|
+
if (props.onDimensions && $el instanceof HTMLVideoElement) {
|
|
226
|
+
props.onDimensions($el.videoWidth, $el.videoHeight);
|
|
227
|
+
}
|
|
228
|
+
};
|
|
229
|
+
$el.addEventListener("loadedmetadata", loadedMetadata);
|
|
230
|
+
$el.addEventListener("error", onError);
|
|
231
|
+
return () => {
|
|
232
|
+
$el.removeEventListener("loadedmetadata", loadedMetadata);
|
|
233
|
+
$el.removeEventListener("error", onError);
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
}, []);
|
|
237
|
+
return /* @__PURE__ */ jsxs3(AudioPlayerContainer, { children: [
|
|
238
|
+
/* @__PURE__ */ jsx3(
|
|
239
|
+
PlayButton,
|
|
240
|
+
{
|
|
241
|
+
disabled: playRequested,
|
|
242
|
+
onClick: () => {
|
|
243
|
+
if (isPlaying) {
|
|
244
|
+
pause();
|
|
245
|
+
} else {
|
|
246
|
+
play();
|
|
247
|
+
}
|
|
248
|
+
},
|
|
249
|
+
children: playRequested ? /* @__PURE__ */ jsx3(Spinner, { stroke: "#999" }) : isPlaying ? /* @__PURE__ */ jsx3(PauseIcon, { title: "Pause" }) : /* @__PURE__ */ jsx3(PlayIcon, { title: "Play" })
|
|
250
|
+
}
|
|
251
|
+
),
|
|
252
|
+
/* @__PURE__ */ jsx3(TimeDisplay, { ref: currentTime, children: "0:00" }),
|
|
253
|
+
/* @__PURE__ */ jsxs3(
|
|
254
|
+
ProgressContainer,
|
|
255
|
+
{
|
|
256
|
+
onClick: (e) => {
|
|
257
|
+
const { left, width } = e.currentTarget.getBoundingClientRect();
|
|
258
|
+
const percent = (e.pageX - left) / width;
|
|
259
|
+
setDurationPercent(percent);
|
|
260
|
+
},
|
|
261
|
+
children: [
|
|
262
|
+
/* @__PURE__ */ jsx3(ProgressBackground, {}),
|
|
263
|
+
duration ? /* @__PURE__ */ jsx3(ProgressCurrent, { ref: progress }) : null
|
|
264
|
+
]
|
|
265
|
+
}
|
|
266
|
+
),
|
|
267
|
+
/* @__PURE__ */ jsx3(TimeDisplay, { children: formatTime(duration) }),
|
|
268
|
+
/* @__PURE__ */ jsxs3(SoundContainer, { onMouseEnter: () => setIsVolumeOpen(true), onMouseLeave: () => setIsVolumeOpen(false), children: [
|
|
269
|
+
/* @__PURE__ */ jsx3(VolumeContainer, { $isOpen: isVolumeOpen, children: /* @__PURE__ */ jsxs3("span", { children: [
|
|
270
|
+
/* @__PURE__ */ jsx3(VisuallyHiddenLabel, { htmlFor: "audio-slider", children: "Change volume" }),
|
|
271
|
+
/* @__PURE__ */ jsx3(
|
|
272
|
+
VolumeSlider,
|
|
273
|
+
{
|
|
274
|
+
id: "audio-slider",
|
|
275
|
+
role: "slider",
|
|
276
|
+
disabled: isMuted,
|
|
277
|
+
min: "0",
|
|
278
|
+
max: "100",
|
|
279
|
+
value: volume,
|
|
280
|
+
onChange: (e) => setVolume(Number(e.currentTarget.value))
|
|
281
|
+
}
|
|
282
|
+
)
|
|
283
|
+
] }) }),
|
|
284
|
+
/* @__PURE__ */ jsx3(SoundButton, { onClick: () => toggleMute(), children: /* @__PURE__ */ jsx3(Volume, { title: isMuted ? "Mute" : "Unmute" }) })
|
|
285
|
+
] })
|
|
286
|
+
] });
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
// src/Annotation/AudioAnnotation/create-audio-annotation.tsx
|
|
290
|
+
import { CanvasPanel } from "react-iiif-vault";
|
|
291
|
+
import { getValue } from "@iiif/helpers";
|
|
292
|
+
import { Input, InputContainer, InputLabel, LanguageFieldEditor, FormFieldWrapper } from "@manifest-editor/editors";
|
|
47
293
|
|
|
48
294
|
// ../ui/atoms/Button.tsx
|
|
49
|
-
import
|
|
50
|
-
var ButtonReset =
|
|
295
|
+
import styled4 from "styled-components";
|
|
296
|
+
var ButtonReset = styled4.button`
|
|
51
297
|
border: none;
|
|
52
298
|
outline: none;
|
|
53
299
|
background-color: transparent;
|
|
@@ -60,7 +306,7 @@ var ButtonReset = styled.button`
|
|
|
60
306
|
color: inherit;
|
|
61
307
|
}
|
|
62
308
|
`;
|
|
63
|
-
var Button =
|
|
309
|
+
var Button = styled4.button`
|
|
64
310
|
padding: 0.5rem 1rem;
|
|
65
311
|
color: ${(props) => props.theme.color.main || "none"};
|
|
66
312
|
background-color: ${(props) => props.theme.color.white || "white"};
|
|
@@ -79,12 +325,12 @@ var Button = styled.button`
|
|
|
79
325
|
background: #eee;
|
|
80
326
|
}
|
|
81
327
|
`;
|
|
82
|
-
var SmallButton =
|
|
328
|
+
var SmallButton = styled4(Button)`
|
|
83
329
|
padding: 0.25em ${(props) => props.theme.padding.xs || "0.4em"};
|
|
84
330
|
height: unset;
|
|
85
331
|
background: none;
|
|
86
332
|
`;
|
|
87
|
-
var SecondaryButton =
|
|
333
|
+
var SecondaryButton = styled4(Button)`
|
|
88
334
|
{
|
|
89
335
|
padding: 0 ${(props) => props.theme.padding.medium || "1rem"};
|
|
90
336
|
color: ${(props) => props.theme.color.main || "#B84C74;"};
|
|
@@ -104,7 +350,7 @@ var SecondaryButton = styled(Button)`
|
|
|
104
350
|
}
|
|
105
351
|
}
|
|
106
352
|
`;
|
|
107
|
-
var CalltoButton =
|
|
353
|
+
var CalltoButton = styled4(Button)`
|
|
108
354
|
padding: 0 ${(props) => props.theme.padding.medium || "1rem"};
|
|
109
355
|
color: ${(props) => props.theme.color.white || "white"};
|
|
110
356
|
background-color: ${(props) => props.theme.color.main || "#B84C74;"};
|
|
@@ -118,7 +364,7 @@ var CalltoButton = styled(Button)`
|
|
|
118
364
|
background-color: ${(props) => props.theme.color.mainHover || "#B84C74;"};
|
|
119
365
|
}
|
|
120
366
|
`;
|
|
121
|
-
var ButtonGroup =
|
|
367
|
+
var ButtonGroup = styled4.div`
|
|
122
368
|
display: flex;
|
|
123
369
|
flex-direction: row;
|
|
124
370
|
flex-wrap: wrap;
|
|
@@ -126,212 +372,138 @@ var ButtonGroup = styled.div`
|
|
|
126
372
|
justify-content: ${(props) => props.$right ? "flex-end" : "flex-start"};
|
|
127
373
|
`;
|
|
128
374
|
|
|
129
|
-
//
|
|
130
|
-
import
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
overflow: visible;
|
|
136
|
-
`;
|
|
137
|
-
|
|
138
|
-
// src/ContentResource/PlaintextCreator/create-plaintext.tsx
|
|
139
|
-
import { useState } from "react";
|
|
140
|
-
import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
141
|
-
async function createPlaintext(data, ctx) {
|
|
142
|
-
return ctx.embed({
|
|
143
|
-
id: data.url,
|
|
144
|
-
type: "Text",
|
|
145
|
-
label: data.label,
|
|
146
|
-
format: "text/plain"
|
|
147
|
-
});
|
|
148
|
-
}
|
|
149
|
-
function CreatePlaintextForm(props) {
|
|
150
|
-
const [label, setLabel] = useState({ en: ["View as text"] });
|
|
151
|
-
const onSubmit = (e) => {
|
|
152
|
-
e.preventDefault();
|
|
153
|
-
const data = new FormData(e.target);
|
|
154
|
-
const formData = Object.fromEntries(data.entries());
|
|
155
|
-
if (formData.url) {
|
|
156
|
-
props.runCreate({ url: formData.url, label });
|
|
157
|
-
}
|
|
375
|
+
// src/Annotation/AudioAnnotation/create-audio-annotation.tsx
|
|
376
|
+
import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
377
|
+
async function createAudioAnnotation(data, ctx) {
|
|
378
|
+
const annotation = {
|
|
379
|
+
id: ctx.generateId("annotation"),
|
|
380
|
+
type: "Annotation"
|
|
158
381
|
};
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
LanguageFieldEditor,
|
|
162
|
-
{
|
|
163
|
-
focusId: "label",
|
|
164
|
-
label: "Label",
|
|
165
|
-
fields: label,
|
|
166
|
-
onSave: (e) => setLabel(e.toInternationalString())
|
|
167
|
-
}
|
|
168
|
-
),
|
|
169
|
-
/* @__PURE__ */ jsxs2(InputContainer, { $wide: true, children: [
|
|
170
|
-
/* @__PURE__ */ jsx3(InputLabel, { htmlFor: "id", children: "Link to plaintext" }),
|
|
171
|
-
/* @__PURE__ */ jsx3(Input, { id: "url", name: "url", defaultValue: "" })
|
|
172
|
-
] }),
|
|
173
|
-
/* @__PURE__ */ jsx3(Button, { type: "submit", children: "Create" })
|
|
174
|
-
] }) });
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
// src/ContentResource/PlaintextCreator/index.tsx
|
|
178
|
-
import { jsx as jsx4 } from "react/jsx-runtime";
|
|
179
|
-
var plaintextCreator = {
|
|
180
|
-
id: "@manifest-editor/plaintext-creator",
|
|
181
|
-
create: createPlaintext,
|
|
182
|
-
label: "Plaintext",
|
|
183
|
-
summary: "Add link to an plaintext",
|
|
184
|
-
icon: /* @__PURE__ */ jsx4(TextFormatIcon, {}),
|
|
185
|
-
render(ctx) {
|
|
186
|
-
return /* @__PURE__ */ jsx4(CreatePlaintextForm, { ...ctx });
|
|
187
|
-
},
|
|
188
|
-
resourceType: "ContentResource",
|
|
189
|
-
resourceFields: ["label", "format"],
|
|
190
|
-
supports: {
|
|
191
|
-
parentFields: ["seeAlso", "rendering", "homepage"]
|
|
192
|
-
},
|
|
193
|
-
staticFields: {
|
|
194
|
-
format: "text/plain"
|
|
195
|
-
}
|
|
196
|
-
};
|
|
197
|
-
|
|
198
|
-
// src/ContentResource/WebPageCreator/create-web-page.tsx
|
|
199
|
-
import { LanguageFieldEditor as LanguageFieldEditor2, InputContainer as InputContainer2, InputLabel as InputLabel2, Input as Input2 } from "@manifest-editor/editors";
|
|
200
|
-
import { useState as useState2 } from "react";
|
|
201
|
-
import { jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
202
|
-
async function createWebPage(data, ctx) {
|
|
203
|
-
return ctx.embed({
|
|
382
|
+
const targetType = ctx.options.targetType;
|
|
383
|
+
const body = await ctx.embed({
|
|
204
384
|
id: data.url,
|
|
205
|
-
type: "
|
|
206
|
-
|
|
207
|
-
|
|
385
|
+
type: "Sound",
|
|
386
|
+
format: "audio/mp4",
|
|
387
|
+
duration: data.duration || 0
|
|
208
388
|
});
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
import { jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
240
|
-
function LinkIcon() {
|
|
241
|
-
return /* @__PURE__ */ jsxs4("svg", { xmlns: "http://www.w3.org/2000/svg", height: "24px", viewBox: "0 0 24 24", width: "24px", fill: "#000000", children: [
|
|
242
|
-
/* @__PURE__ */ jsx6("path", { d: "M0 0h24v24H0z", fill: "none" }),
|
|
243
|
-
/* @__PURE__ */ jsx6("path", { d: "M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76 0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71 0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71 0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76 0 5-2.24 5-5s-2.24-5-5-5z" })
|
|
244
|
-
] });
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
// src/ContentResource/WebPageCreator/index.tsx
|
|
248
|
-
import { jsx as jsx7 } from "react/jsx-runtime";
|
|
249
|
-
var webPageCreator = {
|
|
250
|
-
id: "@manifest-editor/web-page-creator",
|
|
251
|
-
create: createWebPage,
|
|
252
|
-
label: "Web page",
|
|
253
|
-
summary: "Add link to an external web page",
|
|
254
|
-
icon: /* @__PURE__ */ jsx7(LinkIcon, {}),
|
|
255
|
-
render(ctx) {
|
|
256
|
-
return /* @__PURE__ */ jsx7(CreateWebPageForm, { ...ctx });
|
|
257
|
-
},
|
|
258
|
-
resourceType: "ContentResource",
|
|
259
|
-
resourceFields: ["label", "format"],
|
|
260
|
-
supports: {
|
|
261
|
-
parentFields: ["seeAlso", "rendering", "homepage"]
|
|
389
|
+
if (targetType === "Annotation") {
|
|
390
|
+
return ctx.embed({
|
|
391
|
+
...annotation,
|
|
392
|
+
label: getValue(data.label) && data.label,
|
|
393
|
+
motivation: data.motivation || ctx.options.initialData?.motivation || "painting",
|
|
394
|
+
body,
|
|
395
|
+
target: ctx.getTarget()
|
|
396
|
+
});
|
|
397
|
+
}
|
|
398
|
+
if (targetType === "Canvas") {
|
|
399
|
+
const canvasId = ctx.generateId("canvas");
|
|
400
|
+
const pageId = ctx.generateId("annotation-page", { id: canvasId, type: "Canvas" });
|
|
401
|
+
const annotationResource = ctx.embed({
|
|
402
|
+
...annotation,
|
|
403
|
+
motivation: "painting",
|
|
404
|
+
body,
|
|
405
|
+
target: { type: "SpecificResource", source: { id: canvasId, type: "Canvas" } }
|
|
406
|
+
});
|
|
407
|
+
const page = ctx.embed({
|
|
408
|
+
id: pageId,
|
|
409
|
+
type: "AnnotationPage",
|
|
410
|
+
items: [annotationResource]
|
|
411
|
+
});
|
|
412
|
+
return ctx.embed({
|
|
413
|
+
id: canvasId,
|
|
414
|
+
type: "Canvas",
|
|
415
|
+
label: data.label || { en: ["Untitled HTML canvas"] },
|
|
416
|
+
duration: data.duration || 0,
|
|
417
|
+
items: [page]
|
|
418
|
+
});
|
|
262
419
|
}
|
|
263
|
-
};
|
|
264
|
-
|
|
265
|
-
// src/ContentResource/HTMLBodyCreator/create-html-body.tsx
|
|
266
|
-
import { InputContainer as InputContainer3, InputLabel as InputLabel3, RichTextLanguageField } from "@manifest-editor/editors";
|
|
267
|
-
import { useConfig } from "@manifest-editor/shell";
|
|
268
|
-
import { useState as useState3 } from "react";
|
|
269
|
-
import { jsx as jsx8, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
270
|
-
async function createHtmlBody(data, ctx) {
|
|
271
|
-
return ctx.embed({
|
|
272
|
-
id: ctx.generateId(`html/${data.language}`),
|
|
273
|
-
language: data.language,
|
|
274
|
-
type: "TextualBody",
|
|
275
|
-
format: "text/html",
|
|
276
|
-
value: data.body || ""
|
|
277
|
-
});
|
|
278
420
|
}
|
|
279
|
-
function
|
|
280
|
-
const
|
|
281
|
-
const [
|
|
282
|
-
const [
|
|
421
|
+
function CreateAudioAnnotationForm(props) {
|
|
422
|
+
const [url, setUrl] = useState2("");
|
|
423
|
+
const [duration, setDuration] = useState2(0);
|
|
424
|
+
const [error, setError] = useState2("");
|
|
425
|
+
const [label, setLabel] = useState2({ en: [""] });
|
|
283
426
|
const onSubmit = () => {
|
|
284
427
|
props.runCreate({
|
|
285
|
-
|
|
286
|
-
|
|
428
|
+
url,
|
|
429
|
+
duration,
|
|
430
|
+
label
|
|
287
431
|
});
|
|
288
432
|
};
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
)
|
|
433
|
+
useEffect2(() => {
|
|
434
|
+
setError("");
|
|
435
|
+
setDuration(0);
|
|
436
|
+
if (url) {
|
|
437
|
+
const labelFromUrl = url.split("/").pop()?.split(".").shift();
|
|
438
|
+
setLabel({ en: [labelFromUrl || ""] });
|
|
439
|
+
}
|
|
440
|
+
}, [url]);
|
|
441
|
+
return /* @__PURE__ */ jsxs4(PaddedSidebarContainer, { children: [
|
|
442
|
+
error ? /* @__PURE__ */ jsx4(ErrorMessage, { children: error }) : null,
|
|
443
|
+
/* @__PURE__ */ jsxs4(InputContainer, { children: [
|
|
444
|
+
/* @__PURE__ */ jsx4(InputLabel, { htmlFor: "audio-url", children: "URL" }),
|
|
445
|
+
/* @__PURE__ */ jsx4(Input, { type: "text", id: "audio-url", value: url, onChange: (e) => setUrl(e.target.value) })
|
|
302
446
|
] }),
|
|
303
|
-
/* @__PURE__ */
|
|
447
|
+
url && !error ? /* @__PURE__ */ jsx4("div", { children: /* @__PURE__ */ jsx4(
|
|
448
|
+
LanguageFieldEditor,
|
|
449
|
+
{
|
|
450
|
+
containerId: "label",
|
|
451
|
+
focusId: "label_",
|
|
452
|
+
label: "Label",
|
|
453
|
+
fields: label,
|
|
454
|
+
onSave: (e) => setLabel(e.toInternationalString())
|
|
455
|
+
},
|
|
456
|
+
url + "__" + duration
|
|
457
|
+
) }) : null,
|
|
458
|
+
url && !error ? /* @__PURE__ */ jsx4(CanvasPanel.AudioHTML, { media: { url, duration, type: "Sound" }, children: /* @__PURE__ */ jsx4(
|
|
459
|
+
MediaControls,
|
|
460
|
+
{
|
|
461
|
+
onError: (error2) => setError(error2),
|
|
462
|
+
onDuration: (duration2) => setDuration(duration2)
|
|
463
|
+
},
|
|
464
|
+
url + "__" + duration
|
|
465
|
+
) }, url + "__" + duration) : null,
|
|
466
|
+
duration && !error ? /* @__PURE__ */ jsxs4(FormFieldWrapper, { children: [
|
|
467
|
+
/* @__PURE__ */ jsx4(InputLabel, { htmlFor: "duration", children: "Duration" }),
|
|
468
|
+
/* @__PURE__ */ jsx4(Input, { type: "number", id: "duration", value: duration, onChange: (e) => setDuration(e.target.valueAsNumber) })
|
|
469
|
+
] }) : null,
|
|
470
|
+
url && !error && /* @__PURE__ */ jsx4(Button, { onClick: onSubmit, children: "Add audio" })
|
|
304
471
|
] });
|
|
305
472
|
}
|
|
306
473
|
|
|
307
|
-
// src/
|
|
308
|
-
import {
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
474
|
+
// src/Annotation/AudioAnnotation/index.tsx
|
|
475
|
+
import { AudioIcon } from "@manifest-editor/components";
|
|
476
|
+
import { jsx as jsx5 } from "react/jsx-runtime";
|
|
477
|
+
var audioAnnotation = {
|
|
478
|
+
id: "@manifest-editor/audio-annotation",
|
|
479
|
+
create: createAudioAnnotation,
|
|
480
|
+
label: "Audio",
|
|
481
|
+
summary: "Audio annotation",
|
|
482
|
+
icon: /* @__PURE__ */ jsx5(AudioIcon, {}),
|
|
315
483
|
render(ctx) {
|
|
316
|
-
return /* @__PURE__ */
|
|
484
|
+
return /* @__PURE__ */ jsx5(CreateAudioAnnotationForm, { ...ctx });
|
|
317
485
|
},
|
|
318
|
-
resourceType: "
|
|
319
|
-
resourceFields: ["id", "
|
|
486
|
+
resourceType: "Annotation",
|
|
487
|
+
resourceFields: ["id", "type", "motivation", "body", "target"],
|
|
488
|
+
additionalTypes: ["Canvas"],
|
|
320
489
|
supports: {
|
|
321
|
-
|
|
322
|
-
|
|
490
|
+
initialData: true,
|
|
491
|
+
parentTypes: ["AnnotationPage", "Manifest"],
|
|
492
|
+
parentFields: ["items"]
|
|
323
493
|
},
|
|
324
494
|
staticFields: {
|
|
325
|
-
type: "
|
|
326
|
-
format: "text/html"
|
|
495
|
+
type: "Annotation"
|
|
327
496
|
}
|
|
328
497
|
};
|
|
329
498
|
|
|
330
|
-
// src/Annotation/
|
|
331
|
-
import {
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
499
|
+
// src/Annotation/CaptionedImageAnnotation/index.tsx
|
|
500
|
+
import { AddImageIcon } from "@manifest-editor/components";
|
|
501
|
+
|
|
502
|
+
// src/Annotation/CaptionedImageAnnotation/create-captioned-image-annotation.tsx
|
|
503
|
+
import { Input as Input2, InputContainer as InputContainer2, InputLabel as InputLabel2, LanguageFieldEditor as LanguageFieldEditor2 } from "@manifest-editor/editors";
|
|
504
|
+
import { useState as useState3 } from "react";
|
|
505
|
+
import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
506
|
+
async function createCaptionedImageAnnotation(data, ctx) {
|
|
335
507
|
const annotation = {
|
|
336
508
|
id: ctx.generateId("annotation"),
|
|
337
509
|
type: "Annotation"
|
|
@@ -354,6 +526,16 @@ async function createHtmlAnnotation(data, ctx) {
|
|
|
354
526
|
);
|
|
355
527
|
}
|
|
356
528
|
}
|
|
529
|
+
const resource = await ctx.create(
|
|
530
|
+
"@manifest-editor/image-url-creator",
|
|
531
|
+
{ url: data.imageUrl },
|
|
532
|
+
{
|
|
533
|
+
parent: { resource: annotation, property: "body" }
|
|
534
|
+
}
|
|
535
|
+
);
|
|
536
|
+
if (resource) {
|
|
537
|
+
bodies.push(resource);
|
|
538
|
+
}
|
|
357
539
|
if (targetType === "Annotation") {
|
|
358
540
|
return ctx.embed({
|
|
359
541
|
...annotation,
|
|
@@ -364,12 +546,18 @@ async function createHtmlAnnotation(data, ctx) {
|
|
|
364
546
|
}
|
|
365
547
|
if (targetType === "Canvas") {
|
|
366
548
|
const canvasId = ctx.generateId("canvas");
|
|
367
|
-
const pageId = ctx.generateId("annotation-page", {
|
|
549
|
+
const pageId = ctx.generateId("annotation-page", {
|
|
550
|
+
id: canvasId,
|
|
551
|
+
type: "Canvas"
|
|
552
|
+
});
|
|
368
553
|
const annotationResource = ctx.embed({
|
|
369
554
|
...annotation,
|
|
370
555
|
motivation: "painting",
|
|
371
556
|
body: bodies,
|
|
372
|
-
target: {
|
|
557
|
+
target: {
|
|
558
|
+
type: "SpecificResource",
|
|
559
|
+
source: { id: canvasId, type: "Canvas" }
|
|
560
|
+
}
|
|
373
561
|
});
|
|
374
562
|
const page = ctx.embed({
|
|
375
563
|
id: pageId,
|
|
@@ -386,18 +574,26 @@ async function createHtmlAnnotation(data, ctx) {
|
|
|
386
574
|
});
|
|
387
575
|
}
|
|
388
576
|
}
|
|
389
|
-
function
|
|
390
|
-
const [body, setBody] =
|
|
391
|
-
const onSubmit = () => {
|
|
577
|
+
function CreateCaptionedImageAnnotation(props) {
|
|
578
|
+
const [body, setBody] = useState3({ en: [""] });
|
|
579
|
+
const onSubmit = (e) => {
|
|
580
|
+
e.preventDefault();
|
|
581
|
+
const data = new FormData(e.target);
|
|
582
|
+
const formData = Object.fromEntries(data.entries());
|
|
392
583
|
props.runCreate({
|
|
393
|
-
body
|
|
584
|
+
body,
|
|
585
|
+
imageUrl: formData.url
|
|
394
586
|
});
|
|
395
587
|
};
|
|
396
|
-
return /* @__PURE__ */
|
|
397
|
-
/* @__PURE__ */
|
|
398
|
-
/* @__PURE__ */
|
|
399
|
-
/* @__PURE__ */
|
|
400
|
-
|
|
588
|
+
return /* @__PURE__ */ jsx6("form", { onSubmit, children: /* @__PURE__ */ jsxs5(PaddedSidebarContainer, { children: [
|
|
589
|
+
/* @__PURE__ */ jsx6(InputContainer2, { children: /* @__PURE__ */ jsxs5(InputContainer2, { $wide: true, children: [
|
|
590
|
+
/* @__PURE__ */ jsx6(InputLabel2, { htmlFor: "id", children: "Link to Image" }),
|
|
591
|
+
/* @__PURE__ */ jsx6(Input2, { id: "url", name: "url", defaultValue: "" })
|
|
592
|
+
] }) }),
|
|
593
|
+
/* @__PURE__ */ jsxs5(InputContainer2, { children: [
|
|
594
|
+
/* @__PURE__ */ jsx6(InputLabel2, { children: "Image Caption" }),
|
|
595
|
+
/* @__PURE__ */ jsx6(
|
|
596
|
+
LanguageFieldEditor2,
|
|
401
597
|
{
|
|
402
598
|
focusId: "html-content",
|
|
403
599
|
label: "HTML Content",
|
|
@@ -406,28 +602,27 @@ function CreateHTMLAnnotation(props) {
|
|
|
406
602
|
}
|
|
407
603
|
)
|
|
408
604
|
] }),
|
|
409
|
-
/* @__PURE__ */
|
|
410
|
-
] });
|
|
605
|
+
/* @__PURE__ */ jsx6(Button, { type: "submit", children: "Create" })
|
|
606
|
+
] }) });
|
|
411
607
|
}
|
|
412
608
|
|
|
413
|
-
// src/Annotation/
|
|
414
|
-
import {
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
icon: /* @__PURE__ */ jsx11(HTMLIcon, {}),
|
|
609
|
+
// src/Annotation/CaptionedImageAnnotation/index.tsx
|
|
610
|
+
import { jsx as jsx7 } from "react/jsx-runtime";
|
|
611
|
+
var captionedImageAnnotation = {
|
|
612
|
+
id: "@manifest-editor/captioned-image-annotation",
|
|
613
|
+
create: createCaptionedImageAnnotation,
|
|
614
|
+
label: "Captioned image",
|
|
615
|
+
summary: "Add an image from a URL with caption",
|
|
616
|
+
icon: /* @__PURE__ */ jsx7(AddImageIcon, {}),
|
|
422
617
|
render(ctx) {
|
|
423
|
-
return /* @__PURE__ */
|
|
618
|
+
return /* @__PURE__ */ jsx7(CreateCaptionedImageAnnotation, { ...ctx });
|
|
424
619
|
},
|
|
425
620
|
resourceType: "Annotation",
|
|
426
621
|
resourceFields: ["id", "type", "motivation", "body", "target"],
|
|
427
622
|
additionalTypes: ["Canvas"],
|
|
428
623
|
supports: {
|
|
429
624
|
initialData: true,
|
|
430
|
-
parentTypes: ["AnnotationPage"
|
|
625
|
+
parentTypes: ["AnnotationPage"],
|
|
431
626
|
parentFields: ["items"]
|
|
432
627
|
},
|
|
433
628
|
staticFields: {
|
|
@@ -435,306 +630,121 @@ var htmlAnnotation = {
|
|
|
435
630
|
}
|
|
436
631
|
};
|
|
437
632
|
|
|
438
|
-
//
|
|
439
|
-
import {
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
)
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
parentTypes: ["Manifest", "Canvas", "Range"],
|
|
468
|
-
parentFieldMap: {
|
|
469
|
-
Manifest: ["annotations"],
|
|
470
|
-
Canvas: ["items", "annotations"],
|
|
471
|
-
Range: ["annotations"]
|
|
633
|
+
// src/Annotation/HTMLAnnotation/create-html-annotation.tsx
|
|
634
|
+
import { useState as useState4 } from "react";
|
|
635
|
+
import {
|
|
636
|
+
InputContainer as InputContainer3,
|
|
637
|
+
InputLabel as InputLabel3,
|
|
638
|
+
LanguageFieldEditor as LanguageFieldEditor3
|
|
639
|
+
} from "@manifest-editor/editors";
|
|
640
|
+
import { jsx as jsx8, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
641
|
+
async function createHtmlAnnotation(data, ctx) {
|
|
642
|
+
const annotation = {
|
|
643
|
+
id: ctx.generateId("annotation"),
|
|
644
|
+
type: "Annotation"
|
|
645
|
+
};
|
|
646
|
+
const targetType = ctx.options.targetType;
|
|
647
|
+
const languages = Object.keys(data.body);
|
|
648
|
+
const bodies = [];
|
|
649
|
+
for (const language of languages) {
|
|
650
|
+
const body = data.body[language].join("\n");
|
|
651
|
+
if (body) {
|
|
652
|
+
bodies.push(
|
|
653
|
+
await ctx.create(
|
|
654
|
+
"@manifest-editor/html-body-creator",
|
|
655
|
+
{
|
|
656
|
+
language,
|
|
657
|
+
body
|
|
658
|
+
},
|
|
659
|
+
{ parent: { resource: annotation, property: "items" } }
|
|
660
|
+
)
|
|
661
|
+
);
|
|
472
662
|
}
|
|
473
663
|
}
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
}
|
|
482
|
-
|
|
483
|
-
// src/ContentResource/YouTubeCreator/index.tsx
|
|
484
|
-
import { YouTubeIcon } from "@manifest-editor/components";
|
|
485
|
-
|
|
486
|
-
// src/ContentResource/YouTubeCreator/create-youtube-body.tsx
|
|
487
|
-
import { InputContainer as InputContainer5, InputLabel as InputLabel5, Input as Input3 } from "@manifest-editor/editors";
|
|
488
|
-
import { jsx as jsx14, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
489
|
-
var ytRegex = /^.*(?:(?:youtu\.be\/|v\/|vi\/|u\/\w\/|embed\/|shorts\/)|(?:(?:watch)?\?vi?=|&vi?=))([^#&?]*).*/;
|
|
490
|
-
function getYouTubeId(url) {
|
|
491
|
-
const id = (url || "").match(ytRegex);
|
|
492
|
-
return id ? id[1] : null;
|
|
493
|
-
}
|
|
494
|
-
async function createYoutubeBody(data, ctx) {
|
|
495
|
-
const id = getYouTubeId(data.youtubeUrl);
|
|
496
|
-
const body = ctx.embed({
|
|
497
|
-
id: `https://www.youtube.com/watch?v=${id}`,
|
|
498
|
-
type: "Video",
|
|
499
|
-
service: [
|
|
500
|
-
{
|
|
501
|
-
profile: "http://digirati.com/objectifier",
|
|
502
|
-
params: {
|
|
503
|
-
data: `https://www.youtube.com/embed/${id}`
|
|
504
|
-
}
|
|
505
|
-
},
|
|
506
|
-
{
|
|
507
|
-
id: `https://www.youtube.com/watch?v=${id}`,
|
|
508
|
-
profile: "https://www.youtube.com"
|
|
509
|
-
}
|
|
510
|
-
]
|
|
511
|
-
});
|
|
512
|
-
if (ctx.options.targetType === "Canvas") {
|
|
664
|
+
if (targetType === "Annotation") {
|
|
665
|
+
return ctx.embed({
|
|
666
|
+
...annotation,
|
|
667
|
+
motivation: data.motivation || ctx.options.initialData?.motivation || "painting",
|
|
668
|
+
body: bodies,
|
|
669
|
+
target: ctx.getTarget()
|
|
670
|
+
});
|
|
671
|
+
}
|
|
672
|
+
if (targetType === "Canvas") {
|
|
513
673
|
const canvasId = ctx.generateId("canvas");
|
|
514
|
-
const pageId = ctx.generateId("annotation-page", {
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
674
|
+
const pageId = ctx.generateId("annotation-page", {
|
|
675
|
+
id: canvasId,
|
|
676
|
+
type: "Canvas"
|
|
677
|
+
});
|
|
678
|
+
const annotationResource = ctx.embed({
|
|
679
|
+
...annotation,
|
|
518
680
|
motivation: "painting",
|
|
519
|
-
body:
|
|
520
|
-
target: {
|
|
681
|
+
body: bodies,
|
|
682
|
+
target: {
|
|
683
|
+
type: "SpecificResource",
|
|
684
|
+
source: { id: canvasId, type: "Canvas" }
|
|
685
|
+
}
|
|
521
686
|
});
|
|
522
687
|
const page = ctx.embed({
|
|
523
688
|
id: pageId,
|
|
524
689
|
type: "AnnotationPage",
|
|
525
|
-
items: [
|
|
690
|
+
items: [annotationResource]
|
|
526
691
|
});
|
|
527
692
|
return ctx.embed({
|
|
528
693
|
id: canvasId,
|
|
529
694
|
type: "Canvas",
|
|
530
|
-
label: data.label || { en: ["Untitled
|
|
695
|
+
label: data.label || { en: ["Untitled HTML canvas"] },
|
|
531
696
|
height: data.height || 1e3,
|
|
532
697
|
width: data.width || 1e3,
|
|
533
|
-
duration: data.duration || 1,
|
|
534
698
|
items: [page]
|
|
535
699
|
});
|
|
536
700
|
}
|
|
537
|
-
if (ctx.options.targetType === "Annotation" || ctx.options.targetType === "Canvas") {
|
|
538
|
-
return ctx.embed({
|
|
539
|
-
id: ctx.generateId("annotation"),
|
|
540
|
-
type: "Annotation",
|
|
541
|
-
motivation: "painting",
|
|
542
|
-
body: [body],
|
|
543
|
-
target: ctx.getTarget()
|
|
544
|
-
});
|
|
545
|
-
}
|
|
546
|
-
return body;
|
|
547
|
-
}
|
|
548
|
-
function YouTubeForm(props) {
|
|
549
|
-
const onSubmit = (e) => {
|
|
550
|
-
e.preventDefault();
|
|
551
|
-
const data = new FormData(e.target);
|
|
552
|
-
const formData = Object.fromEntries(data.entries());
|
|
553
|
-
if (formData.youtubeUrl) {
|
|
554
|
-
props.runCreate({ youtubeUrl: formData.youtubeUrl });
|
|
555
|
-
}
|
|
556
|
-
};
|
|
557
|
-
return /* @__PURE__ */ jsx14(PaddedSidebarContainer, { children: /* @__PURE__ */ jsxs8("form", { onSubmit, children: [
|
|
558
|
-
/* @__PURE__ */ jsxs8(InputContainer5, { $wide: true, children: [
|
|
559
|
-
/* @__PURE__ */ jsx14(InputLabel5, { htmlFor: "id", children: "Link to YouTube" }),
|
|
560
|
-
/* @__PURE__ */ jsx14(Input3, { id: "youtubeUrl", name: "youtubeUrl", defaultValue: "" })
|
|
561
|
-
] }),
|
|
562
|
-
/* @__PURE__ */ jsx14(Button, { type: "submit", children: "Create" })
|
|
563
|
-
] }) });
|
|
564
|
-
}
|
|
565
|
-
|
|
566
|
-
// src/ContentResource/YouTubeCreator/index.tsx
|
|
567
|
-
import { jsx as jsx15 } from "react/jsx-runtime";
|
|
568
|
-
var youTubeBodyCreator = {
|
|
569
|
-
id: "@manifest-editor/youtube",
|
|
570
|
-
create: createYoutubeBody,
|
|
571
|
-
label: "YouTube",
|
|
572
|
-
summary: "Embed YouTube",
|
|
573
|
-
icon: /* @__PURE__ */ jsx15(YouTubeIcon, {}),
|
|
574
|
-
resourceType: "ContentResource",
|
|
575
|
-
additionalTypes: ["Canvas", "Annotation"],
|
|
576
|
-
resourceFields: ["id", "type", "service"],
|
|
577
|
-
render: (ctx) => /* @__PURE__ */ jsx15(YouTubeForm, { ...ctx }),
|
|
578
|
-
supports: {
|
|
579
|
-
parentTypes: ["Annotation", "Manifest", "AnnotationPage"],
|
|
580
|
-
parentFieldMap: {
|
|
581
|
-
Annotation: ["body"],
|
|
582
|
-
Manifest: ["items"],
|
|
583
|
-
AnnotationPage: ["items"]
|
|
584
|
-
}
|
|
585
|
-
},
|
|
586
|
-
staticFields: {
|
|
587
|
-
type: "Video"
|
|
588
|
-
}
|
|
589
|
-
};
|
|
590
|
-
|
|
591
|
-
// src/ContentResource/ImageUrlCreator/create-image-url.tsx
|
|
592
|
-
import { InputContainer as InputContainer6, InputLabel as InputLabel6, Input as Input4 } from "@manifest-editor/editors";
|
|
593
|
-
import { getImageDimensions, getFormat } from "@manifest-editor/shell";
|
|
594
|
-
import { jsx as jsx16, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
595
|
-
async function createImageUrl(data, ctx) {
|
|
596
|
-
if (!data.height || !data.width) {
|
|
597
|
-
const dimensions = await getImageDimensions(data.url);
|
|
598
|
-
if (dimensions) {
|
|
599
|
-
data.height = dimensions.height;
|
|
600
|
-
data.width = dimensions.width;
|
|
601
|
-
}
|
|
602
|
-
}
|
|
603
|
-
return ctx.embed({
|
|
604
|
-
id: data.url,
|
|
605
|
-
type: "Image",
|
|
606
|
-
format: data.format || await getFormat(data.url),
|
|
607
|
-
height: data.height,
|
|
608
|
-
width: data.width,
|
|
609
|
-
service: data.service ? Array.isArray(data.service) ? data.service : [data.service] : void 0
|
|
610
|
-
});
|
|
611
701
|
}
|
|
612
|
-
function
|
|
613
|
-
const
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
props.runCreate({ url: formData.url });
|
|
619
|
-
}
|
|
702
|
+
function CreateHTMLAnnotation(props) {
|
|
703
|
+
const [body, setBody] = useState4({ en: [""] });
|
|
704
|
+
const onSubmit = () => {
|
|
705
|
+
props.runCreate({
|
|
706
|
+
body
|
|
707
|
+
});
|
|
620
708
|
};
|
|
621
|
-
return /* @__PURE__ */
|
|
622
|
-
/* @__PURE__ */
|
|
623
|
-
/* @__PURE__ */
|
|
624
|
-
/* @__PURE__ */
|
|
709
|
+
return /* @__PURE__ */ jsxs6(PaddedSidebarContainer, { children: [
|
|
710
|
+
/* @__PURE__ */ jsxs6(InputContainer3, { children: [
|
|
711
|
+
/* @__PURE__ */ jsx8(InputLabel3, { children: "HTML Body" }),
|
|
712
|
+
/* @__PURE__ */ jsx8(
|
|
713
|
+
LanguageFieldEditor3,
|
|
714
|
+
{
|
|
715
|
+
focusId: "html-content",
|
|
716
|
+
label: "HTML Content",
|
|
717
|
+
fields: body,
|
|
718
|
+
onSave: (e) => setBody(e.toInternationalString())
|
|
719
|
+
}
|
|
720
|
+
)
|
|
625
721
|
] }),
|
|
626
|
-
/* @__PURE__ */
|
|
627
|
-
] })
|
|
722
|
+
/* @__PURE__ */ jsx8(Button, { onClick: () => onSubmit(), children: "Create" })
|
|
723
|
+
] });
|
|
628
724
|
}
|
|
629
725
|
|
|
630
|
-
// src/
|
|
631
|
-
import {
|
|
632
|
-
import { jsx as
|
|
633
|
-
var
|
|
634
|
-
id: "@manifest-editor/
|
|
635
|
-
create:
|
|
636
|
-
label: "
|
|
637
|
-
summary: "
|
|
638
|
-
icon: /* @__PURE__ */
|
|
726
|
+
// src/Annotation/HTMLAnnotation/index.tsx
|
|
727
|
+
import { HTMLIcon as HTMLIcon2 } from "@manifest-editor/components";
|
|
728
|
+
import { jsx as jsx9 } from "react/jsx-runtime";
|
|
729
|
+
var htmlAnnotation = {
|
|
730
|
+
id: "@manifest-editor/html-annotation",
|
|
731
|
+
create: createHtmlAnnotation,
|
|
732
|
+
label: "HTML",
|
|
733
|
+
summary: "HTML annotation",
|
|
734
|
+
icon: /* @__PURE__ */ jsx9(HTMLIcon2, {}),
|
|
639
735
|
render(ctx) {
|
|
640
|
-
return /* @__PURE__ */
|
|
736
|
+
return /* @__PURE__ */ jsx9(CreateHTMLAnnotation, { ...ctx });
|
|
641
737
|
},
|
|
642
|
-
resourceType: "
|
|
643
|
-
resourceFields: ["
|
|
738
|
+
resourceType: "Annotation",
|
|
739
|
+
resourceFields: ["id", "type", "motivation", "body", "target"],
|
|
740
|
+
additionalTypes: ["Canvas"],
|
|
644
741
|
supports: {
|
|
645
|
-
|
|
742
|
+
initialData: true,
|
|
743
|
+
parentTypes: ["AnnotationPage", "Manifest"],
|
|
744
|
+
parentFields: ["items"]
|
|
646
745
|
},
|
|
647
746
|
staticFields: {
|
|
648
|
-
type: "
|
|
649
|
-
}
|
|
650
|
-
};
|
|
651
|
-
|
|
652
|
-
// src/ContentResource/ImageServiceCreator/create-image-service.tsx
|
|
653
|
-
import {
|
|
654
|
-
imageServiceRequestToString,
|
|
655
|
-
createImageServiceRequest,
|
|
656
|
-
canonicalServiceUrl
|
|
657
|
-
} from "@iiif/parser/image-3";
|
|
658
|
-
import { InputContainer as InputContainer7, InputLabel as InputLabel7, Input as Input5 } from "@manifest-editor/editors";
|
|
659
|
-
import { jsx as jsx18, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
660
|
-
async function createImageServer(data, ctx) {
|
|
661
|
-
const request = createImageServiceRequest(data.service);
|
|
662
|
-
const imageId = imageServiceRequestToString({
|
|
663
|
-
identifier: request.identifier,
|
|
664
|
-
server: request.server,
|
|
665
|
-
scheme: request.scheme,
|
|
666
|
-
type: "image",
|
|
667
|
-
size: {
|
|
668
|
-
max: !data.size?.width && !data.size?.height,
|
|
669
|
-
confined: false,
|
|
670
|
-
upscaled: false,
|
|
671
|
-
...data.size || {}
|
|
672
|
-
},
|
|
673
|
-
format: "jpg",
|
|
674
|
-
// This isn't how it should be modelled, always full,
|
|
675
|
-
// region: data.selector ? data.selector : { full: true },
|
|
676
|
-
region: { full: true },
|
|
677
|
-
rotation: { angle: 0 },
|
|
678
|
-
quality: "default",
|
|
679
|
-
prefix: request.prefix,
|
|
680
|
-
originalPath: request.originalPath
|
|
681
|
-
});
|
|
682
|
-
const resource = ctx.embed({
|
|
683
|
-
id: imageId,
|
|
684
|
-
type: "Image",
|
|
685
|
-
format: data.format || "image/jpeg",
|
|
686
|
-
height: data.height || data.service.height,
|
|
687
|
-
width: data.width || data.service.width,
|
|
688
|
-
service: data.embedService === false ? void 0 : [data.service]
|
|
689
|
-
});
|
|
690
|
-
return resource;
|
|
691
|
-
}
|
|
692
|
-
function CreateImageServerForm(props) {
|
|
693
|
-
const onSubmit = (e) => {
|
|
694
|
-
e.preventDefault();
|
|
695
|
-
const data = new FormData(e.target);
|
|
696
|
-
const formData = Object.fromEntries(data.entries());
|
|
697
|
-
const url = formData.url;
|
|
698
|
-
if (url) {
|
|
699
|
-
const canon = canonicalServiceUrl(url);
|
|
700
|
-
fetch(canon).then((r) => r.json()).then((service) => {
|
|
701
|
-
if (service["@id"]) {
|
|
702
|
-
service.id = service["@id"];
|
|
703
|
-
}
|
|
704
|
-
if (service["@type"]) {
|
|
705
|
-
service.type = service["@type"];
|
|
706
|
-
}
|
|
707
|
-
props.runCreate({ url: formData.url, service });
|
|
708
|
-
});
|
|
709
|
-
}
|
|
710
|
-
};
|
|
711
|
-
return /* @__PURE__ */ jsx18(PaddedSidebarContainer, { children: /* @__PURE__ */ jsxs10("form", { onSubmit, children: [
|
|
712
|
-
/* @__PURE__ */ jsxs10(InputContainer7, { $wide: true, children: [
|
|
713
|
-
/* @__PURE__ */ jsx18(InputLabel7, { htmlFor: "id", children: "Link to image service" }),
|
|
714
|
-
/* @__PURE__ */ jsx18(Input5, { id: "url", name: "url", defaultValue: "" })
|
|
715
|
-
] }),
|
|
716
|
-
/* @__PURE__ */ jsx18(Button, { type: "submit", children: "Create" })
|
|
717
|
-
] }) });
|
|
718
|
-
}
|
|
719
|
-
|
|
720
|
-
// src/ContentResource/ImageServiceCreator/index.tsx
|
|
721
|
-
import { jsx as jsx19 } from "react/jsx-runtime";
|
|
722
|
-
var imageServiceCreator = {
|
|
723
|
-
id: "@manifest-editor/image-service-creator",
|
|
724
|
-
create: createImageServer,
|
|
725
|
-
label: "Image Service",
|
|
726
|
-
summary: "Add an image from Image Service",
|
|
727
|
-
icon: /* @__PURE__ */ jsx19(TextFormatIcon, {}),
|
|
728
|
-
render(ctx) {
|
|
729
|
-
return /* @__PURE__ */ jsx19(CreateImageServerForm, { ...ctx });
|
|
730
|
-
},
|
|
731
|
-
resourceType: "ContentResource",
|
|
732
|
-
resourceFields: ["id", "type", "height", "width", "format", "service"],
|
|
733
|
-
supports: {
|
|
734
|
-
parentFields: ["logo", "body", "thumbnail"]
|
|
735
|
-
},
|
|
736
|
-
staticFields: {
|
|
737
|
-
type: "Image"
|
|
747
|
+
type: "Annotation"
|
|
738
748
|
}
|
|
739
749
|
};
|
|
740
750
|
|
|
@@ -902,8 +912,76 @@ var resizeToFitService = {
|
|
|
902
912
|
}
|
|
903
913
|
};
|
|
904
914
|
|
|
915
|
+
// src/ContentResource/ImageServiceCreator/create-image-service.tsx
|
|
916
|
+
import {
|
|
917
|
+
imageServiceRequestToString,
|
|
918
|
+
createImageServiceRequest,
|
|
919
|
+
canonicalServiceUrl
|
|
920
|
+
} from "@iiif/parser/image-3";
|
|
921
|
+
import { InputContainer as InputContainer4, InputLabel as InputLabel4, Input as Input3 } from "@manifest-editor/editors";
|
|
922
|
+
import { jsx as jsx10, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
923
|
+
async function createImageServer(data, ctx) {
|
|
924
|
+
const request = createImageServiceRequest(data.service);
|
|
925
|
+
const imageId = imageServiceRequestToString({
|
|
926
|
+
identifier: request.identifier,
|
|
927
|
+
server: request.server,
|
|
928
|
+
scheme: request.scheme,
|
|
929
|
+
type: "image",
|
|
930
|
+
size: {
|
|
931
|
+
max: !data.size?.width && !data.size?.height,
|
|
932
|
+
confined: false,
|
|
933
|
+
upscaled: false,
|
|
934
|
+
...data.size || {}
|
|
935
|
+
},
|
|
936
|
+
format: "jpg",
|
|
937
|
+
// This isn't how it should be modelled, always full,
|
|
938
|
+
// region: data.selector ? data.selector : { full: true },
|
|
939
|
+
region: { full: true },
|
|
940
|
+
rotation: { angle: 0 },
|
|
941
|
+
quality: "default",
|
|
942
|
+
prefix: request.prefix,
|
|
943
|
+
originalPath: request.originalPath
|
|
944
|
+
});
|
|
945
|
+
const resource = ctx.embed({
|
|
946
|
+
id: imageId,
|
|
947
|
+
type: "Image",
|
|
948
|
+
format: data.format || "image/jpeg",
|
|
949
|
+
height: data.height || data.service.height,
|
|
950
|
+
width: data.width || data.service.width,
|
|
951
|
+
service: data.embedService === false ? void 0 : [data.service]
|
|
952
|
+
});
|
|
953
|
+
return resource;
|
|
954
|
+
}
|
|
955
|
+
function CreateImageServerForm(props) {
|
|
956
|
+
const onSubmit = (e) => {
|
|
957
|
+
e.preventDefault();
|
|
958
|
+
const data = new FormData(e.target);
|
|
959
|
+
const formData = Object.fromEntries(data.entries());
|
|
960
|
+
const url = formData.url;
|
|
961
|
+
if (url) {
|
|
962
|
+
const canon = canonicalServiceUrl(url);
|
|
963
|
+
fetch(canon).then((r) => r.json()).then((service) => {
|
|
964
|
+
if (service["@id"]) {
|
|
965
|
+
service.id = service["@id"];
|
|
966
|
+
}
|
|
967
|
+
if (service["@type"]) {
|
|
968
|
+
service.type = service["@type"];
|
|
969
|
+
}
|
|
970
|
+
props.runCreate({ url: formData.url, service });
|
|
971
|
+
});
|
|
972
|
+
}
|
|
973
|
+
};
|
|
974
|
+
return /* @__PURE__ */ jsx10(PaddedSidebarContainer, { children: /* @__PURE__ */ jsxs7("form", { onSubmit, children: [
|
|
975
|
+
/* @__PURE__ */ jsxs7(InputContainer4, { $wide: true, children: [
|
|
976
|
+
/* @__PURE__ */ jsx10(InputLabel4, { htmlFor: "id", children: "Link to image service" }),
|
|
977
|
+
/* @__PURE__ */ jsx10(Input3, { id: "url", name: "url", defaultValue: "" })
|
|
978
|
+
] }),
|
|
979
|
+
/* @__PURE__ */ jsx10(Button, { type: "submit", children: "Create" })
|
|
980
|
+
] }) });
|
|
981
|
+
}
|
|
982
|
+
|
|
905
983
|
// src/Annotation/ImageServiceAnnotation/create-service-annotation.tsx
|
|
906
|
-
import { jsx as
|
|
984
|
+
import { jsx as jsx11 } from "react/jsx-runtime";
|
|
907
985
|
async function createImageServiceAnnotation(data, ctx) {
|
|
908
986
|
const annotation = {
|
|
909
987
|
id: ctx.generateId("annotation"),
|
|
@@ -946,21 +1024,135 @@ async function createImageServiceAnnotation(data, ctx) {
|
|
|
946
1024
|
}
|
|
947
1025
|
}
|
|
948
1026
|
function CreateImageServiceAnnotationForm(props) {
|
|
949
|
-
return /* @__PURE__ */
|
|
1027
|
+
return /* @__PURE__ */ jsx11(CreateImageServerForm, { ...props });
|
|
950
1028
|
}
|
|
951
1029
|
|
|
952
1030
|
// src/Annotation/ImageServiceAnnotation/index.tsx
|
|
953
1031
|
import { IIIFLogo } from "@manifest-editor/components";
|
|
954
|
-
import { jsx as
|
|
1032
|
+
import { jsx as jsx12 } from "react/jsx-runtime";
|
|
955
1033
|
var imageServiceAnnotation = {
|
|
956
1034
|
id: "@manifest-editor/image-service-annotation",
|
|
957
1035
|
create: createImageServiceAnnotation,
|
|
958
1036
|
label: "IIIF Image",
|
|
959
1037
|
dependencies: ["@manifest-editor/image-service-creator"],
|
|
960
1038
|
summary: "IIIF Image service",
|
|
961
|
-
|
|
1039
|
+
tags: ["image", "image-service"],
|
|
1040
|
+
icon: /* @__PURE__ */ jsx12(IIIFLogo, { style: { padding: 10 } }),
|
|
1041
|
+
render(ctx) {
|
|
1042
|
+
return /* @__PURE__ */ jsx12(CreateImageServiceAnnotationForm, { ...ctx });
|
|
1043
|
+
},
|
|
1044
|
+
resourceType: "Annotation",
|
|
1045
|
+
resourceFields: ["id", "type", "motivation", "body", "target"],
|
|
1046
|
+
additionalTypes: ["Canvas"],
|
|
1047
|
+
supports: {
|
|
1048
|
+
parentTypes: ["AnnotationPage", "Manifest"],
|
|
1049
|
+
parentFields: ["items"]
|
|
1050
|
+
},
|
|
1051
|
+
sideEffects: [resizeToFitService, resizeResourceToEmptyCanvas, repositionMultipleImages],
|
|
1052
|
+
staticFields: {
|
|
1053
|
+
type: "Annotation"
|
|
1054
|
+
}
|
|
1055
|
+
};
|
|
1056
|
+
|
|
1057
|
+
// src/ContentResource/ImageUrlCreator/create-image-url.tsx
|
|
1058
|
+
import { InputContainer as InputContainer5, InputLabel as InputLabel5, Input as Input4 } from "@manifest-editor/editors";
|
|
1059
|
+
import { getImageDimensions, getFormat } from "@manifest-editor/shell";
|
|
1060
|
+
import { jsx as jsx13, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
1061
|
+
async function createImageUrl(data, ctx) {
|
|
1062
|
+
if (!data.height || !data.width) {
|
|
1063
|
+
const dimensions = await getImageDimensions(data.url);
|
|
1064
|
+
if (dimensions) {
|
|
1065
|
+
data.height = dimensions.height;
|
|
1066
|
+
data.width = dimensions.width;
|
|
1067
|
+
}
|
|
1068
|
+
}
|
|
1069
|
+
return ctx.embed({
|
|
1070
|
+
id: data.url,
|
|
1071
|
+
type: "Image",
|
|
1072
|
+
format: data.format || await getFormat(data.url),
|
|
1073
|
+
height: data.height,
|
|
1074
|
+
width: data.width,
|
|
1075
|
+
service: data.service ? Array.isArray(data.service) ? data.service : [data.service] : void 0
|
|
1076
|
+
});
|
|
1077
|
+
}
|
|
1078
|
+
function CreateImageUrlForm(props) {
|
|
1079
|
+
const onSubmit = (e) => {
|
|
1080
|
+
e.preventDefault();
|
|
1081
|
+
const data = new FormData(e.target);
|
|
1082
|
+
const formData = Object.fromEntries(data.entries());
|
|
1083
|
+
if (formData.url) {
|
|
1084
|
+
props.runCreate({ url: formData.url });
|
|
1085
|
+
}
|
|
1086
|
+
};
|
|
1087
|
+
return /* @__PURE__ */ jsx13(PaddedSidebarContainer, { children: /* @__PURE__ */ jsxs8("form", { onSubmit, children: [
|
|
1088
|
+
/* @__PURE__ */ jsxs8(InputContainer5, { $wide: true, children: [
|
|
1089
|
+
/* @__PURE__ */ jsx13(InputLabel5, { htmlFor: "id", children: "Link to Image" }),
|
|
1090
|
+
/* @__PURE__ */ jsx13(Input4, { id: "url", name: "url", defaultValue: "" })
|
|
1091
|
+
] }),
|
|
1092
|
+
/* @__PURE__ */ jsx13(Button, { type: "submit", children: "Create" })
|
|
1093
|
+
] }) });
|
|
1094
|
+
}
|
|
1095
|
+
|
|
1096
|
+
// src/Annotation/ImageUrlAnnotation/create-image-url-annotation.tsx
|
|
1097
|
+
import { jsx as jsx14 } from "react/jsx-runtime";
|
|
1098
|
+
async function createImageUrlAnnotation(data, ctx) {
|
|
1099
|
+
const annotation = {
|
|
1100
|
+
id: ctx.generateId("annotation"),
|
|
1101
|
+
type: "Annotation"
|
|
1102
|
+
};
|
|
1103
|
+
const targetType = ctx.options.targetType;
|
|
1104
|
+
const resource = await ctx.create("@manifest-editor/image-url-creator", data, {
|
|
1105
|
+
parent: { resource: annotation, property: "body" }
|
|
1106
|
+
});
|
|
1107
|
+
if (targetType === "Annotation") {
|
|
1108
|
+
return {
|
|
1109
|
+
...annotation,
|
|
1110
|
+
body: [resource],
|
|
1111
|
+
motivation: data.motivation || "painting",
|
|
1112
|
+
target: ctx.getTarget()
|
|
1113
|
+
};
|
|
1114
|
+
}
|
|
1115
|
+
if (targetType === "Canvas") {
|
|
1116
|
+
const canvasId = ctx.generateId("canvas");
|
|
1117
|
+
const pageId = ctx.generateId("annotation-page", { id: canvasId, type: "Canvas" });
|
|
1118
|
+
const annotationResource = ctx.embed({
|
|
1119
|
+
...annotation,
|
|
1120
|
+
motivation: "painting",
|
|
1121
|
+
body: [resource],
|
|
1122
|
+
target: { type: "SpecificResource", source: { id: canvasId, type: "Canvas" } }
|
|
1123
|
+
});
|
|
1124
|
+
const page = ctx.embed({
|
|
1125
|
+
id: pageId,
|
|
1126
|
+
type: "AnnotationPage",
|
|
1127
|
+
items: [annotationResource]
|
|
1128
|
+
});
|
|
1129
|
+
return ctx.embed({
|
|
1130
|
+
id: canvasId,
|
|
1131
|
+
type: "Canvas",
|
|
1132
|
+
label: data.label || { en: ["Untitled canvas"] },
|
|
1133
|
+
height: resource.resource.height || 1e3,
|
|
1134
|
+
width: resource.resource.width || 1e3,
|
|
1135
|
+
items: [page]
|
|
1136
|
+
});
|
|
1137
|
+
}
|
|
1138
|
+
}
|
|
1139
|
+
function CreateImageUrlAnnotationForm(props) {
|
|
1140
|
+
return /* @__PURE__ */ jsx14(CreateImageUrlForm, { ...props });
|
|
1141
|
+
}
|
|
1142
|
+
|
|
1143
|
+
// src/Annotation/ImageUrlAnnotation/index.tsx
|
|
1144
|
+
import { AddImageIcon as AddImageIcon2 } from "@manifest-editor/components";
|
|
1145
|
+
import { jsx as jsx15 } from "react/jsx-runtime";
|
|
1146
|
+
var imageUrlAnnotation = {
|
|
1147
|
+
id: "@manifest-editor/image-url-annotation",
|
|
1148
|
+
create: createImageUrlAnnotation,
|
|
1149
|
+
label: "Image",
|
|
1150
|
+
dependencies: ["@manifest-editor/image-url-creator"],
|
|
1151
|
+
summary: "Image from URL",
|
|
1152
|
+
tags: ["image"],
|
|
1153
|
+
icon: /* @__PURE__ */ jsx15(AddImageIcon2, {}),
|
|
962
1154
|
render(ctx) {
|
|
963
|
-
return /* @__PURE__ */
|
|
1155
|
+
return /* @__PURE__ */ jsx15(CreateImageUrlAnnotationForm, { ...ctx });
|
|
964
1156
|
},
|
|
965
1157
|
resourceType: "Annotation",
|
|
966
1158
|
resourceFields: ["id", "type", "motivation", "body", "target"],
|
|
@@ -976,14 +1168,14 @@ var imageServiceAnnotation = {
|
|
|
976
1168
|
};
|
|
977
1169
|
|
|
978
1170
|
// src/Annotation/NoBodyAnnotation/index.tsx
|
|
979
|
-
import { EmptyCanvasIcon
|
|
980
|
-
import { jsx as
|
|
1171
|
+
import { EmptyCanvasIcon } from "@manifest-editor/components";
|
|
1172
|
+
import { jsx as jsx16 } from "react/jsx-runtime";
|
|
981
1173
|
var noBodyAnnotation = {
|
|
982
1174
|
id: "@manifest-editor/no-body-annotation",
|
|
983
1175
|
create: createNoBodyAnnotation,
|
|
984
1176
|
label: "Annotation without body",
|
|
985
1177
|
summary: "Add an annotation that only has motivation and target",
|
|
986
|
-
icon: /* @__PURE__ */
|
|
1178
|
+
icon: /* @__PURE__ */ jsx16(EmptyCanvasIcon, {}),
|
|
987
1179
|
resourceType: "Annotation",
|
|
988
1180
|
resourceFields: ["id", "type", "motivation", "target"],
|
|
989
1181
|
supports: {
|
|
@@ -1007,192 +1199,73 @@ function createNoBodyAnnotation(data, ctx) {
|
|
|
1007
1199
|
});
|
|
1008
1200
|
}
|
|
1009
1201
|
|
|
1010
|
-
// src/
|
|
1011
|
-
import {
|
|
1012
|
-
import {
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
var isProduction = false;
|
|
1016
|
-
var prefix = "Invariant failed";
|
|
1017
|
-
function invariant(condition, message) {
|
|
1018
|
-
if (condition) {
|
|
1019
|
-
return;
|
|
1020
|
-
}
|
|
1021
|
-
if (isProduction) {
|
|
1022
|
-
throw new Error(prefix);
|
|
1023
|
-
}
|
|
1024
|
-
var provided = typeof message === "function" ? message() : message;
|
|
1025
|
-
var value = provided ? "".concat(prefix, ": ").concat(provided) : prefix;
|
|
1026
|
-
throw new Error(value);
|
|
1027
|
-
}
|
|
1202
|
+
// src/Annotation/VideoAnnotation/create-video-annotation.tsx
|
|
1203
|
+
import { getValue as getValue2 } from "@iiif/helpers";
|
|
1204
|
+
import { InputContainer as InputContainer6, InputLabel as InputLabel6, Input as Input5, LanguageFieldEditor as LanguageFieldEditor4, DimensionsTriplet } from "@manifest-editor/editors";
|
|
1205
|
+
import { ErrorMessage as ErrorMessage2 } from "@manifest-editor/components";
|
|
1206
|
+
import { useState as useState5, useEffect as useEffect3 } from "react";
|
|
1028
1207
|
|
|
1029
|
-
//
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
const type = target.source.type;
|
|
1043
|
-
const previewVault = ctx.getPreviewVault();
|
|
1044
|
-
if (targetType === "Canvas" || targetType === "Annotation") {
|
|
1045
|
-
if (type === "Canvas") {
|
|
1046
|
-
const canvasId = target.source.id;
|
|
1047
|
-
const manifestId = target.source.partOf?.find((t) => t.type === "Manifest");
|
|
1048
|
-
invariant(manifestId, "Could not load external resource without partOf");
|
|
1049
|
-
const manifest = await previewVault.loadManifest(manifestId);
|
|
1050
|
-
invariant(manifest, "Manifest not found");
|
|
1051
|
-
const canvasRef = manifest.items.find((item) => item.id === canvasId);
|
|
1052
|
-
invariant(canvasRef, "Canvas not found");
|
|
1053
|
-
const canvas = previewVault.get(canvasRef);
|
|
1054
|
-
if (targetType === "Canvas") {
|
|
1055
|
-
return ctx.embed(previewVault.toPresentation3(canvas));
|
|
1056
|
-
}
|
|
1057
|
-
const annotationPage = previewVault.get(canvas.items[0]);
|
|
1058
|
-
const annotation = previewVault.get(annotationPage.items[0]);
|
|
1059
|
-
if (targetType === "Annotation") {
|
|
1060
|
-
const fullAnnotation = previewVault.toPresentation3(annotation);
|
|
1061
|
-
if (fullAnnotation && fullAnnotation?.body?.service) {
|
|
1062
|
-
const width = fullAnnotation?.body.width;
|
|
1063
|
-
const height = fullAnnotation?.body.height;
|
|
1064
|
-
const service = Array.isArray(fullAnnotation?.body?.service) ? fullAnnotation?.body?.service[0] : fullAnnotation?.body?.service;
|
|
1065
|
-
if (!service.width || !service.height) {
|
|
1066
|
-
service.width = width;
|
|
1067
|
-
service.height = height;
|
|
1068
|
-
}
|
|
1069
|
-
}
|
|
1070
|
-
if (target.selector && target.selector.type === "BoxSelector") {
|
|
1071
|
-
const selector = {
|
|
1072
|
-
"@context": "http://iiif.io/api/annex/openannotation/context.json",
|
|
1073
|
-
type: "iiif:ImageApiSelector",
|
|
1074
|
-
region: [
|
|
1075
|
-
~~target.selector.spatial.x,
|
|
1076
|
-
~~target.selector.spatial.y,
|
|
1077
|
-
~~target.selector.spatial.width,
|
|
1078
|
-
~~target.selector.spatial.height
|
|
1079
|
-
].join(",")
|
|
1080
|
-
};
|
|
1081
|
-
fullAnnotation.body = {
|
|
1082
|
-
id: ctx.generateId("SpecificResource", annotation),
|
|
1083
|
-
type: "SpecificResource",
|
|
1084
|
-
source: fullAnnotation.body,
|
|
1085
|
-
selector
|
|
1086
|
-
};
|
|
1087
|
-
return ctx.embed({
|
|
1088
|
-
...fullAnnotation,
|
|
1089
|
-
target: ctx.getTarget()
|
|
1090
|
-
});
|
|
1091
|
-
}
|
|
1092
|
-
return ctx.embed({
|
|
1093
|
-
...previewVault.toPresentation3(annotation),
|
|
1094
|
-
target: ctx.getTarget()
|
|
1095
|
-
});
|
|
1096
|
-
}
|
|
1097
|
-
}
|
|
1098
|
-
}
|
|
1099
|
-
throw new Error("Not yet supported.");
|
|
1100
|
-
}
|
|
1101
|
-
var IIIFBrowserCreatorForm = lazy(() => import("./iiif-browser-form.lazy-PL3WMLU5.js"));
|
|
1102
|
-
|
|
1103
|
-
// src/ContentResource/IIIFBrowserCreator/index.tsx
|
|
1104
|
-
import { IIIFBrowserIcon } from "@manifest-editor/components";
|
|
1105
|
-
import { jsx as jsx23 } from "react/jsx-runtime";
|
|
1106
|
-
var iiifBrowserCreator = {
|
|
1107
|
-
id: "@manifest-editor/iiif-browser-creator",
|
|
1108
|
-
create: createFromIIIFBrowserOutput,
|
|
1109
|
-
label: "IIIF Browser",
|
|
1110
|
-
summary: "Browse IIIF Resources",
|
|
1111
|
-
icon: /* @__PURE__ */ jsx23(IIIFBrowserIcon, {}),
|
|
1112
|
-
render(ctx) {
|
|
1113
|
-
return /* @__PURE__ */ jsx23(IIIFBrowserCreatorForm, { ...ctx });
|
|
1114
|
-
},
|
|
1115
|
-
resourceType: "ContentResource",
|
|
1116
|
-
resourceFields: ["id", "language", "type", "format", "value"],
|
|
1117
|
-
additionalTypes: ["Annotation", "Canvas"],
|
|
1118
|
-
supports: {
|
|
1119
|
-
parentTypes: ["Annotation", "Manifest", "AnnotationPage"],
|
|
1120
|
-
parentFieldMap: {
|
|
1121
|
-
Annotation: ["body"],
|
|
1122
|
-
Manifest: ["items"],
|
|
1123
|
-
AnnotationPage: ["items"]
|
|
1124
|
-
}
|
|
1125
|
-
},
|
|
1126
|
-
sideEffects: [resizeToFitService, resizeResourceToEmptyCanvas, repositionMultipleImages],
|
|
1127
|
-
staticFields: {}
|
|
1128
|
-
};
|
|
1129
|
-
|
|
1130
|
-
// src/Canvas/InternalCanvas/index.tsx
|
|
1131
|
-
import { useManifest, useVault } from "react-iiif-vault";
|
|
1132
|
-
import { IIIFExplorer } from "@manifest-editor/iiif-browser";
|
|
1133
|
-
import { jsx as jsx24 } from "react/jsx-runtime";
|
|
1134
|
-
var internalCanvas = {
|
|
1135
|
-
id: "@manifest-editor/internal-canvas",
|
|
1136
|
-
create: createInternalCanvas,
|
|
1137
|
-
label: "Internal canvas link",
|
|
1138
|
-
summary: "Canvas from the same manifest",
|
|
1139
|
-
icon: /* @__PURE__ */ jsx24(ThumbnailStripIcon, {}),
|
|
1140
|
-
resourceType: "Canvas",
|
|
1141
|
-
resourceFields: ["id", "type", "label"],
|
|
1142
|
-
supports: {
|
|
1143
|
-
parentTypes: ["Manifest"],
|
|
1144
|
-
parentFields: ["start"]
|
|
1145
|
-
},
|
|
1146
|
-
render: (ctx) => /* @__PURE__ */ jsx24(InternalCanvas, { ...ctx })
|
|
1147
|
-
};
|
|
1148
|
-
function InternalCanvas(props) {
|
|
1149
|
-
const manifest = useManifest();
|
|
1150
|
-
const vault = useVault();
|
|
1151
|
-
invariant(manifest, "Manifest is not loaded");
|
|
1152
|
-
return /* @__PURE__ */ jsx24(
|
|
1153
|
-
IIIFExplorer,
|
|
1208
|
+
// ../ui/ui/VideoPlayer/VideoPlayer.tsx
|
|
1209
|
+
import { CanvasPanel as CanvasPanel2, MediaPlayerProvider, useSimpleMediaPlayer } from "react-iiif-vault";
|
|
1210
|
+
import { jsx as jsx17, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
1211
|
+
function VideoPlayer({
|
|
1212
|
+
media,
|
|
1213
|
+
onError,
|
|
1214
|
+
duration,
|
|
1215
|
+
onDuration,
|
|
1216
|
+
onDimensions
|
|
1217
|
+
}) {
|
|
1218
|
+
const [{ element, currentTime, progress }, state, actions] = useSimpleMediaPlayer({ duration });
|
|
1219
|
+
return /* @__PURE__ */ jsxs9(
|
|
1220
|
+
MediaPlayerProvider,
|
|
1154
1221
|
{
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1222
|
+
element,
|
|
1223
|
+
state,
|
|
1224
|
+
actions,
|
|
1225
|
+
currentTime,
|
|
1226
|
+
progress,
|
|
1227
|
+
children: [
|
|
1228
|
+
/* @__PURE__ */ jsx17(
|
|
1229
|
+
"div",
|
|
1230
|
+
{
|
|
1231
|
+
style: {
|
|
1232
|
+
maxHeight: 400,
|
|
1233
|
+
aspectRatio: `${media.width}/${media.height}`,
|
|
1234
|
+
position: "relative"
|
|
1235
|
+
},
|
|
1236
|
+
children: /* @__PURE__ */ jsx17(CanvasPanel2.VideoHTML, { element, media, playPause: actions.playPause })
|
|
1167
1237
|
}
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1238
|
+
),
|
|
1239
|
+
/* @__PURE__ */ jsx17(MediaControls, { onError, onDuration, onDimensions })
|
|
1240
|
+
]
|
|
1171
1241
|
}
|
|
1172
1242
|
);
|
|
1173
1243
|
}
|
|
1174
|
-
async function createInternalCanvas(data, ctx) {
|
|
1175
|
-
return ctx.embed({ id: data.id, type: "Canvas" });
|
|
1176
|
-
}
|
|
1177
1244
|
|
|
1178
|
-
// src/Annotation/
|
|
1179
|
-
import { jsx as
|
|
1180
|
-
async function
|
|
1245
|
+
// src/Annotation/VideoAnnotation/create-video-annotation.tsx
|
|
1246
|
+
import { jsx as jsx18, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
1247
|
+
async function createVideoAnnotation(data, ctx) {
|
|
1181
1248
|
const annotation = {
|
|
1182
1249
|
id: ctx.generateId("annotation"),
|
|
1183
1250
|
type: "Annotation"
|
|
1184
1251
|
};
|
|
1185
1252
|
const targetType = ctx.options.targetType;
|
|
1186
|
-
const
|
|
1187
|
-
|
|
1253
|
+
const body = await ctx.embed({
|
|
1254
|
+
id: data.url,
|
|
1255
|
+
type: "Video",
|
|
1256
|
+
format: "video/mp4",
|
|
1257
|
+
width: data.width,
|
|
1258
|
+
height: data.height,
|
|
1259
|
+
duration: data.duration || 0
|
|
1188
1260
|
});
|
|
1189
1261
|
if (targetType === "Annotation") {
|
|
1190
|
-
return {
|
|
1262
|
+
return ctx.embed({
|
|
1191
1263
|
...annotation,
|
|
1192
|
-
|
|
1193
|
-
motivation: data.motivation || "painting",
|
|
1264
|
+
label: getValue2(data.label) && data.label,
|
|
1265
|
+
motivation: data.motivation || ctx.options.initialData?.motivation || "painting",
|
|
1266
|
+
body,
|
|
1194
1267
|
target: ctx.getTarget()
|
|
1195
|
-
};
|
|
1268
|
+
});
|
|
1196
1269
|
}
|
|
1197
1270
|
if (targetType === "Canvas") {
|
|
1198
1271
|
const canvasId = ctx.generateId("canvas");
|
|
@@ -1200,7 +1273,7 @@ async function createImageUrlAnnotation(data, ctx) {
|
|
|
1200
1273
|
const annotationResource = ctx.embed({
|
|
1201
1274
|
...annotation,
|
|
1202
1275
|
motivation: "painting",
|
|
1203
|
-
body
|
|
1276
|
+
body,
|
|
1204
1277
|
target: { type: "SpecificResource", source: { id: canvasId, type: "Canvas" } }
|
|
1205
1278
|
});
|
|
1206
1279
|
const page = ctx.embed({
|
|
@@ -1211,657 +1284,750 @@ async function createImageUrlAnnotation(data, ctx) {
|
|
|
1211
1284
|
return ctx.embed({
|
|
1212
1285
|
id: canvasId,
|
|
1213
1286
|
type: "Canvas",
|
|
1214
|
-
label: data.label || { en: ["Untitled canvas"] },
|
|
1215
|
-
|
|
1216
|
-
width:
|
|
1287
|
+
label: data.label || { en: ["Untitled HTML canvas"] },
|
|
1288
|
+
duration: data.duration || 0,
|
|
1289
|
+
width: data.width,
|
|
1290
|
+
height: data.height,
|
|
1217
1291
|
items: [page]
|
|
1218
1292
|
});
|
|
1219
1293
|
}
|
|
1220
1294
|
}
|
|
1221
|
-
function
|
|
1222
|
-
|
|
1295
|
+
function CreateVideoAnnotationForm(props) {
|
|
1296
|
+
const [url, setUrl] = useState5("");
|
|
1297
|
+
const [duration, setDuration] = useState5(0);
|
|
1298
|
+
const [width, setWidth] = useState5(0);
|
|
1299
|
+
const [height, setHeight] = useState5(0);
|
|
1300
|
+
const [error, setError] = useState5("");
|
|
1301
|
+
const [label, setLabel] = useState5({ en: [""] });
|
|
1302
|
+
const onSubmit = () => {
|
|
1303
|
+
props.runCreate({
|
|
1304
|
+
url,
|
|
1305
|
+
duration,
|
|
1306
|
+
label,
|
|
1307
|
+
width,
|
|
1308
|
+
height
|
|
1309
|
+
});
|
|
1310
|
+
};
|
|
1311
|
+
useEffect3(() => {
|
|
1312
|
+
setError("");
|
|
1313
|
+
setDuration(0);
|
|
1314
|
+
if (url) {
|
|
1315
|
+
const labelFromUrl = url.split("/").pop()?.split(".").shift();
|
|
1316
|
+
setLabel({ en: [labelFromUrl || ""] });
|
|
1317
|
+
}
|
|
1318
|
+
}, [url]);
|
|
1319
|
+
return /* @__PURE__ */ jsxs10(PaddedSidebarContainer, { children: [
|
|
1320
|
+
error ? /* @__PURE__ */ jsx18(ErrorMessage2, { children: error }) : null,
|
|
1321
|
+
/* @__PURE__ */ jsxs10(InputContainer6, { children: [
|
|
1322
|
+
/* @__PURE__ */ jsx18(InputLabel6, { htmlFor: "video-url", children: "URL" }),
|
|
1323
|
+
/* @__PURE__ */ jsx18(Input5, { type: "text", id: "video-url", value: url, onChange: (e) => setUrl(e.target.value) })
|
|
1324
|
+
] }),
|
|
1325
|
+
url && !error ? /* @__PURE__ */ jsx18("div", { children: /* @__PURE__ */ jsx18(
|
|
1326
|
+
LanguageFieldEditor4,
|
|
1327
|
+
{
|
|
1328
|
+
containerId: "label",
|
|
1329
|
+
focusId: "label_",
|
|
1330
|
+
label: "Label",
|
|
1331
|
+
fields: label,
|
|
1332
|
+
onSave: (e) => setLabel(e.toInternationalString())
|
|
1333
|
+
},
|
|
1334
|
+
url + "__" + duration
|
|
1335
|
+
) }) : null,
|
|
1336
|
+
url && !error ? /* @__PURE__ */ jsx18(
|
|
1337
|
+
VideoPlayer,
|
|
1338
|
+
{
|
|
1339
|
+
duration,
|
|
1340
|
+
onDuration: (d) => setDuration(d),
|
|
1341
|
+
onError: (err) => setError(err),
|
|
1342
|
+
media: {
|
|
1343
|
+
url,
|
|
1344
|
+
duration,
|
|
1345
|
+
height,
|
|
1346
|
+
width,
|
|
1347
|
+
type: "Video"
|
|
1348
|
+
},
|
|
1349
|
+
onDimensions: (w, h) => {
|
|
1350
|
+
setWidth(w || 0);
|
|
1351
|
+
setHeight(h || 0);
|
|
1352
|
+
}
|
|
1353
|
+
}
|
|
1354
|
+
) : null,
|
|
1355
|
+
!error && (duration || width || height) ? /* @__PURE__ */ jsx18(InputContainer6, { $wide: true, children: /* @__PURE__ */ jsx18(
|
|
1356
|
+
DimensionsTriplet,
|
|
1357
|
+
{
|
|
1358
|
+
widthId: "width",
|
|
1359
|
+
width: width || 0,
|
|
1360
|
+
changeWidth: (v) => setWidth(v),
|
|
1361
|
+
heightId: "height",
|
|
1362
|
+
height: height || 0,
|
|
1363
|
+
changeHeight: (v) => setHeight(v),
|
|
1364
|
+
durationId: "duration",
|
|
1365
|
+
duration: duration || 0,
|
|
1366
|
+
changeDuration: (v) => setDuration(v)
|
|
1367
|
+
}
|
|
1368
|
+
) }) : null,
|
|
1369
|
+
url && !error && /* @__PURE__ */ jsx18(Button, { onClick: onSubmit, children: "Add video" })
|
|
1370
|
+
] });
|
|
1223
1371
|
}
|
|
1224
1372
|
|
|
1225
|
-
// src/Annotation/
|
|
1226
|
-
import {
|
|
1227
|
-
import { jsx as
|
|
1228
|
-
var
|
|
1229
|
-
id: "@manifest-editor/
|
|
1230
|
-
create:
|
|
1231
|
-
label: "
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
icon: /* @__PURE__ */ jsx26(AddImageIcon2, {}),
|
|
1373
|
+
// src/Annotation/VideoAnnotation/index.tsx
|
|
1374
|
+
import { VideoIcon } from "@manifest-editor/components";
|
|
1375
|
+
import { jsx as jsx19 } from "react/jsx-runtime";
|
|
1376
|
+
var videoAnnotation = {
|
|
1377
|
+
id: "@manifest-editor/video-annotation",
|
|
1378
|
+
create: createVideoAnnotation,
|
|
1379
|
+
label: "Video",
|
|
1380
|
+
summary: "Video annotation",
|
|
1381
|
+
icon: /* @__PURE__ */ jsx19(VideoIcon, {}),
|
|
1235
1382
|
render(ctx) {
|
|
1236
|
-
return /* @__PURE__ */
|
|
1383
|
+
return /* @__PURE__ */ jsx19(CreateVideoAnnotationForm, { ...ctx });
|
|
1237
1384
|
},
|
|
1238
1385
|
resourceType: "Annotation",
|
|
1239
1386
|
resourceFields: ["id", "type", "motivation", "body", "target"],
|
|
1240
1387
|
additionalTypes: ["Canvas"],
|
|
1241
1388
|
supports: {
|
|
1389
|
+
initialData: true,
|
|
1242
1390
|
parentTypes: ["AnnotationPage", "Manifest"],
|
|
1243
1391
|
parentFields: ["items"]
|
|
1244
1392
|
},
|
|
1245
|
-
sideEffects: [resizeToFitService, resizeResourceToEmptyCanvas, repositionMultipleImages],
|
|
1246
1393
|
staticFields: {
|
|
1247
1394
|
type: "Annotation"
|
|
1248
1395
|
}
|
|
1249
1396
|
};
|
|
1250
1397
|
|
|
1251
|
-
//
|
|
1252
|
-
import {
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
color: ${(props) => props.theme.color.white || "white"};
|
|
1398
|
+
// ../ui/icons/ThumbnailStripIcon.tsx
|
|
1399
|
+
import { jsx as jsx20, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
1400
|
+
var ThumbnailStripIcon = () => /* @__PURE__ */ jsx20(
|
|
1401
|
+
"svg",
|
|
1402
|
+
{
|
|
1403
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
1404
|
+
height: "24px",
|
|
1405
|
+
viewBox: "0 0 24 24",
|
|
1406
|
+
width: "24px",
|
|
1407
|
+
fill: "#000000",
|
|
1408
|
+
transform: "scale(-1, 1)",
|
|
1409
|
+
children: /* @__PURE__ */ jsxs11("g", { children: [
|
|
1410
|
+
/* @__PURE__ */ jsx20("rect", { fill: "none", height: "24", width: "24" }),
|
|
1411
|
+
/* @__PURE__ */ jsx20("path", { d: "M16,20H2V4h14V20z M18,8h4V4h-4V8z M18,20h4v-4h-4V20z M18,14h4v-4h-4V14z" })
|
|
1412
|
+
] })
|
|
1267
1413
|
}
|
|
1268
|
-
|
|
1269
|
-
font-size: 0.75em;
|
|
1270
|
-
white-space: nowrap;
|
|
1271
|
-
padding: ${props.theme.padding.xs || "0.25rem"} ${props.theme.padding.small || "0.5rem"};
|
|
1272
|
-
line-height: 1.6em;
|
|
1273
|
-
width: fit-content;
|
|
1274
|
-
`}
|
|
1275
|
-
`;
|
|
1276
|
-
|
|
1277
|
-
// ../ui/ui/MediaControls/MediaControls.tsx
|
|
1278
|
-
import { formatTime, useMediaActions, useMediaElements, useMediaState } from "react-iiif-vault";
|
|
1279
|
-
import { useLayoutEffect, useState as useState5 } from "react";
|
|
1414
|
+
);
|
|
1280
1415
|
|
|
1281
|
-
//
|
|
1282
|
-
import { jsx as
|
|
1283
|
-
var
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
]
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
"path",
|
|
1298
|
-
{
|
|
1299
|
-
fill: "currentColor",
|
|
1300
|
-
d: "M3 9v6h4l5 5V4L7 9H3zm13.5 3A4.5 4.5 0 0 0 14 7.97v8.05c1.48-.73 2.5-2.25 2.5-4.02zM14 3.23v2.06c2.89.86 5 3.54 5 6.71s-2.11 5.85-5 6.71v2.06c4.01-.91 7-4.49 7-8.77s-2.99-7.86-7-8.77z"
|
|
1301
|
-
}
|
|
1302
|
-
)
|
|
1303
|
-
] });
|
|
1304
|
-
var VolumeDownIcon = ({ title, ...props }) => /* @__PURE__ */ jsxs11("svg", { ...props, xmlns: "http://www.w3.org/2000/svg", height: "1em", width: "1em", viewBox: "2 2 20 20", children: [
|
|
1305
|
-
title ? /* @__PURE__ */ jsx27("title", { children: title }) : null,
|
|
1306
|
-
/* @__PURE__ */ jsx27("path", { d: "M0 0h24v24H0z", fill: "none" }),
|
|
1307
|
-
/* @__PURE__ */ jsx27(
|
|
1308
|
-
"path",
|
|
1309
|
-
{
|
|
1310
|
-
fill: "currentColor",
|
|
1311
|
-
d: "M18.5 12c0-1.77-1.02-3.29-2.5-4.03v8.05c1.48-.73 2.5-2.25 2.5-4.02zM5 9v6h4l5 5V4L9 9H5z"
|
|
1312
|
-
}
|
|
1313
|
-
)
|
|
1314
|
-
] });
|
|
1315
|
-
var VolumeOffIcon = ({ title, ...props }) => /* @__PURE__ */ jsxs11("svg", { ...props, xmlns: "http://www.w3.org/2000/svg", height: "1em", width: "1em", viewBox: "2 2 20 20", children: [
|
|
1316
|
-
title ? /* @__PURE__ */ jsx27("title", { children: title }) : null,
|
|
1317
|
-
/* @__PURE__ */ jsx27("path", { d: "M0 0h24v24H0z", fill: "none" }),
|
|
1318
|
-
/* @__PURE__ */ jsx27(
|
|
1319
|
-
"path",
|
|
1320
|
-
{
|
|
1321
|
-
fill: "currentColor",
|
|
1322
|
-
d: "M16.5 12A4.5 4.5 0 0 0 14 7.97v2.21l2.45 2.45c.03-.2.05-.41.05-.63zm2.5 0c0 .94-.2 1.82-.54 2.64l1.51 1.51A8.796 8.796 0 0 0 21 12c0-4.28-2.99-7.86-7-8.77v2.06c2.89.86 5 3.54 5 6.71zM4.27 3 3 4.27 7.73 9H3v6h4l5 5v-6.73l4.25 4.25c-.67.52-1.42.93-2.25 1.18v2.06a8.99 8.99 0 0 0 3.69-1.81L19.73 21 21 19.73l-9-9L4.27 3zM12 4 9.91 6.09 12 8.18V4z"
|
|
1416
|
+
// src/AnnotationPage/EmptyAnnotationPage/index.tsx
|
|
1417
|
+
import { jsx as jsx21 } from "react/jsx-runtime";
|
|
1418
|
+
var emptyAnnotationPage = {
|
|
1419
|
+
id: "@manifest-editor/empty-annotation-page",
|
|
1420
|
+
create: createEmptyAnnotationPage,
|
|
1421
|
+
label: "Empty annotation page",
|
|
1422
|
+
summary: "AnnotationPage with nothing",
|
|
1423
|
+
icon: /* @__PURE__ */ jsx21(ThumbnailStripIcon, {}),
|
|
1424
|
+
resourceType: "AnnotationPage",
|
|
1425
|
+
resourceFields: ["id", "type", "items"],
|
|
1426
|
+
supports: {
|
|
1427
|
+
parentTypes: ["Manifest", "Canvas", "Range"],
|
|
1428
|
+
parentFieldMap: {
|
|
1429
|
+
Manifest: ["annotations"],
|
|
1430
|
+
Canvas: ["items", "annotations"],
|
|
1431
|
+
Range: ["annotations"]
|
|
1323
1432
|
}
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
`;
|
|
1335
|
-
var BaseButton = styled4.button`
|
|
1336
|
-
cursor: pointer;
|
|
1337
|
-
padding: 0.75em 1.5em;
|
|
1338
|
-
font-size: 0.938em;
|
|
1339
|
-
background: none;
|
|
1340
|
-
color: inherit;
|
|
1341
|
-
border: none;
|
|
1342
|
-
text-decoration: none;
|
|
1343
|
-
display: inline-block;
|
|
1344
|
-
vertical-align: top;
|
|
1345
|
-
white-space: nowrap;
|
|
1346
|
-
`;
|
|
1347
|
-
var PlayButton = styled4(BaseButton)`
|
|
1348
|
-
width: 2em;
|
|
1349
|
-
height: 2em;
|
|
1350
|
-
overflow: hidden;
|
|
1351
|
-
font-size: 1.1em;
|
|
1352
|
-
background: #fff;
|
|
1353
|
-
border-radius: 3px;
|
|
1354
|
-
padding: 0;
|
|
1355
|
-
margin: 0;
|
|
1356
|
-
color: #000; // Not in colours
|
|
1433
|
+
}
|
|
1434
|
+
};
|
|
1435
|
+
async function createEmptyAnnotationPage(data, ctx) {
|
|
1436
|
+
return ctx.embed({
|
|
1437
|
+
id: ctx.generateId("annotations"),
|
|
1438
|
+
label: data.label,
|
|
1439
|
+
type: "AnnotationPage",
|
|
1440
|
+
items: []
|
|
1441
|
+
});
|
|
1442
|
+
}
|
|
1357
1443
|
|
|
1358
|
-
|
|
1359
|
-
|
|
1444
|
+
// src/Canvas/EmptyCanvas/index.tsx
|
|
1445
|
+
import { EmptyCanvasIcon as EmptyCanvasIcon2 } from "@manifest-editor/components";
|
|
1446
|
+
import { jsx as jsx22 } from "react/jsx-runtime";
|
|
1447
|
+
var emptyCanvas = {
|
|
1448
|
+
id: "@manifest-editor/empty-canvas",
|
|
1449
|
+
create: createEmptyCanvas,
|
|
1450
|
+
label: "Empty canvas",
|
|
1451
|
+
summary: "No content",
|
|
1452
|
+
icon: /* @__PURE__ */ jsx22(EmptyCanvasIcon2, {}),
|
|
1453
|
+
resourceType: "Canvas",
|
|
1454
|
+
resourceFields: ["id", "type", "label", "height", "width", "items"],
|
|
1455
|
+
supports: {
|
|
1456
|
+
parentTypes: ["Manifest"],
|
|
1457
|
+
parentFields: ["items"]
|
|
1360
1458
|
}
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
position: absolute;
|
|
1379
|
-
top: 13px;
|
|
1380
|
-
left: 0;
|
|
1381
|
-
border-radius: 3px;
|
|
1382
|
-
transition: width 200ms;
|
|
1383
|
-
`;
|
|
1384
|
-
var ProgressBackground = styled4.div`
|
|
1385
|
-
position: absolute;
|
|
1386
|
-
top: 13px;
|
|
1387
|
-
left: 0;
|
|
1388
|
-
height: 6px;
|
|
1389
|
-
border-radius: 3px;
|
|
1390
|
-
width: 100%;
|
|
1391
|
-
pointer-events: none;
|
|
1392
|
-
background: #fff;
|
|
1393
|
-
`;
|
|
1394
|
-
var SoundButton = styled4(BaseButton)`
|
|
1395
|
-
width: 2em;
|
|
1396
|
-
height: 2em;
|
|
1397
|
-
overflow: hidden;
|
|
1398
|
-
font-size: 1.1em;
|
|
1399
|
-
background: transparent;
|
|
1400
|
-
border-radius: 3px;
|
|
1401
|
-
padding: 0;
|
|
1402
|
-
margin: 0;
|
|
1403
|
-
`;
|
|
1404
|
-
var SoundContainer = styled4.div`
|
|
1405
|
-
display: flex;
|
|
1406
|
-
align-items: center;
|
|
1407
|
-
`;
|
|
1408
|
-
var VolumeContainer = styled4.div`
|
|
1409
|
-
width: 0;
|
|
1410
|
-
overflow: hidden;
|
|
1411
|
-
transition: width 500ms;
|
|
1412
|
-
color: #4a473f; // Not in colours
|
|
1459
|
+
};
|
|
1460
|
+
async function createEmptyCanvas(data, ctx) {
|
|
1461
|
+
const canvasId = ctx.generateId("canvas");
|
|
1462
|
+
const page = ctx.embed({
|
|
1463
|
+
id: ctx.generateId("annotation-page", { id: canvasId, type: "Canvas" }),
|
|
1464
|
+
type: "AnnotationPage",
|
|
1465
|
+
items: []
|
|
1466
|
+
});
|
|
1467
|
+
return {
|
|
1468
|
+
id: canvasId,
|
|
1469
|
+
type: "Canvas",
|
|
1470
|
+
label: data.label || { en: [""] },
|
|
1471
|
+
height: data.height || 1e3,
|
|
1472
|
+
width: data.width || 1e3,
|
|
1473
|
+
items: [page]
|
|
1474
|
+
};
|
|
1475
|
+
}
|
|
1413
1476
|
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
`}
|
|
1417
|
-
`;
|
|
1418
|
-
var VolumeSlider = styled4.input.attrs({ type: "range" })`
|
|
1419
|
-
width: 120px;
|
|
1420
|
-
margin: 0 15px;
|
|
1421
|
-
`;
|
|
1477
|
+
// src/Canvas/InternalCanvas/index.tsx
|
|
1478
|
+
import { useManifest, useVault } from "react-iiif-vault";
|
|
1422
1479
|
|
|
1423
|
-
//
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
repeatCount: "indefinite"
|
|
1437
|
-
}
|
|
1438
|
-
) })
|
|
1439
|
-
] }) });
|
|
1480
|
+
// ../../node_modules/.pnpm/tiny-invariant@1.3.3/node_modules/tiny-invariant/dist/esm/tiny-invariant.js
|
|
1481
|
+
var isProduction = false;
|
|
1482
|
+
var prefix = "Invariant failed";
|
|
1483
|
+
function invariant(condition, message) {
|
|
1484
|
+
if (condition) {
|
|
1485
|
+
return;
|
|
1486
|
+
}
|
|
1487
|
+
if (isProduction) {
|
|
1488
|
+
throw new Error(prefix);
|
|
1489
|
+
}
|
|
1490
|
+
var provided = typeof message === "function" ? message() : message;
|
|
1491
|
+
var value = provided ? "".concat(prefix, ": ").concat(provided) : prefix;
|
|
1492
|
+
throw new Error(value);
|
|
1440
1493
|
}
|
|
1441
1494
|
|
|
1442
|
-
//
|
|
1443
|
-
import
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
const
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
if ($el.duration && props.onDuration) {
|
|
1480
|
-
props.onDuration($el.duration);
|
|
1481
|
-
}
|
|
1482
|
-
if (props.onDimensions && $el instanceof HTMLVideoElement) {
|
|
1483
|
-
props.onDimensions($el.videoWidth, $el.videoHeight);
|
|
1495
|
+
// src/Canvas/InternalCanvas/index.tsx
|
|
1496
|
+
import { IIIFExplorer } from "@manifest-editor/iiif-browser";
|
|
1497
|
+
import { jsx as jsx23 } from "react/jsx-runtime";
|
|
1498
|
+
var internalCanvas = {
|
|
1499
|
+
id: "@manifest-editor/internal-canvas",
|
|
1500
|
+
create: createInternalCanvas,
|
|
1501
|
+
label: "Internal canvas link",
|
|
1502
|
+
summary: "Canvas from the same manifest",
|
|
1503
|
+
icon: /* @__PURE__ */ jsx23(ThumbnailStripIcon, {}),
|
|
1504
|
+
resourceType: "Canvas",
|
|
1505
|
+
resourceFields: ["id", "type", "label"],
|
|
1506
|
+
supports: {
|
|
1507
|
+
parentTypes: ["Manifest"],
|
|
1508
|
+
parentFields: ["start"]
|
|
1509
|
+
},
|
|
1510
|
+
render: (ctx) => /* @__PURE__ */ jsx23(InternalCanvas, { ...ctx })
|
|
1511
|
+
};
|
|
1512
|
+
function InternalCanvas(props) {
|
|
1513
|
+
const manifest = useManifest();
|
|
1514
|
+
const vault = useVault();
|
|
1515
|
+
invariant(manifest, "Manifest is not loaded");
|
|
1516
|
+
return /* @__PURE__ */ jsx23(
|
|
1517
|
+
IIIFExplorer,
|
|
1518
|
+
{
|
|
1519
|
+
vault,
|
|
1520
|
+
entry: manifest,
|
|
1521
|
+
window: false,
|
|
1522
|
+
hideHeader: true,
|
|
1523
|
+
hideBack: true,
|
|
1524
|
+
output: { type: "url" },
|
|
1525
|
+
outputTargets: [
|
|
1526
|
+
{
|
|
1527
|
+
type: "callback",
|
|
1528
|
+
label: "Select canvas",
|
|
1529
|
+
cb: (url) => {
|
|
1530
|
+
props.runCreate({ id: url });
|
|
1531
|
+
}
|
|
1484
1532
|
}
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
$el.addEventListener("error", onError);
|
|
1488
|
-
return () => {
|
|
1489
|
-
$el.removeEventListener("loadedmetadata", loadedMetadata);
|
|
1490
|
-
$el.removeEventListener("error", onError);
|
|
1491
|
-
};
|
|
1533
|
+
],
|
|
1534
|
+
outputTypes: ["Canvas"]
|
|
1492
1535
|
}
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
{
|
|
1498
|
-
disabled: playRequested,
|
|
1499
|
-
onClick: () => {
|
|
1500
|
-
if (isPlaying) {
|
|
1501
|
-
pause();
|
|
1502
|
-
} else {
|
|
1503
|
-
play();
|
|
1504
|
-
}
|
|
1505
|
-
},
|
|
1506
|
-
children: playRequested ? /* @__PURE__ */ jsx29(Spinner, { stroke: "#999" }) : isPlaying ? /* @__PURE__ */ jsx29(PauseIcon, { title: "Pause" }) : /* @__PURE__ */ jsx29(PlayIcon, { title: "Play" })
|
|
1507
|
-
}
|
|
1508
|
-
),
|
|
1509
|
-
/* @__PURE__ */ jsx29(TimeDisplay, { ref: currentTime, children: "0:00" }),
|
|
1510
|
-
/* @__PURE__ */ jsxs13(
|
|
1511
|
-
ProgressContainer,
|
|
1512
|
-
{
|
|
1513
|
-
onClick: (e) => {
|
|
1514
|
-
const { left, width } = e.currentTarget.getBoundingClientRect();
|
|
1515
|
-
const percent = (e.pageX - left) / width;
|
|
1516
|
-
setDurationPercent(percent);
|
|
1517
|
-
},
|
|
1518
|
-
children: [
|
|
1519
|
-
/* @__PURE__ */ jsx29(ProgressBackground, {}),
|
|
1520
|
-
duration ? /* @__PURE__ */ jsx29(ProgressCurrent, { ref: progress }) : null
|
|
1521
|
-
]
|
|
1522
|
-
}
|
|
1523
|
-
),
|
|
1524
|
-
/* @__PURE__ */ jsx29(TimeDisplay, { children: formatTime(duration) }),
|
|
1525
|
-
/* @__PURE__ */ jsxs13(SoundContainer, { onMouseEnter: () => setIsVolumeOpen(true), onMouseLeave: () => setIsVolumeOpen(false), children: [
|
|
1526
|
-
/* @__PURE__ */ jsx29(VolumeContainer, { $isOpen: isVolumeOpen, children: /* @__PURE__ */ jsxs13("span", { children: [
|
|
1527
|
-
/* @__PURE__ */ jsx29(VisuallyHiddenLabel, { htmlFor: "audio-slider", children: "Change volume" }),
|
|
1528
|
-
/* @__PURE__ */ jsx29(
|
|
1529
|
-
VolumeSlider,
|
|
1530
|
-
{
|
|
1531
|
-
id: "audio-slider",
|
|
1532
|
-
role: "slider",
|
|
1533
|
-
disabled: isMuted,
|
|
1534
|
-
min: "0",
|
|
1535
|
-
max: "100",
|
|
1536
|
-
value: volume,
|
|
1537
|
-
onChange: (e) => setVolume(Number(e.currentTarget.value))
|
|
1538
|
-
}
|
|
1539
|
-
)
|
|
1540
|
-
] }) }),
|
|
1541
|
-
/* @__PURE__ */ jsx29(SoundButton, { onClick: () => toggleMute(), children: /* @__PURE__ */ jsx29(Volume, { title: isMuted ? "Mute" : "Unmute" }) })
|
|
1542
|
-
] })
|
|
1543
|
-
] });
|
|
1536
|
+
);
|
|
1537
|
+
}
|
|
1538
|
+
async function createInternalCanvas(data, ctx) {
|
|
1539
|
+
return ctx.embed({ id: data.id, type: "Canvas" });
|
|
1544
1540
|
}
|
|
1545
1541
|
|
|
1546
|
-
// src/
|
|
1547
|
-
import {
|
|
1548
|
-
import {
|
|
1549
|
-
import {
|
|
1550
|
-
import { jsx as
|
|
1551
|
-
async function
|
|
1552
|
-
|
|
1553
|
-
id: ctx.generateId(
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
id: data.url,
|
|
1559
|
-
type: "Sound",
|
|
1560
|
-
format: "audio/mp4",
|
|
1561
|
-
duration: data.duration || 0
|
|
1542
|
+
// src/ContentResource/HTMLBodyCreator/create-html-body.tsx
|
|
1543
|
+
import { InputContainer as InputContainer7, InputLabel as InputLabel7, RichTextLanguageField } from "@manifest-editor/editors";
|
|
1544
|
+
import { useConfig } from "@manifest-editor/shell";
|
|
1545
|
+
import { useState as useState6 } from "react";
|
|
1546
|
+
import { jsx as jsx24, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
1547
|
+
async function createHtmlBody(data, ctx) {
|
|
1548
|
+
return ctx.embed({
|
|
1549
|
+
id: ctx.generateId(`html/${data.language}`),
|
|
1550
|
+
language: data.language,
|
|
1551
|
+
type: "TextualBody",
|
|
1552
|
+
format: "text/html",
|
|
1553
|
+
value: data.body || ""
|
|
1562
1554
|
});
|
|
1563
|
-
if (targetType === "Annotation") {
|
|
1564
|
-
return ctx.embed({
|
|
1565
|
-
...annotation,
|
|
1566
|
-
label: getValue(data.label) && data.label,
|
|
1567
|
-
motivation: data.motivation || ctx.options.initialData?.motivation || "painting",
|
|
1568
|
-
body,
|
|
1569
|
-
target: ctx.getTarget()
|
|
1570
|
-
});
|
|
1571
|
-
}
|
|
1572
|
-
if (targetType === "Canvas") {
|
|
1573
|
-
const canvasId = ctx.generateId("canvas");
|
|
1574
|
-
const pageId = ctx.generateId("annotation-page", { id: canvasId, type: "Canvas" });
|
|
1575
|
-
const annotationResource = ctx.embed({
|
|
1576
|
-
...annotation,
|
|
1577
|
-
motivation: "painting",
|
|
1578
|
-
body,
|
|
1579
|
-
target: { type: "SpecificResource", source: { id: canvasId, type: "Canvas" } }
|
|
1580
|
-
});
|
|
1581
|
-
const page = ctx.embed({
|
|
1582
|
-
id: pageId,
|
|
1583
|
-
type: "AnnotationPage",
|
|
1584
|
-
items: [annotationResource]
|
|
1585
|
-
});
|
|
1586
|
-
return ctx.embed({
|
|
1587
|
-
id: canvasId,
|
|
1588
|
-
type: "Canvas",
|
|
1589
|
-
label: data.label || { en: ["Untitled HTML canvas"] },
|
|
1590
|
-
duration: data.duration || 0,
|
|
1591
|
-
items: [page]
|
|
1592
|
-
});
|
|
1593
|
-
}
|
|
1594
1555
|
}
|
|
1595
|
-
function
|
|
1596
|
-
const
|
|
1597
|
-
const [
|
|
1598
|
-
const [
|
|
1599
|
-
const [label, setLabel] = useState6({ en: [""] });
|
|
1556
|
+
function CreateHTMLBodyForm(props) {
|
|
1557
|
+
const { i18n } = useConfig();
|
|
1558
|
+
const [body, setBodyValue] = useState6("<p></p>");
|
|
1559
|
+
const [language, setLang] = useState6(i18n.defaultLanguage);
|
|
1600
1560
|
const onSubmit = () => {
|
|
1601
1561
|
props.runCreate({
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
label
|
|
1562
|
+
language,
|
|
1563
|
+
body
|
|
1605
1564
|
});
|
|
1606
1565
|
};
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1566
|
+
return /* @__PURE__ */ jsxs12(PaddedSidebarContainer, { children: [
|
|
1567
|
+
/* @__PURE__ */ jsxs12(InputContainer7, { children: [
|
|
1568
|
+
/* @__PURE__ */ jsx24(InputLabel7, { children: "HTML Body" }),
|
|
1569
|
+
/* @__PURE__ */ jsx24(
|
|
1570
|
+
RichTextLanguageField,
|
|
1571
|
+
{
|
|
1572
|
+
value: body,
|
|
1573
|
+
language,
|
|
1574
|
+
onUpdateLanguage: (lng) => setLang(lng),
|
|
1575
|
+
languages: i18n.availableLanguages,
|
|
1576
|
+
onUpdate: (e) => setBodyValue(e)
|
|
1577
|
+
}
|
|
1578
|
+
)
|
|
1620
1579
|
] }),
|
|
1621
|
-
|
|
1622
|
-
|
|
1580
|
+
/* @__PURE__ */ jsx24(Button, { onClick: () => onSubmit(), children: "Create" })
|
|
1581
|
+
] });
|
|
1582
|
+
}
|
|
1583
|
+
|
|
1584
|
+
// ../ui/icons/TextFormatIcon.tsx
|
|
1585
|
+
import { jsx as jsx25, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
1586
|
+
var TextFormatIcon = (props) => /* @__PURE__ */ jsxs13("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", height: "1em", width: "1em", ...props, children: [
|
|
1587
|
+
/* @__PURE__ */ jsx25("path", { d: "M0 0h24v24H0z", fill: "none" }),
|
|
1588
|
+
/* @__PURE__ */ jsx25("path", { d: "M5 17v2h14v-2H5zm4.5-4.2h5l.9 2.2h2.1L12.75 4h-1.5L6.5 15h2.1l.9-2.2zM12 5.98 13.87 11h-3.74L12 5.98z" })
|
|
1589
|
+
] });
|
|
1590
|
+
|
|
1591
|
+
// src/ContentResource/HTMLBodyCreator/index.tsx
|
|
1592
|
+
import { jsx as jsx26 } from "react/jsx-runtime";
|
|
1593
|
+
var htmlBodyCreator = {
|
|
1594
|
+
id: "@manifest-editor/html-body-creator",
|
|
1595
|
+
create: createHtmlBody,
|
|
1596
|
+
label: "HTML Body",
|
|
1597
|
+
summary: "Add HTML annotation body",
|
|
1598
|
+
icon: /* @__PURE__ */ jsx26(TextFormatIcon, {}),
|
|
1599
|
+
render(ctx) {
|
|
1600
|
+
return /* @__PURE__ */ jsx26(CreateHTMLBodyForm, { ...ctx });
|
|
1601
|
+
},
|
|
1602
|
+
resourceType: "ContentResource",
|
|
1603
|
+
resourceFields: ["id", "language", "type", "format", "value"],
|
|
1604
|
+
supports: {
|
|
1605
|
+
parentTypes: ["Annotation"],
|
|
1606
|
+
parentFields: ["body"]
|
|
1607
|
+
},
|
|
1608
|
+
staticFields: {
|
|
1609
|
+
type: "TextualBody",
|
|
1610
|
+
format: "text/html"
|
|
1611
|
+
}
|
|
1612
|
+
};
|
|
1613
|
+
|
|
1614
|
+
// src/ContentResource/IIIFBrowserCreator/index.tsx
|
|
1615
|
+
import { IIIFBrowserIcon } from "@manifest-editor/components";
|
|
1616
|
+
|
|
1617
|
+
// src/ContentResource/IIIFBrowserCreator/iiif-browser-creator.tsx
|
|
1618
|
+
import {
|
|
1619
|
+
normaliseContentState,
|
|
1620
|
+
parseContentState
|
|
1621
|
+
} from "@iiif/helpers";
|
|
1622
|
+
import { lazy } from "react";
|
|
1623
|
+
async function createFromIIIFBrowserOutput(data, ctx) {
|
|
1624
|
+
const targetType = ctx.options.targetType;
|
|
1625
|
+
if (Array.isArray(data.output)) {
|
|
1626
|
+
throw new Error("Multiple items not yet supported");
|
|
1627
|
+
}
|
|
1628
|
+
const contentState = normaliseContentState(
|
|
1629
|
+
typeof data.output === "string" ? parseContentState(data.output) : data.output
|
|
1630
|
+
);
|
|
1631
|
+
if (!contentState.target || contentState.target.length === 0) {
|
|
1632
|
+
throw new Error("No target found in content state");
|
|
1633
|
+
}
|
|
1634
|
+
const target = contentState.target[0];
|
|
1635
|
+
const type = target.source.type;
|
|
1636
|
+
const previewVault = ctx.getPreviewVault();
|
|
1637
|
+
if (targetType === "Canvas" || targetType === "Annotation") {
|
|
1638
|
+
if (type === "Canvas") {
|
|
1639
|
+
const canvasId = target.source.id;
|
|
1640
|
+
const manifestId = target.source.partOf?.find(
|
|
1641
|
+
(t) => t.type === "Manifest"
|
|
1642
|
+
);
|
|
1643
|
+
invariant(manifestId, "Could not load external resource without partOf");
|
|
1644
|
+
const manifest = await previewVault.loadManifest(manifestId);
|
|
1645
|
+
invariant(manifest, "Manifest not found");
|
|
1646
|
+
const canvasRef = manifest.items.find((item) => item.id === canvasId);
|
|
1647
|
+
invariant(canvasRef, "Canvas not found");
|
|
1648
|
+
const canvas = previewVault.get(canvasRef);
|
|
1649
|
+
if (targetType === "Canvas" && target.selector?.type !== "BoxSelector") {
|
|
1650
|
+
return ctx.embed(previewVault.toPresentation3(canvas));
|
|
1651
|
+
}
|
|
1652
|
+
const annotationPage = previewVault.get(canvas.items[0]);
|
|
1653
|
+
const annotation = previewVault.get(annotationPage.items[0]);
|
|
1654
|
+
if (targetType === "Annotation" || targetType === "Canvas") {
|
|
1655
|
+
const fullAnnotation = previewVault.toPresentation3(annotation);
|
|
1656
|
+
if (fullAnnotation?.body?.service) {
|
|
1657
|
+
const width = fullAnnotation?.body.width;
|
|
1658
|
+
const height = fullAnnotation?.body.height;
|
|
1659
|
+
const service = Array.isArray(fullAnnotation?.body?.service) ? fullAnnotation?.body?.service[0] : fullAnnotation?.body?.service;
|
|
1660
|
+
if (!service.width || !service.height) {
|
|
1661
|
+
service.width = width;
|
|
1662
|
+
service.height = height;
|
|
1663
|
+
}
|
|
1664
|
+
}
|
|
1665
|
+
if (target.selector && target.selector.type === "BoxSelector") {
|
|
1666
|
+
const selector = {
|
|
1667
|
+
"@context": "http://iiif.io/api/annex/openannotation/context.json",
|
|
1668
|
+
type: "iiif:ImageApiSelector",
|
|
1669
|
+
region: [
|
|
1670
|
+
~~target.selector.spatial.x,
|
|
1671
|
+
~~target.selector.spatial.y,
|
|
1672
|
+
~~target.selector.spatial.width,
|
|
1673
|
+
~~target.selector.spatial.height
|
|
1674
|
+
].join(",")
|
|
1675
|
+
};
|
|
1676
|
+
fullAnnotation.body = {
|
|
1677
|
+
id: ctx.generateId("SpecificResource", annotation),
|
|
1678
|
+
type: "SpecificResource",
|
|
1679
|
+
source: fullAnnotation.body,
|
|
1680
|
+
selector
|
|
1681
|
+
};
|
|
1682
|
+
if (targetType === "Canvas") {
|
|
1683
|
+
const canvasId2 = ctx.generateId("Canvas", annotation);
|
|
1684
|
+
fullAnnotation.target = canvasId2;
|
|
1685
|
+
const pageId = ctx.generateId("Page", annotation);
|
|
1686
|
+
const annotationPage2 = ctx.embed({
|
|
1687
|
+
id: pageId,
|
|
1688
|
+
type: "AnnotationPage",
|
|
1689
|
+
items: [fullAnnotation]
|
|
1690
|
+
});
|
|
1691
|
+
return ctx.embed({
|
|
1692
|
+
id: canvasId2,
|
|
1693
|
+
type: "Canvas",
|
|
1694
|
+
width: ~~target.selector.spatial.width,
|
|
1695
|
+
height: ~~target.selector.spatial.height,
|
|
1696
|
+
items: [annotationPage2]
|
|
1697
|
+
});
|
|
1698
|
+
}
|
|
1699
|
+
return ctx.embed({
|
|
1700
|
+
...fullAnnotation,
|
|
1701
|
+
target: ctx.getTarget()
|
|
1702
|
+
});
|
|
1703
|
+
}
|
|
1704
|
+
return ctx.embed({
|
|
1705
|
+
...previewVault.toPresentation3(annotation),
|
|
1706
|
+
target: ctx.getTarget()
|
|
1707
|
+
});
|
|
1708
|
+
}
|
|
1709
|
+
}
|
|
1710
|
+
}
|
|
1711
|
+
throw new Error("Not yet supported.");
|
|
1712
|
+
}
|
|
1713
|
+
var IIIFBrowserCreatorForm = lazy(
|
|
1714
|
+
() => import("./iiif-browser-form.lazy-W42LJ6X2.js")
|
|
1715
|
+
);
|
|
1716
|
+
|
|
1717
|
+
// src/ContentResource/IIIFBrowserCreator/index.tsx
|
|
1718
|
+
import { jsx as jsx27 } from "react/jsx-runtime";
|
|
1719
|
+
var iiifBrowserCreator = {
|
|
1720
|
+
id: "@manifest-editor/iiif-browser-creator",
|
|
1721
|
+
create: createFromIIIFBrowserOutput,
|
|
1722
|
+
label: "IIIF Browser",
|
|
1723
|
+
summary: "Browse IIIF Resources",
|
|
1724
|
+
icon: /* @__PURE__ */ jsx27(IIIFBrowserIcon, {}),
|
|
1725
|
+
render(ctx) {
|
|
1726
|
+
return /* @__PURE__ */ jsx27(IIIFBrowserCreatorForm, { ...ctx });
|
|
1727
|
+
},
|
|
1728
|
+
hiddenModal: true,
|
|
1729
|
+
tags: ["image", "image-service"],
|
|
1730
|
+
resourceType: "ContentResource",
|
|
1731
|
+
resourceFields: ["id", "language", "type", "format", "value"],
|
|
1732
|
+
additionalTypes: ["Annotation", "Canvas"],
|
|
1733
|
+
supports: {
|
|
1734
|
+
parentTypes: ["Annotation", "Manifest", "AnnotationPage"],
|
|
1735
|
+
parentFieldMap: {
|
|
1736
|
+
Annotation: ["body"],
|
|
1737
|
+
Manifest: ["items"],
|
|
1738
|
+
AnnotationPage: ["items"]
|
|
1739
|
+
}
|
|
1740
|
+
},
|
|
1741
|
+
sideEffects: [
|
|
1742
|
+
resizeToFitService,
|
|
1743
|
+
resizeResourceToEmptyCanvas,
|
|
1744
|
+
repositionMultipleImages
|
|
1745
|
+
],
|
|
1746
|
+
staticFields: {}
|
|
1747
|
+
};
|
|
1748
|
+
|
|
1749
|
+
// src/ContentResource/ImageServiceCreator/index.tsx
|
|
1750
|
+
import { jsx as jsx28 } from "react/jsx-runtime";
|
|
1751
|
+
var imageServiceCreator = {
|
|
1752
|
+
id: "@manifest-editor/image-service-creator",
|
|
1753
|
+
create: createImageServer,
|
|
1754
|
+
label: "Image Service",
|
|
1755
|
+
summary: "Add an image from Image Service",
|
|
1756
|
+
icon: /* @__PURE__ */ jsx28(TextFormatIcon, {}),
|
|
1757
|
+
render(ctx) {
|
|
1758
|
+
return /* @__PURE__ */ jsx28(CreateImageServerForm, { ...ctx });
|
|
1759
|
+
},
|
|
1760
|
+
resourceType: "ContentResource",
|
|
1761
|
+
resourceFields: ["id", "type", "height", "width", "format", "service"],
|
|
1762
|
+
supports: {
|
|
1763
|
+
parentFields: ["logo", "body", "thumbnail"]
|
|
1764
|
+
},
|
|
1765
|
+
staticFields: {
|
|
1766
|
+
type: "Image"
|
|
1767
|
+
}
|
|
1768
|
+
};
|
|
1769
|
+
|
|
1770
|
+
// src/ContentResource/ImageUrlCreator/index.tsx
|
|
1771
|
+
import { AddImageIcon as AddImageIcon3 } from "@manifest-editor/components";
|
|
1772
|
+
import { jsx as jsx29 } from "react/jsx-runtime";
|
|
1773
|
+
var imageUrlCreator = {
|
|
1774
|
+
id: "@manifest-editor/image-url-creator",
|
|
1775
|
+
create: createImageUrl,
|
|
1776
|
+
label: "Image",
|
|
1777
|
+
summary: "Image from a URL",
|
|
1778
|
+
icon: /* @__PURE__ */ jsx29(AddImageIcon3, {}),
|
|
1779
|
+
render(ctx) {
|
|
1780
|
+
return /* @__PURE__ */ jsx29(CreateImageUrlForm, { ...ctx });
|
|
1781
|
+
},
|
|
1782
|
+
resourceType: "ContentResource",
|
|
1783
|
+
resourceFields: ["format"],
|
|
1784
|
+
supports: {
|
|
1785
|
+
parentFields: ["logo", "body", "thumbnail"]
|
|
1786
|
+
},
|
|
1787
|
+
staticFields: {
|
|
1788
|
+
type: "Image"
|
|
1789
|
+
}
|
|
1790
|
+
};
|
|
1791
|
+
|
|
1792
|
+
// src/ContentResource/PlaintextCreator/create-plaintext.tsx
|
|
1793
|
+
import { LanguageFieldEditor as LanguageFieldEditor5, InputContainer as InputContainer8, InputLabel as InputLabel8, Input as Input6 } from "@manifest-editor/editors";
|
|
1794
|
+
import { useState as useState7 } from "react";
|
|
1795
|
+
import { jsx as jsx30, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
1796
|
+
async function createPlaintext(data, ctx) {
|
|
1797
|
+
return ctx.embed({
|
|
1798
|
+
id: data.url,
|
|
1799
|
+
type: "Text",
|
|
1800
|
+
label: data.label,
|
|
1801
|
+
format: "text/plain"
|
|
1802
|
+
});
|
|
1803
|
+
}
|
|
1804
|
+
function CreatePlaintextForm(props) {
|
|
1805
|
+
const [label, setLabel] = useState7({ en: ["View as text"] });
|
|
1806
|
+
const onSubmit = (e) => {
|
|
1807
|
+
e.preventDefault();
|
|
1808
|
+
const data = new FormData(e.target);
|
|
1809
|
+
const formData = Object.fromEntries(data.entries());
|
|
1810
|
+
if (formData.url) {
|
|
1811
|
+
props.runCreate({ url: formData.url, label });
|
|
1812
|
+
}
|
|
1813
|
+
};
|
|
1814
|
+
return /* @__PURE__ */ jsx30(PaddedSidebarContainer, { children: /* @__PURE__ */ jsxs14("form", { onSubmit, children: [
|
|
1815
|
+
/* @__PURE__ */ jsx30(
|
|
1816
|
+
LanguageFieldEditor5,
|
|
1623
1817
|
{
|
|
1624
|
-
|
|
1625
|
-
focusId: "label_",
|
|
1818
|
+
focusId: "label",
|
|
1626
1819
|
label: "Label",
|
|
1627
1820
|
fields: label,
|
|
1628
1821
|
onSave: (e) => setLabel(e.toInternationalString())
|
|
1629
|
-
}
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1822
|
+
}
|
|
1823
|
+
),
|
|
1824
|
+
/* @__PURE__ */ jsxs14(InputContainer8, { $wide: true, children: [
|
|
1825
|
+
/* @__PURE__ */ jsx30(InputLabel8, { htmlFor: "id", children: "Link to plaintext" }),
|
|
1826
|
+
/* @__PURE__ */ jsx30(Input6, { id: "url", name: "url", defaultValue: "" })
|
|
1827
|
+
] }),
|
|
1828
|
+
/* @__PURE__ */ jsx30(Button, { type: "submit", children: "Create" })
|
|
1829
|
+
] }) });
|
|
1830
|
+
}
|
|
1831
|
+
|
|
1832
|
+
// src/ContentResource/PlaintextCreator/index.tsx
|
|
1833
|
+
import { jsx as jsx31 } from "react/jsx-runtime";
|
|
1834
|
+
var plaintextCreator = {
|
|
1835
|
+
id: "@manifest-editor/plaintext-creator",
|
|
1836
|
+
create: createPlaintext,
|
|
1837
|
+
label: "Plaintext",
|
|
1838
|
+
summary: "Add link to an plaintext",
|
|
1839
|
+
icon: /* @__PURE__ */ jsx31(TextFormatIcon, {}),
|
|
1840
|
+
render(ctx) {
|
|
1841
|
+
return /* @__PURE__ */ jsx31(CreatePlaintextForm, { ...ctx });
|
|
1842
|
+
},
|
|
1843
|
+
resourceType: "ContentResource",
|
|
1844
|
+
resourceFields: ["label", "format"],
|
|
1845
|
+
supports: {
|
|
1846
|
+
parentFields: ["seeAlso", "rendering", "homepage"]
|
|
1847
|
+
},
|
|
1848
|
+
staticFields: {
|
|
1849
|
+
format: "text/plain"
|
|
1850
|
+
}
|
|
1851
|
+
};
|
|
1852
|
+
|
|
1853
|
+
// src/ContentResource/WebPageCreator/create-web-page.tsx
|
|
1854
|
+
import { LanguageFieldEditor as LanguageFieldEditor6, InputContainer as InputContainer9, InputLabel as InputLabel9, Input as Input7 } from "@manifest-editor/editors";
|
|
1855
|
+
import { useState as useState8 } from "react";
|
|
1856
|
+
import { jsx as jsx32, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
1857
|
+
async function createWebPage(data, ctx) {
|
|
1858
|
+
return ctx.embed({
|
|
1859
|
+
id: data.url,
|
|
1860
|
+
type: "Text",
|
|
1861
|
+
label: data.label,
|
|
1862
|
+
format: "text/html"
|
|
1863
|
+
});
|
|
1864
|
+
}
|
|
1865
|
+
function CreateWebPageForm(props) {
|
|
1866
|
+
const [label, setLabel] = useState8({ en: [""] });
|
|
1867
|
+
const onSubmit = (e) => {
|
|
1868
|
+
e.preventDefault();
|
|
1869
|
+
const data = new FormData(e.target);
|
|
1870
|
+
const formData = Object.fromEntries(data.entries());
|
|
1871
|
+
if (formData.url) {
|
|
1872
|
+
props.runCreate({ url: formData.url, label });
|
|
1873
|
+
}
|
|
1874
|
+
};
|
|
1875
|
+
return /* @__PURE__ */ jsx32(PaddedSidebarContainer, { children: /* @__PURE__ */ jsxs15("form", { onSubmit, children: [
|
|
1876
|
+
/* @__PURE__ */ jsx32(
|
|
1877
|
+
LanguageFieldEditor6,
|
|
1878
|
+
{
|
|
1879
|
+
focusId: "label",
|
|
1880
|
+
label: "Label",
|
|
1881
|
+
fields: label,
|
|
1882
|
+
onSave: (e) => setLabel(e.toInternationalString())
|
|
1883
|
+
}
|
|
1884
|
+
),
|
|
1885
|
+
/* @__PURE__ */ jsxs15(InputContainer9, { $wide: true, children: [
|
|
1886
|
+
/* @__PURE__ */ jsx32(InputLabel9, { htmlFor: "id", children: "Link" }),
|
|
1887
|
+
/* @__PURE__ */ jsx32(Input7, { id: "url", name: "url", defaultValue: "" })
|
|
1888
|
+
] }),
|
|
1889
|
+
/* @__PURE__ */ jsx32(Button, { type: "submit", children: "Create link" })
|
|
1890
|
+
] }) });
|
|
1891
|
+
}
|
|
1892
|
+
|
|
1893
|
+
// ../ui/icons/LinkIcon.tsx
|
|
1894
|
+
import { jsx as jsx33, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
1895
|
+
function LinkIcon() {
|
|
1896
|
+
return /* @__PURE__ */ jsxs16("svg", { xmlns: "http://www.w3.org/2000/svg", height: "24px", viewBox: "0 0 24 24", width: "24px", fill: "#000000", children: [
|
|
1897
|
+
/* @__PURE__ */ jsx33("path", { d: "M0 0h24v24H0z", fill: "none" }),
|
|
1898
|
+
/* @__PURE__ */ jsx33("path", { d: "M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76 0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71 0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71 0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76 0 5-2.24 5-5s-2.24-5-5-5z" })
|
|
1645
1899
|
] });
|
|
1646
1900
|
}
|
|
1647
1901
|
|
|
1648
|
-
// src/
|
|
1649
|
-
import {
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
icon: /* @__PURE__ */ jsx31(AudioIcon, {}),
|
|
1902
|
+
// src/ContentResource/WebPageCreator/index.tsx
|
|
1903
|
+
import { jsx as jsx34 } from "react/jsx-runtime";
|
|
1904
|
+
var webPageCreator = {
|
|
1905
|
+
id: "@manifest-editor/web-page-creator",
|
|
1906
|
+
create: createWebPage,
|
|
1907
|
+
label: "Web page",
|
|
1908
|
+
summary: "Add link to an external web page",
|
|
1909
|
+
icon: /* @__PURE__ */ jsx34(LinkIcon, {}),
|
|
1657
1910
|
render(ctx) {
|
|
1658
|
-
return /* @__PURE__ */
|
|
1911
|
+
return /* @__PURE__ */ jsx34(CreateWebPageForm, { ...ctx });
|
|
1659
1912
|
},
|
|
1660
|
-
resourceType: "
|
|
1661
|
-
resourceFields: ["
|
|
1662
|
-
additionalTypes: ["Canvas"],
|
|
1913
|
+
resourceType: "ContentResource",
|
|
1914
|
+
resourceFields: ["label", "format"],
|
|
1663
1915
|
supports: {
|
|
1664
|
-
|
|
1665
|
-
parentTypes: ["AnnotationPage", "Manifest"],
|
|
1666
|
-
parentFields: ["items"]
|
|
1667
|
-
},
|
|
1668
|
-
staticFields: {
|
|
1669
|
-
type: "Annotation"
|
|
1916
|
+
parentFields: ["seeAlso", "rendering", "homepage"]
|
|
1670
1917
|
}
|
|
1671
1918
|
};
|
|
1672
1919
|
|
|
1673
|
-
// src/
|
|
1674
|
-
import {
|
|
1675
|
-
import { InputContainer as InputContainer9, InputLabel as InputLabel9, Input as Input7, LanguageFieldEditor as LanguageFieldEditor5, DimensionsTriplet } from "@manifest-editor/editors";
|
|
1676
|
-
import { useState as useState7, useEffect as useEffect3 } from "react";
|
|
1920
|
+
// src/ContentResource/YouTubeCreator/index.tsx
|
|
1921
|
+
import { YouTubeIcon } from "@manifest-editor/components";
|
|
1677
1922
|
|
|
1678
|
-
//
|
|
1679
|
-
import {
|
|
1680
|
-
import { jsx as
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
onDuration,
|
|
1686
|
-
onDimensions
|
|
1687
|
-
}) {
|
|
1688
|
-
const [{ element, currentTime, progress }, state, actions] = useSimpleMediaPlayer({ duration });
|
|
1689
|
-
return /* @__PURE__ */ jsxs15(
|
|
1690
|
-
MediaPlayerProvider,
|
|
1691
|
-
{
|
|
1692
|
-
element,
|
|
1693
|
-
state,
|
|
1694
|
-
actions,
|
|
1695
|
-
currentTime,
|
|
1696
|
-
progress,
|
|
1697
|
-
children: [
|
|
1698
|
-
/* @__PURE__ */ jsx32(
|
|
1699
|
-
"div",
|
|
1700
|
-
{
|
|
1701
|
-
style: {
|
|
1702
|
-
maxHeight: 400,
|
|
1703
|
-
aspectRatio: `${media.width}/${media.height}`,
|
|
1704
|
-
position: "relative"
|
|
1705
|
-
},
|
|
1706
|
-
children: /* @__PURE__ */ jsx32(CanvasPanel2.VideoHTML, { element, media, playPause: actions.playPause })
|
|
1707
|
-
}
|
|
1708
|
-
),
|
|
1709
|
-
/* @__PURE__ */ jsx32(MediaControls, { onError, onDuration, onDimensions })
|
|
1710
|
-
]
|
|
1711
|
-
}
|
|
1712
|
-
);
|
|
1923
|
+
// src/ContentResource/YouTubeCreator/create-youtube-body.tsx
|
|
1924
|
+
import { Input as Input8, InputContainer as InputContainer10, InputLabel as InputLabel10 } from "@manifest-editor/editors";
|
|
1925
|
+
import { jsx as jsx35, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
1926
|
+
var ytRegex = /^.*(?:(?:youtu\.be\/|v\/|vi\/|u\/\w\/|embed\/|shorts\/)|(?:(?:watch)?\?vi?=|&vi?=))([^#&?]*).*/;
|
|
1927
|
+
function getYouTubeId(url) {
|
|
1928
|
+
const id = (url || "").match(ytRegex);
|
|
1929
|
+
return id ? id[1] : null;
|
|
1713
1930
|
}
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
const annotation = {
|
|
1719
|
-
id: ctx.generateId("annotation"),
|
|
1720
|
-
type: "Annotation"
|
|
1721
|
-
};
|
|
1722
|
-
const targetType = ctx.options.targetType;
|
|
1723
|
-
const body = await ctx.embed({
|
|
1724
|
-
id: data.url,
|
|
1931
|
+
async function createYoutubeBody(data, ctx) {
|
|
1932
|
+
const id = getYouTubeId(data.youtubeUrl);
|
|
1933
|
+
const body = ctx.embed({
|
|
1934
|
+
id: `https://www.youtube.com/watch?v=${id}`,
|
|
1725
1935
|
type: "Video",
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1936
|
+
service: [
|
|
1937
|
+
{
|
|
1938
|
+
profile: "http://digirati.com/objectifier",
|
|
1939
|
+
params: {
|
|
1940
|
+
data: `https://www.youtube.com/embed/${id}`
|
|
1941
|
+
}
|
|
1942
|
+
},
|
|
1943
|
+
{
|
|
1944
|
+
id: `https://www.youtube.com/watch?v=${id}`,
|
|
1945
|
+
profile: "https://www.youtube.com"
|
|
1946
|
+
}
|
|
1947
|
+
]
|
|
1730
1948
|
});
|
|
1731
|
-
if (targetType === "
|
|
1732
|
-
return ctx.embed({
|
|
1733
|
-
...annotation,
|
|
1734
|
-
label: getValue2(data.label) && data.label,
|
|
1735
|
-
motivation: data.motivation || ctx.options.initialData?.motivation || "painting",
|
|
1736
|
-
body,
|
|
1737
|
-
target: ctx.getTarget()
|
|
1738
|
-
});
|
|
1739
|
-
}
|
|
1740
|
-
if (targetType === "Canvas") {
|
|
1949
|
+
if (ctx.options.targetType === "Canvas") {
|
|
1741
1950
|
const canvasId = ctx.generateId("canvas");
|
|
1742
|
-
const pageId = ctx.generateId("annotation-page", {
|
|
1743
|
-
|
|
1744
|
-
|
|
1951
|
+
const pageId = ctx.generateId("annotation-page", {
|
|
1952
|
+
id: canvasId,
|
|
1953
|
+
type: "Canvas"
|
|
1954
|
+
});
|
|
1955
|
+
const annotation = ctx.embed({
|
|
1956
|
+
id: ctx.generateId("annotation", { id: pageId, type: "AnnotationPage" }),
|
|
1957
|
+
type: "Annotation",
|
|
1745
1958
|
motivation: "painting",
|
|
1746
|
-
body,
|
|
1747
|
-
target: {
|
|
1959
|
+
body: [body],
|
|
1960
|
+
target: {
|
|
1961
|
+
type: "SpecificResource",
|
|
1962
|
+
source: { id: canvasId, type: "Canvas" }
|
|
1963
|
+
}
|
|
1748
1964
|
});
|
|
1749
1965
|
const page = ctx.embed({
|
|
1750
1966
|
id: pageId,
|
|
1751
1967
|
type: "AnnotationPage",
|
|
1752
|
-
items: [
|
|
1968
|
+
items: [annotation]
|
|
1753
1969
|
});
|
|
1754
1970
|
return ctx.embed({
|
|
1755
1971
|
id: canvasId,
|
|
1756
1972
|
type: "Canvas",
|
|
1757
|
-
label: data.label || { en: ["Untitled
|
|
1758
|
-
|
|
1759
|
-
width: data.width,
|
|
1760
|
-
|
|
1973
|
+
label: data.label || { en: ["Untitled YouTube canvas"] },
|
|
1974
|
+
height: data.height || 1e3,
|
|
1975
|
+
width: data.width || 1e3,
|
|
1976
|
+
duration: data.duration || 1,
|
|
1761
1977
|
items: [page]
|
|
1762
1978
|
});
|
|
1763
1979
|
}
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
const [label, setLabel] = useState7({ en: [""] });
|
|
1772
|
-
const onSubmit = () => {
|
|
1773
|
-
props.runCreate({
|
|
1774
|
-
url,
|
|
1775
|
-
duration,
|
|
1776
|
-
label,
|
|
1777
|
-
width,
|
|
1778
|
-
height
|
|
1980
|
+
if (ctx.options.targetType === "Annotation") {
|
|
1981
|
+
return ctx.embed({
|
|
1982
|
+
id: ctx.generateId("annotation"),
|
|
1983
|
+
type: "Annotation",
|
|
1984
|
+
motivation: "painting",
|
|
1985
|
+
body: [body],
|
|
1986
|
+
target: ctx.getTarget()
|
|
1779
1987
|
});
|
|
1780
|
-
}
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1988
|
+
}
|
|
1989
|
+
return body;
|
|
1990
|
+
}
|
|
1991
|
+
function YouTubeForm(props) {
|
|
1992
|
+
const onSubmit = (e) => {
|
|
1993
|
+
e.preventDefault();
|
|
1994
|
+
const data = new FormData(e.target);
|
|
1995
|
+
const formData = Object.fromEntries(data.entries());
|
|
1996
|
+
if (formData.youtubeUrl) {
|
|
1997
|
+
props.runCreate({ youtubeUrl: formData.youtubeUrl });
|
|
1787
1998
|
}
|
|
1788
|
-
}
|
|
1789
|
-
return /* @__PURE__ */
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
/* @__PURE__ */
|
|
1793
|
-
/* @__PURE__ */ jsx33(Input7, { type: "text", id: "video-url", value: url, onChange: (e) => setUrl(e.target.value) })
|
|
1999
|
+
};
|
|
2000
|
+
return /* @__PURE__ */ jsx35(PaddedSidebarContainer, { children: /* @__PURE__ */ jsxs17("form", { onSubmit, children: [
|
|
2001
|
+
/* @__PURE__ */ jsxs17(InputContainer10, { $wide: true, children: [
|
|
2002
|
+
/* @__PURE__ */ jsx35(InputLabel10, { htmlFor: "id", children: "Link to YouTube" }),
|
|
2003
|
+
/* @__PURE__ */ jsx35(Input8, { id: "youtubeUrl", name: "youtubeUrl", defaultValue: "" })
|
|
1794
2004
|
] }),
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
{
|
|
1798
|
-
containerId: "label",
|
|
1799
|
-
focusId: "label_",
|
|
1800
|
-
label: "Label",
|
|
1801
|
-
fields: label,
|
|
1802
|
-
onSave: (e) => setLabel(e.toInternationalString())
|
|
1803
|
-
},
|
|
1804
|
-
url + "__" + duration
|
|
1805
|
-
) }) : null,
|
|
1806
|
-
url && !error ? /* @__PURE__ */ jsx33(
|
|
1807
|
-
VideoPlayer,
|
|
1808
|
-
{
|
|
1809
|
-
duration,
|
|
1810
|
-
onDuration: (d) => setDuration(d),
|
|
1811
|
-
onError: (err) => setError(err),
|
|
1812
|
-
media: {
|
|
1813
|
-
url,
|
|
1814
|
-
duration,
|
|
1815
|
-
height,
|
|
1816
|
-
width,
|
|
1817
|
-
type: "Video"
|
|
1818
|
-
},
|
|
1819
|
-
onDimensions: (w, h) => {
|
|
1820
|
-
setWidth(w || 0);
|
|
1821
|
-
setHeight(h || 0);
|
|
1822
|
-
}
|
|
1823
|
-
}
|
|
1824
|
-
) : null,
|
|
1825
|
-
!error && (duration || width || height) ? /* @__PURE__ */ jsx33(InputContainer9, { $wide: true, children: /* @__PURE__ */ jsx33(
|
|
1826
|
-
DimensionsTriplet,
|
|
1827
|
-
{
|
|
1828
|
-
widthId: "width",
|
|
1829
|
-
width: width || 0,
|
|
1830
|
-
changeWidth: (v) => setWidth(v),
|
|
1831
|
-
heightId: "height",
|
|
1832
|
-
height: height || 0,
|
|
1833
|
-
changeHeight: (v) => setHeight(v),
|
|
1834
|
-
durationId: "duration",
|
|
1835
|
-
duration: duration || 0,
|
|
1836
|
-
changeDuration: (v) => setDuration(v)
|
|
1837
|
-
}
|
|
1838
|
-
) }) : null,
|
|
1839
|
-
url && !error && /* @__PURE__ */ jsx33(Button, { onClick: onSubmit, children: "Add video" })
|
|
1840
|
-
] });
|
|
2005
|
+
/* @__PURE__ */ jsx35(Button, { type: "submit", children: "Create" })
|
|
2006
|
+
] }) });
|
|
1841
2007
|
}
|
|
1842
2008
|
|
|
1843
|
-
// src/
|
|
1844
|
-
import {
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
},
|
|
1855
|
-
resourceType: "Annotation",
|
|
1856
|
-
resourceFields: ["id", "type", "motivation", "body", "target"],
|
|
1857
|
-
additionalTypes: ["Canvas"],
|
|
2009
|
+
// src/ContentResource/YouTubeCreator/index.tsx
|
|
2010
|
+
import { jsx as jsx36 } from "react/jsx-runtime";
|
|
2011
|
+
var youTubeBodyCreator = {
|
|
2012
|
+
id: "@manifest-editor/youtube",
|
|
2013
|
+
create: createYoutubeBody,
|
|
2014
|
+
label: "YouTube",
|
|
2015
|
+
summary: "Embed YouTube",
|
|
2016
|
+
icon: /* @__PURE__ */ jsx36(YouTubeIcon, {}),
|
|
2017
|
+
resourceType: "ContentResource",
|
|
2018
|
+
additionalTypes: ["Canvas", "Annotation"],
|
|
2019
|
+
resourceFields: ["id", "type", "service"],
|
|
2020
|
+
render: (ctx) => /* @__PURE__ */ jsx36(YouTubeForm, { ...ctx }),
|
|
1858
2021
|
supports: {
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
2022
|
+
parentTypes: ["Annotation", "Manifest", "AnnotationPage"],
|
|
2023
|
+
parentFieldMap: {
|
|
2024
|
+
Annotation: ["body"],
|
|
2025
|
+
Manifest: ["items"],
|
|
2026
|
+
AnnotationPage: ["items"]
|
|
2027
|
+
}
|
|
1862
2028
|
},
|
|
1863
2029
|
staticFields: {
|
|
1864
|
-
type: "
|
|
2030
|
+
type: "Video"
|
|
1865
2031
|
}
|
|
1866
2032
|
};
|
|
1867
2033
|
|
|
@@ -1907,15 +2073,15 @@ var ManifestBrowserCreatorForm2 = lazy2(() => import("./manifest-browser-form.la
|
|
|
1907
2073
|
|
|
1908
2074
|
// src/Manifest/ManifestBrowserCreator/index.tsx
|
|
1909
2075
|
import { IIIFBrowserIcon as IIIFBrowserIcon2 } from "@manifest-editor/components";
|
|
1910
|
-
import { jsx as
|
|
2076
|
+
import { jsx as jsx37 } from "react/jsx-runtime";
|
|
1911
2077
|
var manifestBrowserCreator = {
|
|
1912
2078
|
id: "@manifest-editor/manifest-browser-creator",
|
|
1913
2079
|
create: createFromManifestBrowserOutput,
|
|
1914
2080
|
label: "IIIF Browser",
|
|
1915
2081
|
summary: "Browse IIIF Resources",
|
|
1916
|
-
icon: /* @__PURE__ */
|
|
2082
|
+
icon: /* @__PURE__ */ jsx37(IIIFBrowserIcon2, {}),
|
|
1917
2083
|
render(ctx) {
|
|
1918
|
-
return /* @__PURE__ */
|
|
2084
|
+
return /* @__PURE__ */ jsx37(ManifestBrowserCreatorForm, { ...ctx });
|
|
1919
2085
|
},
|
|
1920
2086
|
resourceType: "Manifest",
|
|
1921
2087
|
resourceFields: ["id", "label"],
|
|
@@ -1948,11 +2114,13 @@ var allCreators = [
|
|
|
1948
2114
|
webPageCreator,
|
|
1949
2115
|
emptyAnnotationPage,
|
|
1950
2116
|
noBodyAnnotation,
|
|
1951
|
-
internalCanvas
|
|
2117
|
+
internalCanvas,
|
|
2118
|
+
captionedImageAnnotation
|
|
1952
2119
|
];
|
|
1953
2120
|
export {
|
|
1954
2121
|
allCreators,
|
|
1955
2122
|
audioAnnotation,
|
|
2123
|
+
captionedImageAnnotation,
|
|
1956
2124
|
emptyAnnotationPage,
|
|
1957
2125
|
emptyCanvas,
|
|
1958
2126
|
htmlAnnotation,
|