@manifest-editor/creators 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/dist/chunk-7FSKLOVQ.js +33 -0
- package/dist/chunk-YSQDPG26.js +30 -0
- package/dist/iiif-browser-form.lazy-C3VAAY7I.js +34 -0
- package/dist/iiif-browser-form.lazy-PL3WMLU5.js +33 -0
- package/dist/iiif-browser-form.lazy-QLO62DFA.js +32 -0
- package/dist/iiif-browser-form.lazy-ZADCSMAN.js +32 -0
- package/dist/index.cjs +2082 -0
- package/dist/index.d.cts +40 -0
- package/dist/index.d.ts +40 -0
- package/dist/index.js +1972 -0
- package/dist/manifest-browser-form.lazy-FLU4HSPW.js +7 -0
- package/dist/manifest-browser-form.lazy-WRWZPVRC.js +6 -0
- package/package.json +73 -0
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,2082 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __esm = (fn, res) => function __init() {
|
|
9
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
10
|
+
};
|
|
11
|
+
var __export = (target, all) => {
|
|
12
|
+
for (var name in all)
|
|
13
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
14
|
+
};
|
|
15
|
+
var __copyProps = (to, from, except, desc) => {
|
|
16
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
17
|
+
for (let key of __getOwnPropNames(from))
|
|
18
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
19
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
20
|
+
}
|
|
21
|
+
return to;
|
|
22
|
+
};
|
|
23
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
24
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
25
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
26
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
27
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
28
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
29
|
+
mod
|
|
30
|
+
));
|
|
31
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
32
|
+
|
|
33
|
+
// src/ContentResource/IIIFBrowserCreator/iiif-browser-form.lazy.tsx
|
|
34
|
+
var iiif_browser_form_lazy_exports = {};
|
|
35
|
+
__export(iiif_browser_form_lazy_exports, {
|
|
36
|
+
default: () => IIIFBrowserCreatorForm
|
|
37
|
+
});
|
|
38
|
+
function IIIFBrowserCreatorForm(props) {
|
|
39
|
+
const vault = (0, import_shell3.usePreviewVault)();
|
|
40
|
+
const { addHistory, clearHistory } = (0, import_shell3.usePreviewHistory)();
|
|
41
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_shell3.PreviewVaultBoundary, { children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
42
|
+
import_iiif_browser.IIIFExplorer,
|
|
43
|
+
{
|
|
44
|
+
window: false,
|
|
45
|
+
hideHeader: true,
|
|
46
|
+
outputTypes: ["Canvas", "CanvasList", "CanvasRegion", "ImageService", "ImageServiceRegion"],
|
|
47
|
+
vault,
|
|
48
|
+
output: { type: "content-state" },
|
|
49
|
+
homepageCollection: import_shell3.HOMEPAGE_COLLECTION,
|
|
50
|
+
clearHomepageCollection: clearHistory,
|
|
51
|
+
onHistory: addHistory,
|
|
52
|
+
height: 500,
|
|
53
|
+
outputTargets: [
|
|
54
|
+
{
|
|
55
|
+
type: "callback",
|
|
56
|
+
label: "Select",
|
|
57
|
+
cb: (resource) => props.runCreate({ output: resource })
|
|
58
|
+
}
|
|
59
|
+
],
|
|
60
|
+
allowRemoveEntry: true
|
|
61
|
+
}
|
|
62
|
+
) });
|
|
63
|
+
}
|
|
64
|
+
var import_iiif_browser, import_shell3, import_jsx_runtime23;
|
|
65
|
+
var init_iiif_browser_form_lazy = __esm({
|
|
66
|
+
"src/ContentResource/IIIFBrowserCreator/iiif-browser-form.lazy.tsx"() {
|
|
67
|
+
"use strict";
|
|
68
|
+
import_iiif_browser = require("@manifest-editor/iiif-browser");
|
|
69
|
+
import_shell3 = require("@manifest-editor/shell");
|
|
70
|
+
import_jsx_runtime23 = require("react/jsx-runtime");
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
// src/Manifest/ManifestBrowserCreator/manifest-browser-form.lazy.tsx
|
|
75
|
+
var manifest_browser_form_lazy_exports = {};
|
|
76
|
+
__export(manifest_browser_form_lazy_exports, {
|
|
77
|
+
default: () => ManifestBrowserCreatorForm
|
|
78
|
+
});
|
|
79
|
+
function ManifestBrowserCreatorForm(props) {
|
|
80
|
+
const vault = (0, import_shell4.usePreviewVault)();
|
|
81
|
+
const { addHistory, clearHistory } = (0, import_shell4.usePreviewHistory)();
|
|
82
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_jsx_runtime36.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_shell4.PreviewVaultBoundary, { children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
83
|
+
import_iiif_browser3.IIIFExplorer,
|
|
84
|
+
{
|
|
85
|
+
window: false,
|
|
86
|
+
hideHeader: true,
|
|
87
|
+
outputTypes: ["Manifest", "Collection"],
|
|
88
|
+
vault,
|
|
89
|
+
output: { type: "content-state" },
|
|
90
|
+
homepageCollection: import_shell4.HOMEPAGE_COLLECTION,
|
|
91
|
+
clearHomepageCollection: clearHistory,
|
|
92
|
+
onHistory: addHistory,
|
|
93
|
+
outputTargets: [
|
|
94
|
+
{
|
|
95
|
+
type: "callback",
|
|
96
|
+
label: "Select",
|
|
97
|
+
cb: (resource) => props.runCreate({ output: resource })
|
|
98
|
+
}
|
|
99
|
+
],
|
|
100
|
+
allowRemoveEntry: true
|
|
101
|
+
}
|
|
102
|
+
) }) });
|
|
103
|
+
}
|
|
104
|
+
var import_iiif_browser3, import_shell4, import_jsx_runtime36;
|
|
105
|
+
var init_manifest_browser_form_lazy = __esm({
|
|
106
|
+
"src/Manifest/ManifestBrowserCreator/manifest-browser-form.lazy.tsx"() {
|
|
107
|
+
"use strict";
|
|
108
|
+
import_iiif_browser3 = require("@manifest-editor/iiif-browser");
|
|
109
|
+
import_shell4 = require("@manifest-editor/shell");
|
|
110
|
+
import_jsx_runtime36 = require("react/jsx-runtime");
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
// src/index.ts
|
|
115
|
+
var src_exports = {};
|
|
116
|
+
__export(src_exports, {
|
|
117
|
+
allCreators: () => allCreators,
|
|
118
|
+
audioAnnotation: () => audioAnnotation,
|
|
119
|
+
emptyAnnotationPage: () => emptyAnnotationPage,
|
|
120
|
+
emptyCanvas: () => emptyCanvas,
|
|
121
|
+
htmlAnnotation: () => htmlAnnotation,
|
|
122
|
+
htmlBodyCreator: () => htmlBodyCreator,
|
|
123
|
+
iiifBrowserCreator: () => iiifBrowserCreator,
|
|
124
|
+
imageServiceAnnotation: () => imageServiceAnnotation,
|
|
125
|
+
imageServiceCreator: () => imageServiceCreator,
|
|
126
|
+
imageUrlAnnotation: () => imageUrlAnnotation,
|
|
127
|
+
imageUrlCreator: () => imageUrlCreator,
|
|
128
|
+
internalCanvas: () => internalCanvas,
|
|
129
|
+
manifestBrowserCreator: () => manifestBrowserCreator,
|
|
130
|
+
noBodyAnnotation: () => noBodyAnnotation,
|
|
131
|
+
plaintextCreator: () => plaintextCreator,
|
|
132
|
+
videoAnnotation: () => videoAnnotation,
|
|
133
|
+
webPageCreator: () => webPageCreator,
|
|
134
|
+
youTubeBodyCreator: () => youTubeBodyCreator
|
|
135
|
+
});
|
|
136
|
+
module.exports = __toCommonJS(src_exports);
|
|
137
|
+
|
|
138
|
+
// src/Canvas/EmptyCanvas/index.tsx
|
|
139
|
+
var import_components = require("@manifest-editor/components");
|
|
140
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
|
141
|
+
var emptyCanvas = {
|
|
142
|
+
id: "@manifest-editor/empty-canvas",
|
|
143
|
+
create: createEmptyCanvas,
|
|
144
|
+
label: "Empty canvas",
|
|
145
|
+
summary: "No content",
|
|
146
|
+
icon: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_components.EmptyCanvasIcon, {}),
|
|
147
|
+
resourceType: "Canvas",
|
|
148
|
+
resourceFields: ["id", "type", "label", "height", "width", "items"],
|
|
149
|
+
supports: {
|
|
150
|
+
parentTypes: ["Manifest"],
|
|
151
|
+
parentFields: ["items"]
|
|
152
|
+
}
|
|
153
|
+
};
|
|
154
|
+
async function createEmptyCanvas(data, ctx) {
|
|
155
|
+
const canvasId = ctx.generateId("canvas");
|
|
156
|
+
const page = ctx.embed({
|
|
157
|
+
id: ctx.generateId("annotation-page", { id: canvasId, type: "Canvas" }),
|
|
158
|
+
type: "AnnotationPage",
|
|
159
|
+
items: []
|
|
160
|
+
});
|
|
161
|
+
return {
|
|
162
|
+
id: canvasId,
|
|
163
|
+
type: "Canvas",
|
|
164
|
+
label: data.label || { en: [""] },
|
|
165
|
+
height: data.height || 1e3,
|
|
166
|
+
width: data.width || 1e3,
|
|
167
|
+
items: [page]
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// ../ui/icons/TextFormatIcon.tsx
|
|
172
|
+
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
173
|
+
var TextFormatIcon = (props) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", height: "1em", width: "1em", ...props, children: [
|
|
174
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M0 0h24v24H0z", fill: "none" }),
|
|
175
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("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" })
|
|
176
|
+
] });
|
|
177
|
+
|
|
178
|
+
// src/ContentResource/PlaintextCreator/create-plaintext.tsx
|
|
179
|
+
var import_editors = require("@manifest-editor/editors");
|
|
180
|
+
|
|
181
|
+
// ../ui/atoms/Button.tsx
|
|
182
|
+
var import_styled_components = __toESM(require("styled-components"), 1);
|
|
183
|
+
var ButtonReset = import_styled_components.default.button`
|
|
184
|
+
border: none;
|
|
185
|
+
outline: none;
|
|
186
|
+
background-color: transparent;
|
|
187
|
+
margin: 0;
|
|
188
|
+
padding: 0;
|
|
189
|
+
font-size: inherit;
|
|
190
|
+
color: inherit;
|
|
191
|
+
cursor: pointer;
|
|
192
|
+
&:hover {
|
|
193
|
+
color: inherit;
|
|
194
|
+
}
|
|
195
|
+
`;
|
|
196
|
+
var Button = import_styled_components.default.button`
|
|
197
|
+
padding: 0.5rem 1rem;
|
|
198
|
+
color: ${(props) => props.theme.color.main || "none"};
|
|
199
|
+
background-color: ${(props) => props.theme.color.white || "white"};
|
|
200
|
+
border-radius: inherit;
|
|
201
|
+
border: none;
|
|
202
|
+
cursor: pointer;
|
|
203
|
+
display: flex;
|
|
204
|
+
align-items: center;
|
|
205
|
+
font-size: 0.85em;
|
|
206
|
+
:disabled {
|
|
207
|
+
opacity: 0.65;
|
|
208
|
+
cursor: not-allowed;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
&:hover {
|
|
212
|
+
background: #eee;
|
|
213
|
+
}
|
|
214
|
+
`;
|
|
215
|
+
var SmallButton = (0, import_styled_components.default)(Button)`
|
|
216
|
+
padding: 0.25em ${(props) => props.theme.padding.xs || "0.4em"};
|
|
217
|
+
height: unset;
|
|
218
|
+
background: none;
|
|
219
|
+
`;
|
|
220
|
+
var SecondaryButton = (0, import_styled_components.default)(Button)`
|
|
221
|
+
{
|
|
222
|
+
padding: 0 ${(props) => props.theme.padding.medium || "1rem"};
|
|
223
|
+
color: ${(props) => props.theme.color.main || "#B84C74;"};
|
|
224
|
+
background-color: ${(props) => props.theme.color.white || "white"};
|
|
225
|
+
border: 1px solid ${(props) => props.theme.color.main || "#B84C74;"};
|
|
226
|
+
border-radius: 0.25rem;
|
|
227
|
+
cursor: pointer;
|
|
228
|
+
height: 2rem;
|
|
229
|
+
display: flex;
|
|
230
|
+
align-items: center;
|
|
231
|
+
white-space: nowrap;
|
|
232
|
+
font-size: 0.75rem;
|
|
233
|
+
|
|
234
|
+
:disabled {
|
|
235
|
+
opacity: 0.65;
|
|
236
|
+
cursor: not-allowed;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
`;
|
|
240
|
+
var CalltoButton = (0, import_styled_components.default)(Button)`
|
|
241
|
+
padding: 0 ${(props) => props.theme.padding.medium || "1rem"};
|
|
242
|
+
color: ${(props) => props.theme.color.white || "white"};
|
|
243
|
+
background-color: ${(props) => props.theme.color.main || "#B84C74;"};
|
|
244
|
+
border: 1px solid #eee;
|
|
245
|
+
border-radius: 0.25rem;
|
|
246
|
+
cursor: pointer;
|
|
247
|
+
justify-content: center;
|
|
248
|
+
display: flex;
|
|
249
|
+
align-items: center;
|
|
250
|
+
&:hover {
|
|
251
|
+
background-color: ${(props) => props.theme.color.mainHover || "#B84C74;"};
|
|
252
|
+
}
|
|
253
|
+
`;
|
|
254
|
+
var ButtonGroup = import_styled_components.default.div`
|
|
255
|
+
display: flex;
|
|
256
|
+
flex-direction: row;
|
|
257
|
+
flex-wrap: wrap;
|
|
258
|
+
align-items: flex-start;
|
|
259
|
+
justify-content: ${(props) => props.$right ? "flex-end" : "flex-start"};
|
|
260
|
+
`;
|
|
261
|
+
|
|
262
|
+
// ../ui/atoms/PaddedSidebarContainer.tsx
|
|
263
|
+
var import_styled_components2 = __toESM(require("styled-components"), 1);
|
|
264
|
+
var PaddedSidebarContainer = import_styled_components2.default.div`
|
|
265
|
+
padding: 0 0.7em;
|
|
266
|
+
margin: 0.7em 0;
|
|
267
|
+
flex: 1;
|
|
268
|
+
overflow: visible;
|
|
269
|
+
`;
|
|
270
|
+
|
|
271
|
+
// src/ContentResource/PlaintextCreator/create-plaintext.tsx
|
|
272
|
+
var import_react = require("react");
|
|
273
|
+
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
274
|
+
async function createPlaintext(data, ctx) {
|
|
275
|
+
return ctx.embed({
|
|
276
|
+
id: data.url,
|
|
277
|
+
type: "Text",
|
|
278
|
+
label: data.label,
|
|
279
|
+
format: "text/plain"
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
function CreatePlaintextForm(props) {
|
|
283
|
+
const [label, setLabel] = (0, import_react.useState)({ en: ["View as text"] });
|
|
284
|
+
const onSubmit = (e) => {
|
|
285
|
+
e.preventDefault();
|
|
286
|
+
const data = new FormData(e.target);
|
|
287
|
+
const formData = Object.fromEntries(data.entries());
|
|
288
|
+
if (formData.url) {
|
|
289
|
+
props.runCreate({ url: formData.url, label });
|
|
290
|
+
}
|
|
291
|
+
};
|
|
292
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(PaddedSidebarContainer, { children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("form", { onSubmit, children: [
|
|
293
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
294
|
+
import_editors.LanguageFieldEditor,
|
|
295
|
+
{
|
|
296
|
+
focusId: "label",
|
|
297
|
+
label: "Label",
|
|
298
|
+
fields: label,
|
|
299
|
+
onSave: (e) => setLabel(e.toInternationalString())
|
|
300
|
+
}
|
|
301
|
+
),
|
|
302
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_editors.InputContainer, { $wide: true, children: [
|
|
303
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_editors.InputLabel, { htmlFor: "id", children: "Link to plaintext" }),
|
|
304
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_editors.Input, { id: "url", name: "url", defaultValue: "" })
|
|
305
|
+
] }),
|
|
306
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Button, { type: "submit", children: "Create" })
|
|
307
|
+
] }) });
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
// src/ContentResource/PlaintextCreator/index.tsx
|
|
311
|
+
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
312
|
+
var plaintextCreator = {
|
|
313
|
+
id: "@manifest-editor/plaintext-creator",
|
|
314
|
+
create: createPlaintext,
|
|
315
|
+
label: "Plaintext",
|
|
316
|
+
summary: "Add link to an plaintext",
|
|
317
|
+
icon: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(TextFormatIcon, {}),
|
|
318
|
+
render(ctx) {
|
|
319
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(CreatePlaintextForm, { ...ctx });
|
|
320
|
+
},
|
|
321
|
+
resourceType: "ContentResource",
|
|
322
|
+
resourceFields: ["label", "format"],
|
|
323
|
+
supports: {
|
|
324
|
+
parentFields: ["seeAlso", "rendering", "homepage"]
|
|
325
|
+
},
|
|
326
|
+
staticFields: {
|
|
327
|
+
format: "text/plain"
|
|
328
|
+
}
|
|
329
|
+
};
|
|
330
|
+
|
|
331
|
+
// src/ContentResource/WebPageCreator/create-web-page.tsx
|
|
332
|
+
var import_editors2 = require("@manifest-editor/editors");
|
|
333
|
+
var import_react2 = require("react");
|
|
334
|
+
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
335
|
+
async function createWebPage(data, ctx) {
|
|
336
|
+
return ctx.embed({
|
|
337
|
+
id: data.url,
|
|
338
|
+
type: "Text",
|
|
339
|
+
label: data.label,
|
|
340
|
+
format: "text/html"
|
|
341
|
+
});
|
|
342
|
+
}
|
|
343
|
+
function CreateWebPageForm(props) {
|
|
344
|
+
const [label, setLabel] = (0, import_react2.useState)({ en: [""] });
|
|
345
|
+
const onSubmit = (e) => {
|
|
346
|
+
e.preventDefault();
|
|
347
|
+
const data = new FormData(e.target);
|
|
348
|
+
const formData = Object.fromEntries(data.entries());
|
|
349
|
+
if (formData.url) {
|
|
350
|
+
props.runCreate({ url: formData.url, label });
|
|
351
|
+
}
|
|
352
|
+
};
|
|
353
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(PaddedSidebarContainer, { children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("form", { onSubmit, children: [
|
|
354
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
355
|
+
import_editors2.LanguageFieldEditor,
|
|
356
|
+
{
|
|
357
|
+
focusId: "label",
|
|
358
|
+
label: "Label",
|
|
359
|
+
fields: label,
|
|
360
|
+
onSave: (e) => setLabel(e.toInternationalString())
|
|
361
|
+
}
|
|
362
|
+
),
|
|
363
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_editors2.InputContainer, { $wide: true, children: [
|
|
364
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_editors2.InputLabel, { htmlFor: "id", children: "Link" }),
|
|
365
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_editors2.Input, { id: "url", name: "url", defaultValue: "" })
|
|
366
|
+
] }),
|
|
367
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Button, { type: "submit", children: "Create link" })
|
|
368
|
+
] }) });
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
// ../ui/icons/LinkIcon.tsx
|
|
372
|
+
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
373
|
+
function LinkIcon() {
|
|
374
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("svg", { xmlns: "http://www.w3.org/2000/svg", height: "24px", viewBox: "0 0 24 24", width: "24px", fill: "#000000", children: [
|
|
375
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M0 0h24v24H0z", fill: "none" }),
|
|
376
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("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" })
|
|
377
|
+
] });
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
// src/ContentResource/WebPageCreator/index.tsx
|
|
381
|
+
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
382
|
+
var webPageCreator = {
|
|
383
|
+
id: "@manifest-editor/web-page-creator",
|
|
384
|
+
create: createWebPage,
|
|
385
|
+
label: "Web page",
|
|
386
|
+
summary: "Add link to an external web page",
|
|
387
|
+
icon: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(LinkIcon, {}),
|
|
388
|
+
render(ctx) {
|
|
389
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(CreateWebPageForm, { ...ctx });
|
|
390
|
+
},
|
|
391
|
+
resourceType: "ContentResource",
|
|
392
|
+
resourceFields: ["label", "format"],
|
|
393
|
+
supports: {
|
|
394
|
+
parentFields: ["seeAlso", "rendering", "homepage"]
|
|
395
|
+
}
|
|
396
|
+
};
|
|
397
|
+
|
|
398
|
+
// src/ContentResource/HTMLBodyCreator/create-html-body.tsx
|
|
399
|
+
var import_editors3 = require("@manifest-editor/editors");
|
|
400
|
+
var import_shell = require("@manifest-editor/shell");
|
|
401
|
+
var import_react3 = require("react");
|
|
402
|
+
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
403
|
+
async function createHtmlBody(data, ctx) {
|
|
404
|
+
return ctx.embed({
|
|
405
|
+
id: ctx.generateId(`html/${data.language}`),
|
|
406
|
+
language: data.language,
|
|
407
|
+
type: "TextualBody",
|
|
408
|
+
format: "text/html",
|
|
409
|
+
value: data.body || ""
|
|
410
|
+
});
|
|
411
|
+
}
|
|
412
|
+
function CreateHTMLBodyForm(props) {
|
|
413
|
+
const { i18n } = (0, import_shell.useConfig)();
|
|
414
|
+
const [body, setBodyValue] = (0, import_react3.useState)("<p></p>");
|
|
415
|
+
const [language, setLang] = (0, import_react3.useState)(i18n.defaultLanguage);
|
|
416
|
+
const onSubmit = () => {
|
|
417
|
+
props.runCreate({
|
|
418
|
+
language,
|
|
419
|
+
body
|
|
420
|
+
});
|
|
421
|
+
};
|
|
422
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(PaddedSidebarContainer, { children: [
|
|
423
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_editors3.InputContainer, { children: [
|
|
424
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_editors3.InputLabel, { children: "HTML Body" }),
|
|
425
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
426
|
+
import_editors3.RichTextLanguageField,
|
|
427
|
+
{
|
|
428
|
+
value: body,
|
|
429
|
+
language,
|
|
430
|
+
onUpdateLanguage: (lng) => setLang(lng),
|
|
431
|
+
languages: i18n.availableLanguages,
|
|
432
|
+
onUpdate: (e) => setBodyValue(e)
|
|
433
|
+
}
|
|
434
|
+
)
|
|
435
|
+
] }),
|
|
436
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Button, { onClick: () => onSubmit(), children: "Create" })
|
|
437
|
+
] });
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
// src/ContentResource/HTMLBodyCreator/index.tsx
|
|
441
|
+
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
442
|
+
var htmlBodyCreator = {
|
|
443
|
+
id: "@manifest-editor/html-body-creator",
|
|
444
|
+
create: createHtmlBody,
|
|
445
|
+
label: "HTML Body",
|
|
446
|
+
summary: "Add HTML annotation body",
|
|
447
|
+
icon: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(TextFormatIcon, {}),
|
|
448
|
+
render(ctx) {
|
|
449
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(CreateHTMLBodyForm, { ...ctx });
|
|
450
|
+
},
|
|
451
|
+
resourceType: "ContentResource",
|
|
452
|
+
resourceFields: ["id", "language", "type", "format", "value"],
|
|
453
|
+
supports: {
|
|
454
|
+
parentTypes: ["Annotation"],
|
|
455
|
+
parentFields: ["body"]
|
|
456
|
+
},
|
|
457
|
+
staticFields: {
|
|
458
|
+
type: "TextualBody",
|
|
459
|
+
format: "text/html"
|
|
460
|
+
}
|
|
461
|
+
};
|
|
462
|
+
|
|
463
|
+
// src/Annotation/HTMLAnnotation/create-html-annotation.tsx
|
|
464
|
+
var import_react4 = require("react");
|
|
465
|
+
var import_editors4 = require("@manifest-editor/editors");
|
|
466
|
+
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
467
|
+
async function createHtmlAnnotation(data, ctx) {
|
|
468
|
+
const annotation = {
|
|
469
|
+
id: ctx.generateId("annotation"),
|
|
470
|
+
type: "Annotation"
|
|
471
|
+
};
|
|
472
|
+
const targetType = ctx.options.targetType;
|
|
473
|
+
const languages = Object.keys(data.body);
|
|
474
|
+
const bodies = [];
|
|
475
|
+
for (const language of languages) {
|
|
476
|
+
const body = data.body[language].join("\n");
|
|
477
|
+
if (body) {
|
|
478
|
+
bodies.push(
|
|
479
|
+
await ctx.create(
|
|
480
|
+
"@manifest-editor/html-body-creator",
|
|
481
|
+
{
|
|
482
|
+
language,
|
|
483
|
+
body
|
|
484
|
+
},
|
|
485
|
+
{ parent: { resource: annotation, property: "items" } }
|
|
486
|
+
)
|
|
487
|
+
);
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
if (targetType === "Annotation") {
|
|
491
|
+
return ctx.embed({
|
|
492
|
+
...annotation,
|
|
493
|
+
motivation: data.motivation || ctx.options.initialData?.motivation || "painting",
|
|
494
|
+
body: bodies,
|
|
495
|
+
target: ctx.getTarget()
|
|
496
|
+
});
|
|
497
|
+
}
|
|
498
|
+
if (targetType === "Canvas") {
|
|
499
|
+
const canvasId = ctx.generateId("canvas");
|
|
500
|
+
const pageId = ctx.generateId("annotation-page", { id: canvasId, type: "Canvas" });
|
|
501
|
+
const annotationResource = ctx.embed({
|
|
502
|
+
...annotation,
|
|
503
|
+
motivation: "painting",
|
|
504
|
+
body: bodies,
|
|
505
|
+
target: { type: "SpecificResource", source: { id: canvasId, type: "Canvas" } }
|
|
506
|
+
});
|
|
507
|
+
const page = ctx.embed({
|
|
508
|
+
id: pageId,
|
|
509
|
+
type: "AnnotationPage",
|
|
510
|
+
items: [annotationResource]
|
|
511
|
+
});
|
|
512
|
+
return ctx.embed({
|
|
513
|
+
id: canvasId,
|
|
514
|
+
type: "Canvas",
|
|
515
|
+
label: data.label || { en: ["Untitled HTML canvas"] },
|
|
516
|
+
height: data.height || 1e3,
|
|
517
|
+
width: data.width || 1e3,
|
|
518
|
+
items: [page]
|
|
519
|
+
});
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
function CreateHTMLAnnotation(props) {
|
|
523
|
+
const [body, setBody] = (0, import_react4.useState)({ en: [""] });
|
|
524
|
+
const onSubmit = () => {
|
|
525
|
+
props.runCreate({
|
|
526
|
+
body
|
|
527
|
+
});
|
|
528
|
+
};
|
|
529
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(PaddedSidebarContainer, { children: [
|
|
530
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_editors4.InputContainer, { children: [
|
|
531
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_editors4.InputLabel, { children: "HTML Body" }),
|
|
532
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
533
|
+
import_editors4.LanguageFieldEditor,
|
|
534
|
+
{
|
|
535
|
+
focusId: "html-content",
|
|
536
|
+
label: "HTML Content",
|
|
537
|
+
fields: body,
|
|
538
|
+
onSave: (e) => setBody(e.toInternationalString())
|
|
539
|
+
}
|
|
540
|
+
)
|
|
541
|
+
] }),
|
|
542
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Button, { onClick: () => onSubmit(), children: "Create" })
|
|
543
|
+
] });
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
// src/Annotation/HTMLAnnotation/index.tsx
|
|
547
|
+
var import_components2 = require("@manifest-editor/components");
|
|
548
|
+
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
549
|
+
var htmlAnnotation = {
|
|
550
|
+
id: "@manifest-editor/html-annotation",
|
|
551
|
+
create: createHtmlAnnotation,
|
|
552
|
+
label: "HTML",
|
|
553
|
+
summary: "HTML annotation",
|
|
554
|
+
icon: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_components2.HTMLIcon, {}),
|
|
555
|
+
render(ctx) {
|
|
556
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(CreateHTMLAnnotation, { ...ctx });
|
|
557
|
+
},
|
|
558
|
+
resourceType: "Annotation",
|
|
559
|
+
resourceFields: ["id", "type", "motivation", "body", "target"],
|
|
560
|
+
additionalTypes: ["Canvas"],
|
|
561
|
+
supports: {
|
|
562
|
+
initialData: true,
|
|
563
|
+
parentTypes: ["AnnotationPage", "Manifest"],
|
|
564
|
+
parentFields: ["items"]
|
|
565
|
+
},
|
|
566
|
+
staticFields: {
|
|
567
|
+
type: "Annotation"
|
|
568
|
+
}
|
|
569
|
+
};
|
|
570
|
+
|
|
571
|
+
// ../ui/icons/ThumbnailStripIcon.tsx
|
|
572
|
+
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
573
|
+
var ThumbnailStripIcon = () => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
574
|
+
"svg",
|
|
575
|
+
{
|
|
576
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
577
|
+
height: "24px",
|
|
578
|
+
viewBox: "0 0 24 24",
|
|
579
|
+
width: "24px",
|
|
580
|
+
fill: "#000000",
|
|
581
|
+
transform: "scale(-1, 1)",
|
|
582
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("g", { children: [
|
|
583
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("rect", { fill: "none", height: "24", width: "24" }),
|
|
584
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("path", { d: "M16,20H2V4h14V20z M18,8h4V4h-4V8z M18,20h4v-4h-4V20z M18,14h4v-4h-4V14z" })
|
|
585
|
+
] })
|
|
586
|
+
}
|
|
587
|
+
);
|
|
588
|
+
|
|
589
|
+
// src/AnnotationPage/EmptyAnnotationPage/index.tsx
|
|
590
|
+
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
591
|
+
var emptyAnnotationPage = {
|
|
592
|
+
id: "@manifest-editor/empty-annotation-page",
|
|
593
|
+
create: createEmptyAnnotationPage,
|
|
594
|
+
label: "Empty annotation page",
|
|
595
|
+
summary: "AnnotationPage with nothing",
|
|
596
|
+
icon: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(ThumbnailStripIcon, {}),
|
|
597
|
+
resourceType: "AnnotationPage",
|
|
598
|
+
resourceFields: ["id", "type", "items"],
|
|
599
|
+
supports: {
|
|
600
|
+
parentTypes: ["Manifest", "Canvas", "Range"],
|
|
601
|
+
parentFieldMap: {
|
|
602
|
+
Manifest: ["annotations"],
|
|
603
|
+
Canvas: ["items", "annotations"],
|
|
604
|
+
Range: ["annotations"]
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
};
|
|
608
|
+
async function createEmptyAnnotationPage(data, ctx) {
|
|
609
|
+
return ctx.embed({
|
|
610
|
+
id: ctx.generateId("annotations"),
|
|
611
|
+
type: "AnnotationPage",
|
|
612
|
+
items: []
|
|
613
|
+
});
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
// src/ContentResource/YouTubeCreator/index.tsx
|
|
617
|
+
var import_components3 = require("@manifest-editor/components");
|
|
618
|
+
|
|
619
|
+
// src/ContentResource/YouTubeCreator/create-youtube-body.tsx
|
|
620
|
+
var import_editors5 = require("@manifest-editor/editors");
|
|
621
|
+
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
622
|
+
var ytRegex = /^.*(?:(?:youtu\.be\/|v\/|vi\/|u\/\w\/|embed\/|shorts\/)|(?:(?:watch)?\?vi?=|&vi?=))([^#&?]*).*/;
|
|
623
|
+
function getYouTubeId(url) {
|
|
624
|
+
const id = (url || "").match(ytRegex);
|
|
625
|
+
return id ? id[1] : null;
|
|
626
|
+
}
|
|
627
|
+
async function createYoutubeBody(data, ctx) {
|
|
628
|
+
const id = getYouTubeId(data.youtubeUrl);
|
|
629
|
+
const body = ctx.embed({
|
|
630
|
+
id: `https://www.youtube.com/watch?v=${id}`,
|
|
631
|
+
type: "Video",
|
|
632
|
+
service: [
|
|
633
|
+
{
|
|
634
|
+
profile: "http://digirati.com/objectifier",
|
|
635
|
+
params: {
|
|
636
|
+
data: `https://www.youtube.com/embed/${id}`
|
|
637
|
+
}
|
|
638
|
+
},
|
|
639
|
+
{
|
|
640
|
+
id: `https://www.youtube.com/watch?v=${id}`,
|
|
641
|
+
profile: "https://www.youtube.com"
|
|
642
|
+
}
|
|
643
|
+
]
|
|
644
|
+
});
|
|
645
|
+
if (ctx.options.targetType === "Canvas") {
|
|
646
|
+
const canvasId = ctx.generateId("canvas");
|
|
647
|
+
const pageId = ctx.generateId("annotation-page", { id: canvasId, type: "Canvas" });
|
|
648
|
+
const annotation = await ctx.embed({
|
|
649
|
+
id: ctx.generateId("annotation", { id: pageId, type: "AnnotationPage" }),
|
|
650
|
+
type: "Annotation",
|
|
651
|
+
motivation: "painting",
|
|
652
|
+
body: [body],
|
|
653
|
+
target: { type: "SpecificResource", source: { id: canvasId, type: "Canvas" } }
|
|
654
|
+
});
|
|
655
|
+
const page = ctx.embed({
|
|
656
|
+
id: pageId,
|
|
657
|
+
type: "AnnotationPage",
|
|
658
|
+
items: [annotation]
|
|
659
|
+
});
|
|
660
|
+
return ctx.embed({
|
|
661
|
+
id: canvasId,
|
|
662
|
+
type: "Canvas",
|
|
663
|
+
label: data.label || { en: ["Untitled YouTube canvas"] },
|
|
664
|
+
height: data.height || 1e3,
|
|
665
|
+
width: data.width || 1e3,
|
|
666
|
+
duration: data.duration || 1,
|
|
667
|
+
items: [page]
|
|
668
|
+
});
|
|
669
|
+
}
|
|
670
|
+
if (ctx.options.targetType === "Annotation" || ctx.options.targetType === "Canvas") {
|
|
671
|
+
return ctx.embed({
|
|
672
|
+
id: ctx.generateId("annotation"),
|
|
673
|
+
type: "Annotation",
|
|
674
|
+
motivation: "painting",
|
|
675
|
+
body: [body],
|
|
676
|
+
target: ctx.getTarget()
|
|
677
|
+
});
|
|
678
|
+
}
|
|
679
|
+
return body;
|
|
680
|
+
}
|
|
681
|
+
function YouTubeForm(props) {
|
|
682
|
+
const onSubmit = (e) => {
|
|
683
|
+
e.preventDefault();
|
|
684
|
+
const data = new FormData(e.target);
|
|
685
|
+
const formData = Object.fromEntries(data.entries());
|
|
686
|
+
if (formData.youtubeUrl) {
|
|
687
|
+
props.runCreate({ youtubeUrl: formData.youtubeUrl });
|
|
688
|
+
}
|
|
689
|
+
};
|
|
690
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(PaddedSidebarContainer, { children: /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("form", { onSubmit, children: [
|
|
691
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_editors5.InputContainer, { $wide: true, children: [
|
|
692
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_editors5.InputLabel, { htmlFor: "id", children: "Link to YouTube" }),
|
|
693
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_editors5.Input, { id: "youtubeUrl", name: "youtubeUrl", defaultValue: "" })
|
|
694
|
+
] }),
|
|
695
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(Button, { type: "submit", children: "Create" })
|
|
696
|
+
] }) });
|
|
697
|
+
}
|
|
698
|
+
|
|
699
|
+
// src/ContentResource/YouTubeCreator/index.tsx
|
|
700
|
+
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
701
|
+
var youTubeBodyCreator = {
|
|
702
|
+
id: "@manifest-editor/youtube",
|
|
703
|
+
create: createYoutubeBody,
|
|
704
|
+
label: "YouTube",
|
|
705
|
+
summary: "Embed YouTube",
|
|
706
|
+
icon: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_components3.YouTubeIcon, {}),
|
|
707
|
+
resourceType: "ContentResource",
|
|
708
|
+
additionalTypes: ["Canvas", "Annotation"],
|
|
709
|
+
resourceFields: ["id", "type", "service"],
|
|
710
|
+
render: (ctx) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(YouTubeForm, { ...ctx }),
|
|
711
|
+
supports: {
|
|
712
|
+
parentTypes: ["Annotation", "Manifest", "AnnotationPage"],
|
|
713
|
+
parentFieldMap: {
|
|
714
|
+
Annotation: ["body"],
|
|
715
|
+
Manifest: ["items"],
|
|
716
|
+
AnnotationPage: ["items"]
|
|
717
|
+
}
|
|
718
|
+
},
|
|
719
|
+
staticFields: {
|
|
720
|
+
type: "Video"
|
|
721
|
+
}
|
|
722
|
+
};
|
|
723
|
+
|
|
724
|
+
// src/ContentResource/ImageUrlCreator/create-image-url.tsx
|
|
725
|
+
var import_editors6 = require("@manifest-editor/editors");
|
|
726
|
+
var import_shell2 = require("@manifest-editor/shell");
|
|
727
|
+
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
728
|
+
async function createImageUrl(data, ctx) {
|
|
729
|
+
if (!data.height || !data.width) {
|
|
730
|
+
const dimensions = await (0, import_shell2.getImageDimensions)(data.url);
|
|
731
|
+
if (dimensions) {
|
|
732
|
+
data.height = dimensions.height;
|
|
733
|
+
data.width = dimensions.width;
|
|
734
|
+
}
|
|
735
|
+
}
|
|
736
|
+
return ctx.embed({
|
|
737
|
+
id: data.url,
|
|
738
|
+
type: "Image",
|
|
739
|
+
format: data.format || await (0, import_shell2.getFormat)(data.url),
|
|
740
|
+
height: data.height,
|
|
741
|
+
width: data.width,
|
|
742
|
+
service: data.service ? Array.isArray(data.service) ? data.service : [data.service] : void 0
|
|
743
|
+
});
|
|
744
|
+
}
|
|
745
|
+
function CreateImageUrlForm(props) {
|
|
746
|
+
const onSubmit = (e) => {
|
|
747
|
+
e.preventDefault();
|
|
748
|
+
const data = new FormData(e.target);
|
|
749
|
+
const formData = Object.fromEntries(data.entries());
|
|
750
|
+
if (formData.url) {
|
|
751
|
+
props.runCreate({ url: formData.url });
|
|
752
|
+
}
|
|
753
|
+
};
|
|
754
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(PaddedSidebarContainer, { children: /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("form", { onSubmit, children: [
|
|
755
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_editors6.InputContainer, { $wide: true, children: [
|
|
756
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_editors6.InputLabel, { htmlFor: "id", children: "Link to Image" }),
|
|
757
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_editors6.Input, { id: "url", name: "url", defaultValue: "" })
|
|
758
|
+
] }),
|
|
759
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Button, { type: "submit", children: "Create" })
|
|
760
|
+
] }) });
|
|
761
|
+
}
|
|
762
|
+
|
|
763
|
+
// src/ContentResource/ImageUrlCreator/index.tsx
|
|
764
|
+
var import_components4 = require("@manifest-editor/components");
|
|
765
|
+
var import_jsx_runtime17 = require("react/jsx-runtime");
|
|
766
|
+
var imageUrlCreator = {
|
|
767
|
+
id: "@manifest-editor/image-url-creator",
|
|
768
|
+
create: createImageUrl,
|
|
769
|
+
label: "Image",
|
|
770
|
+
summary: "Image from a URL",
|
|
771
|
+
icon: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_components4.AddImageIcon, {}),
|
|
772
|
+
render(ctx) {
|
|
773
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(CreateImageUrlForm, { ...ctx });
|
|
774
|
+
},
|
|
775
|
+
resourceType: "ContentResource",
|
|
776
|
+
resourceFields: ["format"],
|
|
777
|
+
supports: {
|
|
778
|
+
parentFields: ["logo", "body", "thumbnail"]
|
|
779
|
+
},
|
|
780
|
+
staticFields: {
|
|
781
|
+
type: "Image"
|
|
782
|
+
}
|
|
783
|
+
};
|
|
784
|
+
|
|
785
|
+
// src/ContentResource/ImageServiceCreator/create-image-service.tsx
|
|
786
|
+
var import_image_3 = require("@iiif/parser/image-3");
|
|
787
|
+
var import_editors7 = require("@manifest-editor/editors");
|
|
788
|
+
var import_jsx_runtime18 = require("react/jsx-runtime");
|
|
789
|
+
async function createImageServer(data, ctx) {
|
|
790
|
+
const request = (0, import_image_3.createImageServiceRequest)(data.service);
|
|
791
|
+
const imageId = (0, import_image_3.imageServiceRequestToString)({
|
|
792
|
+
identifier: request.identifier,
|
|
793
|
+
server: request.server,
|
|
794
|
+
scheme: request.scheme,
|
|
795
|
+
type: "image",
|
|
796
|
+
size: {
|
|
797
|
+
max: !data.size?.width && !data.size?.height,
|
|
798
|
+
confined: false,
|
|
799
|
+
upscaled: false,
|
|
800
|
+
...data.size || {}
|
|
801
|
+
},
|
|
802
|
+
format: "jpg",
|
|
803
|
+
// This isn't how it should be modelled, always full,
|
|
804
|
+
// region: data.selector ? data.selector : { full: true },
|
|
805
|
+
region: { full: true },
|
|
806
|
+
rotation: { angle: 0 },
|
|
807
|
+
quality: "default",
|
|
808
|
+
prefix: request.prefix,
|
|
809
|
+
originalPath: request.originalPath
|
|
810
|
+
});
|
|
811
|
+
const resource = ctx.embed({
|
|
812
|
+
id: imageId,
|
|
813
|
+
type: "Image",
|
|
814
|
+
format: data.format || "image/jpeg",
|
|
815
|
+
height: data.height || data.service.height,
|
|
816
|
+
width: data.width || data.service.width,
|
|
817
|
+
service: data.embedService === false ? void 0 : [data.service]
|
|
818
|
+
});
|
|
819
|
+
return resource;
|
|
820
|
+
}
|
|
821
|
+
function CreateImageServerForm(props) {
|
|
822
|
+
const onSubmit = (e) => {
|
|
823
|
+
e.preventDefault();
|
|
824
|
+
const data = new FormData(e.target);
|
|
825
|
+
const formData = Object.fromEntries(data.entries());
|
|
826
|
+
const url = formData.url;
|
|
827
|
+
if (url) {
|
|
828
|
+
const canon = (0, import_image_3.canonicalServiceUrl)(url);
|
|
829
|
+
fetch(canon).then((r) => r.json()).then((service) => {
|
|
830
|
+
if (service["@id"]) {
|
|
831
|
+
service.id = service["@id"];
|
|
832
|
+
}
|
|
833
|
+
if (service["@type"]) {
|
|
834
|
+
service.type = service["@type"];
|
|
835
|
+
}
|
|
836
|
+
props.runCreate({ url: formData.url, service });
|
|
837
|
+
});
|
|
838
|
+
}
|
|
839
|
+
};
|
|
840
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(PaddedSidebarContainer, { children: /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("form", { onSubmit, children: [
|
|
841
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_editors7.InputContainer, { $wide: true, children: [
|
|
842
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_editors7.InputLabel, { htmlFor: "id", children: "Link to image service" }),
|
|
843
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_editors7.Input, { id: "url", name: "url", defaultValue: "" })
|
|
844
|
+
] }),
|
|
845
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Button, { type: "submit", children: "Create" })
|
|
846
|
+
] }) });
|
|
847
|
+
}
|
|
848
|
+
|
|
849
|
+
// src/ContentResource/ImageServiceCreator/index.tsx
|
|
850
|
+
var import_jsx_runtime19 = require("react/jsx-runtime");
|
|
851
|
+
var imageServiceCreator = {
|
|
852
|
+
id: "@manifest-editor/image-service-creator",
|
|
853
|
+
create: createImageServer,
|
|
854
|
+
label: "Image Service",
|
|
855
|
+
summary: "Add an image from Image Service",
|
|
856
|
+
icon: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(TextFormatIcon, {}),
|
|
857
|
+
render(ctx) {
|
|
858
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(CreateImageServerForm, { ...ctx });
|
|
859
|
+
},
|
|
860
|
+
resourceType: "ContentResource",
|
|
861
|
+
resourceFields: ["id", "type", "height", "width", "format", "service"],
|
|
862
|
+
supports: {
|
|
863
|
+
parentFields: ["logo", "body", "thumbnail"]
|
|
864
|
+
},
|
|
865
|
+
staticFields: {
|
|
866
|
+
type: "Image"
|
|
867
|
+
}
|
|
868
|
+
};
|
|
869
|
+
|
|
870
|
+
// src/side-effects/reposition-multiple-images.ts
|
|
871
|
+
var import_image_32 = require("@iiif/parser/image-3");
|
|
872
|
+
var import_editor_api = require("@manifest-editor/editor-api");
|
|
873
|
+
var import_editors8 = require("@manifest-editor/editors");
|
|
874
|
+
var repositionMultipleImages = {
|
|
875
|
+
canvasInteraction: true,
|
|
876
|
+
spatial: true,
|
|
877
|
+
async run(result, { vault, options }) {
|
|
878
|
+
if (result && result.type === "Annotation" && options.targetType === "Annotation") {
|
|
879
|
+
const fullAnno = vault.get(result);
|
|
880
|
+
const target = fullAnno.target;
|
|
881
|
+
if (!(target && target.source?.type === "Canvas")) {
|
|
882
|
+
return;
|
|
883
|
+
}
|
|
884
|
+
const canvasRef = target.source;
|
|
885
|
+
const canvas = vault.get(canvasRef);
|
|
886
|
+
if (!canvas.items) {
|
|
887
|
+
return;
|
|
888
|
+
}
|
|
889
|
+
const annoPage = vault.get(canvas.items[0]);
|
|
890
|
+
if (!annoPage) {
|
|
891
|
+
return;
|
|
892
|
+
}
|
|
893
|
+
if (annoPage.items.length < 2) {
|
|
894
|
+
return;
|
|
895
|
+
}
|
|
896
|
+
const bodies = vault.get(fullAnno.body);
|
|
897
|
+
const body = bodies[0];
|
|
898
|
+
const selector = fullAnno.body[0]?.selector;
|
|
899
|
+
const serviceList = body.service || [];
|
|
900
|
+
const imageService = serviceList.find((s) => (0, import_image_32.isImageService)(s));
|
|
901
|
+
if (imageService) {
|
|
902
|
+
if (imageService.width && imageService.height) {
|
|
903
|
+
if (imageService.width !== body.width) {
|
|
904
|
+
vault.modifyEntityField({ id: body.id, type: "ContentResource" }, "width", imageService.width);
|
|
905
|
+
}
|
|
906
|
+
if (imageService.height !== body.height) {
|
|
907
|
+
vault.modifyEntityField({ id: body.id, type: "ContentResource" }, "height", imageService.height);
|
|
908
|
+
}
|
|
909
|
+
}
|
|
910
|
+
}
|
|
911
|
+
let width = imageService?.width || body.width;
|
|
912
|
+
let height = imageService?.height || body.height;
|
|
913
|
+
if (selector) {
|
|
914
|
+
if ((selector.type === "iiif:ImageApiSelector" || selector.type === "ImageApiSelector") && selector.region) {
|
|
915
|
+
const [x, y, width_, height_] = selector.region.split(",");
|
|
916
|
+
width = Number(width_) || width;
|
|
917
|
+
height = Number(height_) || height;
|
|
918
|
+
}
|
|
919
|
+
}
|
|
920
|
+
const editor = new import_editor_api.EditorInstance({ vault, reference: result });
|
|
921
|
+
const imagePosition = (0, import_editors8.centerRectangles)(
|
|
922
|
+
canvas,
|
|
923
|
+
{
|
|
924
|
+
width,
|
|
925
|
+
height
|
|
926
|
+
},
|
|
927
|
+
0.6
|
|
928
|
+
);
|
|
929
|
+
editor.annotation.target.setPosition(imagePosition);
|
|
930
|
+
}
|
|
931
|
+
}
|
|
932
|
+
};
|
|
933
|
+
|
|
934
|
+
// src/side-effects/resize-resource-to-empty-canvas.ts
|
|
935
|
+
var import_editor_api2 = require("@manifest-editor/editor-api");
|
|
936
|
+
var resizeResourceToEmptyCanvas = {
|
|
937
|
+
canvasInteraction: true,
|
|
938
|
+
spatial: true,
|
|
939
|
+
async run(result, { vault, options }) {
|
|
940
|
+
if (result && result.type === "Annotation" && options.targetType === "Annotation") {
|
|
941
|
+
const fullAnno = vault.get(result);
|
|
942
|
+
const target = fullAnno.target;
|
|
943
|
+
if (!(target && target.source?.type === "Canvas")) {
|
|
944
|
+
return;
|
|
945
|
+
}
|
|
946
|
+
const canvasRef = target.source;
|
|
947
|
+
const canvas = vault.get(canvasRef);
|
|
948
|
+
if (!canvas.items) {
|
|
949
|
+
return;
|
|
950
|
+
}
|
|
951
|
+
const annoPage = vault.get(canvas.items[0]);
|
|
952
|
+
if (!annoPage) {
|
|
953
|
+
return;
|
|
954
|
+
}
|
|
955
|
+
if (annoPage.items.length > 1) {
|
|
956
|
+
return;
|
|
957
|
+
}
|
|
958
|
+
const bodies = vault.get(fullAnno.body);
|
|
959
|
+
if (bodies.length !== 1) {
|
|
960
|
+
return;
|
|
961
|
+
}
|
|
962
|
+
const body = bodies[0];
|
|
963
|
+
const selector = fullAnno.body[0]?.selector;
|
|
964
|
+
const service = (body.service || [])[0];
|
|
965
|
+
let width = service?.width || body.width;
|
|
966
|
+
let height = service?.height || body.height;
|
|
967
|
+
const duration = body.duration || service?.duration;
|
|
968
|
+
if (selector) {
|
|
969
|
+
if ((selector.type === "iiif:ImageApiSelector" || selector.type === "ImageApiSelector") && selector.region) {
|
|
970
|
+
const [x, y, width_, height_] = selector.region.split(",");
|
|
971
|
+
width = Number(width_) || width;
|
|
972
|
+
height = Number(height_) || height;
|
|
973
|
+
}
|
|
974
|
+
}
|
|
975
|
+
const editor = new import_editor_api2.EditorInstance({ vault, reference: canvasRef });
|
|
976
|
+
vault.batch(() => {
|
|
977
|
+
if (typeof width !== "undefined") {
|
|
978
|
+
editor.technical.width.set(width);
|
|
979
|
+
}
|
|
980
|
+
if (typeof height !== "undefined") {
|
|
981
|
+
editor.technical.height.set(height);
|
|
982
|
+
}
|
|
983
|
+
if (typeof duration !== "undefined") {
|
|
984
|
+
editor.technical.duration.set(duration);
|
|
985
|
+
}
|
|
986
|
+
});
|
|
987
|
+
}
|
|
988
|
+
}
|
|
989
|
+
};
|
|
990
|
+
|
|
991
|
+
// src/side-effects/resize-to-fit-service.ts
|
|
992
|
+
var import_iiif_image_api = require("@atlas-viewer/iiif-image-api");
|
|
993
|
+
var resizeToFitService = {
|
|
994
|
+
canvasInteraction: true,
|
|
995
|
+
spatial: true,
|
|
996
|
+
async run(result, { vault, options }) {
|
|
997
|
+
if (result && result.type === "Annotation" && options.targetType === "Annotation") {
|
|
998
|
+
const fullAnno = vault.get(result);
|
|
999
|
+
const target = fullAnno.target;
|
|
1000
|
+
if (!(target && target.source?.type === "Canvas")) {
|
|
1001
|
+
return;
|
|
1002
|
+
}
|
|
1003
|
+
const canvasRef = target.source;
|
|
1004
|
+
const canvas = vault.get(canvasRef);
|
|
1005
|
+
if (!canvas.items) {
|
|
1006
|
+
return;
|
|
1007
|
+
}
|
|
1008
|
+
const annoPage = vault.get(canvas.items[0]);
|
|
1009
|
+
if (!annoPage) {
|
|
1010
|
+
return;
|
|
1011
|
+
}
|
|
1012
|
+
const resourceBody = Array.isArray(fullAnno.body) ? fullAnno.body[0] : fullAnno.body;
|
|
1013
|
+
if (resourceBody.type === "SpecificResource" && resourceBody.selector) {
|
|
1014
|
+
return;
|
|
1015
|
+
}
|
|
1016
|
+
const bodies = vault.get(fullAnno.body);
|
|
1017
|
+
const body = bodies[0];
|
|
1018
|
+
const serviceList = body.service || [];
|
|
1019
|
+
const imageService = serviceList.find((s) => (0, import_iiif_image_api.isImageService)(s));
|
|
1020
|
+
if (imageService) {
|
|
1021
|
+
if (imageService.width && imageService.height) {
|
|
1022
|
+
if (imageService.width !== body.width) {
|
|
1023
|
+
vault.modifyEntityField({ id: body.id, type: "ContentResource" }, "width", imageService.width);
|
|
1024
|
+
}
|
|
1025
|
+
if (imageService.height !== body.height) {
|
|
1026
|
+
vault.modifyEntityField({ id: body.id, type: "ContentResource" }, "height", imageService.height);
|
|
1027
|
+
}
|
|
1028
|
+
}
|
|
1029
|
+
}
|
|
1030
|
+
}
|
|
1031
|
+
}
|
|
1032
|
+
};
|
|
1033
|
+
|
|
1034
|
+
// src/Annotation/ImageServiceAnnotation/create-service-annotation.tsx
|
|
1035
|
+
var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
1036
|
+
async function createImageServiceAnnotation(data, ctx) {
|
|
1037
|
+
const annotation = {
|
|
1038
|
+
id: ctx.generateId("annotation"),
|
|
1039
|
+
type: "Annotation"
|
|
1040
|
+
};
|
|
1041
|
+
const targetType = ctx.options.targetType;
|
|
1042
|
+
const resource = await ctx.create("@manifest-editor/image-service-creator", data, {
|
|
1043
|
+
parent: { resource: annotation, property: "body" }
|
|
1044
|
+
});
|
|
1045
|
+
if (targetType === "Annotation") {
|
|
1046
|
+
return {
|
|
1047
|
+
...annotation,
|
|
1048
|
+
body: [resource],
|
|
1049
|
+
motivation: data.motivation || "painting",
|
|
1050
|
+
target: ctx.getTarget()
|
|
1051
|
+
};
|
|
1052
|
+
}
|
|
1053
|
+
if (targetType === "Canvas") {
|
|
1054
|
+
const canvasId = ctx.generateId("canvas");
|
|
1055
|
+
const pageId = ctx.generateId("annotation-page", { id: canvasId, type: "Canvas" });
|
|
1056
|
+
const annotationResource = ctx.embed({
|
|
1057
|
+
...annotation,
|
|
1058
|
+
motivation: "painting",
|
|
1059
|
+
body: [resource],
|
|
1060
|
+
target: { type: "SpecificResource", source: { id: canvasId, type: "Canvas" } }
|
|
1061
|
+
});
|
|
1062
|
+
const page = ctx.embed({
|
|
1063
|
+
id: pageId,
|
|
1064
|
+
type: "AnnotationPage",
|
|
1065
|
+
items: [annotationResource]
|
|
1066
|
+
});
|
|
1067
|
+
return ctx.embed({
|
|
1068
|
+
id: canvasId,
|
|
1069
|
+
type: "Canvas",
|
|
1070
|
+
label: data.label || { en: ["Untitled canvas"] },
|
|
1071
|
+
height: resource.resource.height || 1e3,
|
|
1072
|
+
width: resource.resource.width || 1e3,
|
|
1073
|
+
items: [page]
|
|
1074
|
+
});
|
|
1075
|
+
}
|
|
1076
|
+
}
|
|
1077
|
+
function CreateImageServiceAnnotationForm(props) {
|
|
1078
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(CreateImageServerForm, { ...props });
|
|
1079
|
+
}
|
|
1080
|
+
|
|
1081
|
+
// src/Annotation/ImageServiceAnnotation/index.tsx
|
|
1082
|
+
var import_components5 = require("@manifest-editor/components");
|
|
1083
|
+
var import_jsx_runtime21 = require("react/jsx-runtime");
|
|
1084
|
+
var imageServiceAnnotation = {
|
|
1085
|
+
id: "@manifest-editor/image-service-annotation",
|
|
1086
|
+
create: createImageServiceAnnotation,
|
|
1087
|
+
label: "IIIF Image",
|
|
1088
|
+
dependencies: ["@manifest-editor/image-service-creator"],
|
|
1089
|
+
summary: "IIIF Image service",
|
|
1090
|
+
icon: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_components5.IIIFLogo, { style: { padding: 10 } }),
|
|
1091
|
+
render(ctx) {
|
|
1092
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(CreateImageServiceAnnotationForm, { ...ctx });
|
|
1093
|
+
},
|
|
1094
|
+
resourceType: "Annotation",
|
|
1095
|
+
resourceFields: ["id", "type", "motivation", "body", "target"],
|
|
1096
|
+
additionalTypes: ["Canvas"],
|
|
1097
|
+
supports: {
|
|
1098
|
+
parentTypes: ["AnnotationPage", "Manifest"],
|
|
1099
|
+
parentFields: ["items"]
|
|
1100
|
+
},
|
|
1101
|
+
sideEffects: [resizeToFitService, resizeResourceToEmptyCanvas, repositionMultipleImages],
|
|
1102
|
+
staticFields: {
|
|
1103
|
+
type: "Annotation"
|
|
1104
|
+
}
|
|
1105
|
+
};
|
|
1106
|
+
|
|
1107
|
+
// src/Annotation/NoBodyAnnotation/index.tsx
|
|
1108
|
+
var import_components6 = require("@manifest-editor/components");
|
|
1109
|
+
var import_jsx_runtime22 = require("react/jsx-runtime");
|
|
1110
|
+
var noBodyAnnotation = {
|
|
1111
|
+
id: "@manifest-editor/no-body-annotation",
|
|
1112
|
+
create: createNoBodyAnnotation,
|
|
1113
|
+
label: "Annotation without body",
|
|
1114
|
+
summary: "Add an annotation that only has motivation and target",
|
|
1115
|
+
icon: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_components6.EmptyCanvasIcon, {}),
|
|
1116
|
+
resourceType: "Annotation",
|
|
1117
|
+
resourceFields: ["id", "type", "motivation", "target"],
|
|
1118
|
+
supports: {
|
|
1119
|
+
initialData: true,
|
|
1120
|
+
parentTypes: ["AnnotationPage"],
|
|
1121
|
+
parentFields: ["items"],
|
|
1122
|
+
disallowPainting: true
|
|
1123
|
+
},
|
|
1124
|
+
sideEffects: [],
|
|
1125
|
+
staticFields: {
|
|
1126
|
+
type: "Annotation"
|
|
1127
|
+
}
|
|
1128
|
+
};
|
|
1129
|
+
function createNoBodyAnnotation(data, ctx) {
|
|
1130
|
+
return ctx.embed({
|
|
1131
|
+
id: ctx.generateId("annotation"),
|
|
1132
|
+
type: "Annotation",
|
|
1133
|
+
label: data?.label,
|
|
1134
|
+
motivation: data.motivation || ctx.options.initialData?.motivation || "highlighting",
|
|
1135
|
+
target: ctx.getTarget()
|
|
1136
|
+
});
|
|
1137
|
+
}
|
|
1138
|
+
|
|
1139
|
+
// src/ContentResource/IIIFBrowserCreator/iiif-browser-creator.tsx
|
|
1140
|
+
var import_helpers = require("@iiif/helpers");
|
|
1141
|
+
var import_react5 = require("react");
|
|
1142
|
+
|
|
1143
|
+
// ../../node_modules/.pnpm/tiny-invariant@1.3.3/node_modules/tiny-invariant/dist/esm/tiny-invariant.js
|
|
1144
|
+
var isProduction = false;
|
|
1145
|
+
var prefix = "Invariant failed";
|
|
1146
|
+
function invariant(condition, message) {
|
|
1147
|
+
if (condition) {
|
|
1148
|
+
return;
|
|
1149
|
+
}
|
|
1150
|
+
if (isProduction) {
|
|
1151
|
+
throw new Error(prefix);
|
|
1152
|
+
}
|
|
1153
|
+
var provided = typeof message === "function" ? message() : message;
|
|
1154
|
+
var value = provided ? "".concat(prefix, ": ").concat(provided) : prefix;
|
|
1155
|
+
throw new Error(value);
|
|
1156
|
+
}
|
|
1157
|
+
|
|
1158
|
+
// src/ContentResource/IIIFBrowserCreator/iiif-browser-creator.tsx
|
|
1159
|
+
async function createFromIIIFBrowserOutput(data, ctx) {
|
|
1160
|
+
const targetType = ctx.options.targetType;
|
|
1161
|
+
if (Array.isArray(data.output)) {
|
|
1162
|
+
throw new Error("Multiple items not yet supported");
|
|
1163
|
+
}
|
|
1164
|
+
const contentState = (0, import_helpers.normaliseContentState)(
|
|
1165
|
+
typeof data.output === "string" ? (0, import_helpers.parseContentState)(data.output) : data.output
|
|
1166
|
+
);
|
|
1167
|
+
if (!contentState.target || contentState.target.length === 0) {
|
|
1168
|
+
throw new Error("No target found in content state");
|
|
1169
|
+
}
|
|
1170
|
+
const target = contentState.target[0];
|
|
1171
|
+
const type = target.source.type;
|
|
1172
|
+
const previewVault = ctx.getPreviewVault();
|
|
1173
|
+
if (targetType === "Canvas" || targetType === "Annotation") {
|
|
1174
|
+
if (type === "Canvas") {
|
|
1175
|
+
const canvasId = target.source.id;
|
|
1176
|
+
const manifestId = target.source.partOf?.find((t) => t.type === "Manifest");
|
|
1177
|
+
invariant(manifestId, "Could not load external resource without partOf");
|
|
1178
|
+
const manifest = await previewVault.loadManifest(manifestId);
|
|
1179
|
+
invariant(manifest, "Manifest not found");
|
|
1180
|
+
const canvasRef = manifest.items.find((item) => item.id === canvasId);
|
|
1181
|
+
invariant(canvasRef, "Canvas not found");
|
|
1182
|
+
const canvas = previewVault.get(canvasRef);
|
|
1183
|
+
if (targetType === "Canvas") {
|
|
1184
|
+
return ctx.embed(previewVault.toPresentation3(canvas));
|
|
1185
|
+
}
|
|
1186
|
+
const annotationPage = previewVault.get(canvas.items[0]);
|
|
1187
|
+
const annotation = previewVault.get(annotationPage.items[0]);
|
|
1188
|
+
if (targetType === "Annotation") {
|
|
1189
|
+
const fullAnnotation = previewVault.toPresentation3(annotation);
|
|
1190
|
+
if (fullAnnotation && fullAnnotation?.body?.service) {
|
|
1191
|
+
const width = fullAnnotation?.body.width;
|
|
1192
|
+
const height = fullAnnotation?.body.height;
|
|
1193
|
+
const service = Array.isArray(fullAnnotation?.body?.service) ? fullAnnotation?.body?.service[0] : fullAnnotation?.body?.service;
|
|
1194
|
+
if (!service.width || !service.height) {
|
|
1195
|
+
service.width = width;
|
|
1196
|
+
service.height = height;
|
|
1197
|
+
}
|
|
1198
|
+
}
|
|
1199
|
+
if (target.selector && target.selector.type === "BoxSelector") {
|
|
1200
|
+
const selector = {
|
|
1201
|
+
"@context": "http://iiif.io/api/annex/openannotation/context.json",
|
|
1202
|
+
type: "iiif:ImageApiSelector",
|
|
1203
|
+
region: [
|
|
1204
|
+
~~target.selector.spatial.x,
|
|
1205
|
+
~~target.selector.spatial.y,
|
|
1206
|
+
~~target.selector.spatial.width,
|
|
1207
|
+
~~target.selector.spatial.height
|
|
1208
|
+
].join(",")
|
|
1209
|
+
};
|
|
1210
|
+
fullAnnotation.body = {
|
|
1211
|
+
id: ctx.generateId("SpecificResource", annotation),
|
|
1212
|
+
type: "SpecificResource",
|
|
1213
|
+
source: fullAnnotation.body,
|
|
1214
|
+
selector
|
|
1215
|
+
};
|
|
1216
|
+
return ctx.embed({
|
|
1217
|
+
...fullAnnotation,
|
|
1218
|
+
target: ctx.getTarget()
|
|
1219
|
+
});
|
|
1220
|
+
}
|
|
1221
|
+
return ctx.embed({
|
|
1222
|
+
...previewVault.toPresentation3(annotation),
|
|
1223
|
+
target: ctx.getTarget()
|
|
1224
|
+
});
|
|
1225
|
+
}
|
|
1226
|
+
}
|
|
1227
|
+
}
|
|
1228
|
+
throw new Error("Not yet supported.");
|
|
1229
|
+
}
|
|
1230
|
+
var IIIFBrowserCreatorForm2 = (0, import_react5.lazy)(() => Promise.resolve().then(() => (init_iiif_browser_form_lazy(), iiif_browser_form_lazy_exports)));
|
|
1231
|
+
|
|
1232
|
+
// src/ContentResource/IIIFBrowserCreator/index.tsx
|
|
1233
|
+
var import_components7 = require("@manifest-editor/components");
|
|
1234
|
+
var import_jsx_runtime24 = require("react/jsx-runtime");
|
|
1235
|
+
var iiifBrowserCreator = {
|
|
1236
|
+
id: "@manifest-editor/iiif-browser-creator",
|
|
1237
|
+
create: createFromIIIFBrowserOutput,
|
|
1238
|
+
label: "IIIF Browser",
|
|
1239
|
+
summary: "Browse IIIF Resources",
|
|
1240
|
+
icon: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_components7.IIIFBrowserIcon, {}),
|
|
1241
|
+
render(ctx) {
|
|
1242
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(IIIFBrowserCreatorForm2, { ...ctx });
|
|
1243
|
+
},
|
|
1244
|
+
resourceType: "ContentResource",
|
|
1245
|
+
resourceFields: ["id", "language", "type", "format", "value"],
|
|
1246
|
+
additionalTypes: ["Annotation", "Canvas"],
|
|
1247
|
+
supports: {
|
|
1248
|
+
parentTypes: ["Annotation", "Manifest", "AnnotationPage"],
|
|
1249
|
+
parentFieldMap: {
|
|
1250
|
+
Annotation: ["body"],
|
|
1251
|
+
Manifest: ["items"],
|
|
1252
|
+
AnnotationPage: ["items"]
|
|
1253
|
+
}
|
|
1254
|
+
},
|
|
1255
|
+
sideEffects: [resizeToFitService, resizeResourceToEmptyCanvas, repositionMultipleImages],
|
|
1256
|
+
staticFields: {}
|
|
1257
|
+
};
|
|
1258
|
+
|
|
1259
|
+
// src/Canvas/InternalCanvas/index.tsx
|
|
1260
|
+
var import_react_iiif_vault = require("react-iiif-vault");
|
|
1261
|
+
var import_iiif_browser2 = require("@manifest-editor/iiif-browser");
|
|
1262
|
+
var import_jsx_runtime25 = require("react/jsx-runtime");
|
|
1263
|
+
var internalCanvas = {
|
|
1264
|
+
id: "@manifest-editor/internal-canvas",
|
|
1265
|
+
create: createInternalCanvas,
|
|
1266
|
+
label: "Internal canvas link",
|
|
1267
|
+
summary: "Canvas from the same manifest",
|
|
1268
|
+
icon: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(ThumbnailStripIcon, {}),
|
|
1269
|
+
resourceType: "Canvas",
|
|
1270
|
+
resourceFields: ["id", "type", "label"],
|
|
1271
|
+
supports: {
|
|
1272
|
+
parentTypes: ["Manifest"],
|
|
1273
|
+
parentFields: ["start"]
|
|
1274
|
+
},
|
|
1275
|
+
render: (ctx) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(InternalCanvas, { ...ctx })
|
|
1276
|
+
};
|
|
1277
|
+
function InternalCanvas(props) {
|
|
1278
|
+
const manifest = (0, import_react_iiif_vault.useManifest)();
|
|
1279
|
+
const vault = (0, import_react_iiif_vault.useVault)();
|
|
1280
|
+
invariant(manifest, "Manifest is not loaded");
|
|
1281
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
1282
|
+
import_iiif_browser2.IIIFExplorer,
|
|
1283
|
+
{
|
|
1284
|
+
vault,
|
|
1285
|
+
entry: manifest,
|
|
1286
|
+
window: false,
|
|
1287
|
+
hideHeader: true,
|
|
1288
|
+
hideBack: true,
|
|
1289
|
+
output: { type: "url" },
|
|
1290
|
+
outputTargets: [
|
|
1291
|
+
{
|
|
1292
|
+
type: "callback",
|
|
1293
|
+
label: "Select canvas",
|
|
1294
|
+
cb: (url) => {
|
|
1295
|
+
props.runCreate({ id: url });
|
|
1296
|
+
}
|
|
1297
|
+
}
|
|
1298
|
+
],
|
|
1299
|
+
outputTypes: ["Canvas"]
|
|
1300
|
+
}
|
|
1301
|
+
);
|
|
1302
|
+
}
|
|
1303
|
+
async function createInternalCanvas(data, ctx) {
|
|
1304
|
+
return ctx.embed({ id: data.id, type: "Canvas" });
|
|
1305
|
+
}
|
|
1306
|
+
|
|
1307
|
+
// src/Annotation/ImageUrlAnnotation/create-image-url-annotation.tsx
|
|
1308
|
+
var import_jsx_runtime26 = require("react/jsx-runtime");
|
|
1309
|
+
async function createImageUrlAnnotation(data, ctx) {
|
|
1310
|
+
const annotation = {
|
|
1311
|
+
id: ctx.generateId("annotation"),
|
|
1312
|
+
type: "Annotation"
|
|
1313
|
+
};
|
|
1314
|
+
const targetType = ctx.options.targetType;
|
|
1315
|
+
const resource = await ctx.create("@manifest-editor/image-url-creator", data, {
|
|
1316
|
+
parent: { resource: annotation, property: "body" }
|
|
1317
|
+
});
|
|
1318
|
+
if (targetType === "Annotation") {
|
|
1319
|
+
return {
|
|
1320
|
+
...annotation,
|
|
1321
|
+
body: [resource],
|
|
1322
|
+
motivation: data.motivation || "painting",
|
|
1323
|
+
target: ctx.getTarget()
|
|
1324
|
+
};
|
|
1325
|
+
}
|
|
1326
|
+
if (targetType === "Canvas") {
|
|
1327
|
+
const canvasId = ctx.generateId("canvas");
|
|
1328
|
+
const pageId = ctx.generateId("annotation-page", { id: canvasId, type: "Canvas" });
|
|
1329
|
+
const annotationResource = ctx.embed({
|
|
1330
|
+
...annotation,
|
|
1331
|
+
motivation: "painting",
|
|
1332
|
+
body: [resource],
|
|
1333
|
+
target: { type: "SpecificResource", source: { id: canvasId, type: "Canvas" } }
|
|
1334
|
+
});
|
|
1335
|
+
const page = ctx.embed({
|
|
1336
|
+
id: pageId,
|
|
1337
|
+
type: "AnnotationPage",
|
|
1338
|
+
items: [annotationResource]
|
|
1339
|
+
});
|
|
1340
|
+
return ctx.embed({
|
|
1341
|
+
id: canvasId,
|
|
1342
|
+
type: "Canvas",
|
|
1343
|
+
label: data.label || { en: ["Untitled canvas"] },
|
|
1344
|
+
height: resource.resource.height || 1e3,
|
|
1345
|
+
width: resource.resource.width || 1e3,
|
|
1346
|
+
items: [page]
|
|
1347
|
+
});
|
|
1348
|
+
}
|
|
1349
|
+
}
|
|
1350
|
+
function CreateImageUrlAnnotationForm(props) {
|
|
1351
|
+
return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(CreateImageUrlForm, { ...props });
|
|
1352
|
+
}
|
|
1353
|
+
|
|
1354
|
+
// src/Annotation/ImageUrlAnnotation/index.tsx
|
|
1355
|
+
var import_components8 = require("@manifest-editor/components");
|
|
1356
|
+
var import_jsx_runtime27 = require("react/jsx-runtime");
|
|
1357
|
+
var imageUrlAnnotation = {
|
|
1358
|
+
id: "@manifest-editor/image-url-annotation",
|
|
1359
|
+
create: createImageUrlAnnotation,
|
|
1360
|
+
label: "Image",
|
|
1361
|
+
dependencies: ["@manifest-editor/image-url-creator"],
|
|
1362
|
+
summary: "Image from URL",
|
|
1363
|
+
icon: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_components8.AddImageIcon, {}),
|
|
1364
|
+
render(ctx) {
|
|
1365
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(CreateImageUrlAnnotationForm, { ...ctx });
|
|
1366
|
+
},
|
|
1367
|
+
resourceType: "Annotation",
|
|
1368
|
+
resourceFields: ["id", "type", "motivation", "body", "target"],
|
|
1369
|
+
additionalTypes: ["Canvas"],
|
|
1370
|
+
supports: {
|
|
1371
|
+
parentTypes: ["AnnotationPage", "Manifest"],
|
|
1372
|
+
parentFields: ["items"]
|
|
1373
|
+
},
|
|
1374
|
+
sideEffects: [resizeToFitService, resizeResourceToEmptyCanvas, repositionMultipleImages],
|
|
1375
|
+
staticFields: {
|
|
1376
|
+
type: "Annotation"
|
|
1377
|
+
}
|
|
1378
|
+
};
|
|
1379
|
+
|
|
1380
|
+
// src/Annotation/AudioAnnotation/create-audio-annotation.tsx
|
|
1381
|
+
var import_react7 = require("react");
|
|
1382
|
+
|
|
1383
|
+
// ../ui/atoms/callouts/ErrorMessage.tsx
|
|
1384
|
+
var import_styled_components3 = __toESM(require("styled-components"), 1);
|
|
1385
|
+
var ErrorMessage = import_styled_components3.default.div`
|
|
1386
|
+
border: 2px solid ${(props) => props.theme.color.danger || "red"};
|
|
1387
|
+
width: 100%;
|
|
1388
|
+
border-radius: 5px;
|
|
1389
|
+
padding: ${(props) => props.theme.padding.small || "0.5rem"}
|
|
1390
|
+
${(props) => props.theme.padding.medium || "1rem"};
|
|
1391
|
+
line-height: 1.9em;
|
|
1392
|
+
display: flex;
|
|
1393
|
+
align-items: center;
|
|
1394
|
+
a {
|
|
1395
|
+
color: ${(props) => props.theme.color.white || "white"};
|
|
1396
|
+
}
|
|
1397
|
+
${(props) => props.$small && import_styled_components3.css`
|
|
1398
|
+
font-size: 0.75em;
|
|
1399
|
+
white-space: nowrap;
|
|
1400
|
+
padding: ${props.theme.padding.xs || "0.25rem"} ${props.theme.padding.small || "0.5rem"};
|
|
1401
|
+
line-height: 1.6em;
|
|
1402
|
+
width: fit-content;
|
|
1403
|
+
`}
|
|
1404
|
+
`;
|
|
1405
|
+
|
|
1406
|
+
// ../ui/ui/MediaControls/MediaControls.tsx
|
|
1407
|
+
var import_react_iiif_vault2 = require("react-iiif-vault");
|
|
1408
|
+
var import_react6 = require("react");
|
|
1409
|
+
|
|
1410
|
+
// ../ui/ui/MediaControls/MediaControls.icons.tsx
|
|
1411
|
+
var import_jsx_runtime28 = require("react/jsx-runtime");
|
|
1412
|
+
var PlayIcon = (props) => /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("svg", { ...props, viewBox: "4 4 16 16", xmlns: "http://www.w3.org/2000/svg", height: "1em", width: "1em", children: [
|
|
1413
|
+
props.title ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("title", { children: props.title }) : null,
|
|
1414
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("path", { d: "M0 0h24v24H0z", fill: "none" }),
|
|
1415
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("path", { d: "M8 5v14l11-7z", fill: "currentColor" })
|
|
1416
|
+
] });
|
|
1417
|
+
var PauseIcon = (props) => /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("svg", { ...props, viewBox: "4 4 16 16", xmlns: "http://www.w3.org/2000/svg", height: "1em", width: "1em", children: [
|
|
1418
|
+
props.title ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("title", { children: props.title }) : null,
|
|
1419
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("path", { d: "M0 0h24v24H0z", fill: "none" }),
|
|
1420
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("path", { fill: "currentColor", d: "M6 19h4V5H6v14zm8-14v14h4V5h-4z" })
|
|
1421
|
+
] });
|
|
1422
|
+
var VolumeUpIcon = ({ title, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("svg", { ...props, xmlns: "http://www.w3.org/2000/svg", height: "1em", width: "1em", viewBox: "2 2 20 20", children: [
|
|
1423
|
+
title ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("title", { children: title }) : null,
|
|
1424
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("path", { d: "M0 0h24v24H0z", fill: "none" }),
|
|
1425
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
1426
|
+
"path",
|
|
1427
|
+
{
|
|
1428
|
+
fill: "currentColor",
|
|
1429
|
+
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"
|
|
1430
|
+
}
|
|
1431
|
+
)
|
|
1432
|
+
] });
|
|
1433
|
+
var VolumeDownIcon = ({ title, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("svg", { ...props, xmlns: "http://www.w3.org/2000/svg", height: "1em", width: "1em", viewBox: "2 2 20 20", children: [
|
|
1434
|
+
title ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("title", { children: title }) : null,
|
|
1435
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("path", { d: "M0 0h24v24H0z", fill: "none" }),
|
|
1436
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
1437
|
+
"path",
|
|
1438
|
+
{
|
|
1439
|
+
fill: "currentColor",
|
|
1440
|
+
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"
|
|
1441
|
+
}
|
|
1442
|
+
)
|
|
1443
|
+
] });
|
|
1444
|
+
var VolumeOffIcon = ({ title, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("svg", { ...props, xmlns: "http://www.w3.org/2000/svg", height: "1em", width: "1em", viewBox: "2 2 20 20", children: [
|
|
1445
|
+
title ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("title", { children: title }) : null,
|
|
1446
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("path", { d: "M0 0h24v24H0z", fill: "none" }),
|
|
1447
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
1448
|
+
"path",
|
|
1449
|
+
{
|
|
1450
|
+
fill: "currentColor",
|
|
1451
|
+
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"
|
|
1452
|
+
}
|
|
1453
|
+
)
|
|
1454
|
+
] });
|
|
1455
|
+
|
|
1456
|
+
// ../ui/ui/MediaControls/MediaControls.styles.ts
|
|
1457
|
+
var import_styled_components4 = __toESM(require("styled-components"), 1);
|
|
1458
|
+
var AudioPlayerContainer = import_styled_components4.default.div`
|
|
1459
|
+
background: #ededed; // Not in variable.
|
|
1460
|
+
display: flex;
|
|
1461
|
+
padding: 0.5em;
|
|
1462
|
+
align-items: center;
|
|
1463
|
+
`;
|
|
1464
|
+
var BaseButton = import_styled_components4.default.button`
|
|
1465
|
+
cursor: pointer;
|
|
1466
|
+
padding: 0.75em 1.5em;
|
|
1467
|
+
font-size: 0.938em;
|
|
1468
|
+
background: none;
|
|
1469
|
+
color: inherit;
|
|
1470
|
+
border: none;
|
|
1471
|
+
text-decoration: none;
|
|
1472
|
+
display: inline-block;
|
|
1473
|
+
vertical-align: top;
|
|
1474
|
+
white-space: nowrap;
|
|
1475
|
+
`;
|
|
1476
|
+
var PlayButton = (0, import_styled_components4.default)(BaseButton)`
|
|
1477
|
+
width: 2em;
|
|
1478
|
+
height: 2em;
|
|
1479
|
+
overflow: hidden;
|
|
1480
|
+
font-size: 1.1em;
|
|
1481
|
+
background: #fff;
|
|
1482
|
+
border-radius: 3px;
|
|
1483
|
+
padding: 0;
|
|
1484
|
+
margin: 0;
|
|
1485
|
+
color: #000; // Not in colours
|
|
1486
|
+
|
|
1487
|
+
&:disabled {
|
|
1488
|
+
color: #999;
|
|
1489
|
+
}
|
|
1490
|
+
`;
|
|
1491
|
+
var TimeDisplay = import_styled_components4.default.div`
|
|
1492
|
+
margin: 0 1em;
|
|
1493
|
+
font-size: 0.85em;
|
|
1494
|
+
color: #000;
|
|
1495
|
+
`;
|
|
1496
|
+
var ProgressContainer = import_styled_components4.default.div`
|
|
1497
|
+
flex: 1 1 0px;
|
|
1498
|
+
height: 6px;
|
|
1499
|
+
display: flex;
|
|
1500
|
+
position: relative;
|
|
1501
|
+
padding: 15px 0;
|
|
1502
|
+
`;
|
|
1503
|
+
var ProgressCurrent = import_styled_components4.default.div`
|
|
1504
|
+
background: #d85680;
|
|
1505
|
+
height: 6px;
|
|
1506
|
+
pointer-events: none;
|
|
1507
|
+
position: absolute;
|
|
1508
|
+
top: 13px;
|
|
1509
|
+
left: 0;
|
|
1510
|
+
border-radius: 3px;
|
|
1511
|
+
transition: width 200ms;
|
|
1512
|
+
`;
|
|
1513
|
+
var ProgressBackground = import_styled_components4.default.div`
|
|
1514
|
+
position: absolute;
|
|
1515
|
+
top: 13px;
|
|
1516
|
+
left: 0;
|
|
1517
|
+
height: 6px;
|
|
1518
|
+
border-radius: 3px;
|
|
1519
|
+
width: 100%;
|
|
1520
|
+
pointer-events: none;
|
|
1521
|
+
background: #fff;
|
|
1522
|
+
`;
|
|
1523
|
+
var SoundButton = (0, import_styled_components4.default)(BaseButton)`
|
|
1524
|
+
width: 2em;
|
|
1525
|
+
height: 2em;
|
|
1526
|
+
overflow: hidden;
|
|
1527
|
+
font-size: 1.1em;
|
|
1528
|
+
background: transparent;
|
|
1529
|
+
border-radius: 3px;
|
|
1530
|
+
padding: 0;
|
|
1531
|
+
margin: 0;
|
|
1532
|
+
`;
|
|
1533
|
+
var SoundContainer = import_styled_components4.default.div`
|
|
1534
|
+
display: flex;
|
|
1535
|
+
align-items: center;
|
|
1536
|
+
`;
|
|
1537
|
+
var VolumeContainer = import_styled_components4.default.div`
|
|
1538
|
+
width: 0;
|
|
1539
|
+
overflow: hidden;
|
|
1540
|
+
transition: width 500ms;
|
|
1541
|
+
color: #4a473f; // Not in colours
|
|
1542
|
+
|
|
1543
|
+
${(props) => props.$isOpen && import_styled_components4.css`
|
|
1544
|
+
width: 150px;
|
|
1545
|
+
`}
|
|
1546
|
+
`;
|
|
1547
|
+
var VolumeSlider = import_styled_components4.default.input.attrs({ type: "range" })`
|
|
1548
|
+
width: 120px;
|
|
1549
|
+
margin: 0 15px;
|
|
1550
|
+
`;
|
|
1551
|
+
|
|
1552
|
+
// ../ui/madoc/components/icons/Spinner.tsx
|
|
1553
|
+
var import_jsx_runtime29 = require("react/jsx-runtime");
|
|
1554
|
+
function Spinner(props) {
|
|
1555
|
+
return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("svg", { width: "1em", height: "1em", viewBox: "0 0 42 42", xmlns: "http://www.w3.org/2000/svg", stroke: "#fff", ...props, children: /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("g", { transform: "translate(2 2)", strokeWidth: 5, fill: "none", fillRule: "evenodd", children: [
|
|
1556
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("circle", { strokeOpacity: 0.5, cx: 18, cy: 18, r: 18 }),
|
|
1557
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("path", { d: "M36 18c0-9.94-8.06-18-18-18", children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
1558
|
+
"animateTransform",
|
|
1559
|
+
{
|
|
1560
|
+
attributeName: "transform",
|
|
1561
|
+
type: "rotate",
|
|
1562
|
+
from: "0 18 18",
|
|
1563
|
+
to: "360 18 18",
|
|
1564
|
+
dur: "1s",
|
|
1565
|
+
repeatCount: "indefinite"
|
|
1566
|
+
}
|
|
1567
|
+
) })
|
|
1568
|
+
] }) });
|
|
1569
|
+
}
|
|
1570
|
+
|
|
1571
|
+
// ../ui/atoms/VisuallHidden/VisuallHidden.tsx
|
|
1572
|
+
var import_styled_components5 = __toESM(require("styled-components"), 1);
|
|
1573
|
+
var visuallyHidden = import_styled_components5.css`
|
|
1574
|
+
clip: rect(1px, 1px, 1px, 1px);
|
|
1575
|
+
clip-path: inset(50%);
|
|
1576
|
+
height: 1px;
|
|
1577
|
+
width: 1px;
|
|
1578
|
+
margin: -1px;
|
|
1579
|
+
overflow: hidden;
|
|
1580
|
+
padding: 0;
|
|
1581
|
+
position: absolute;
|
|
1582
|
+
`;
|
|
1583
|
+
var VisuallyHiddenLabel = import_styled_components5.default.label`
|
|
1584
|
+
${visuallyHidden}
|
|
1585
|
+
`;
|
|
1586
|
+
|
|
1587
|
+
// ../ui/ui/MediaControls/MediaControls.tsx
|
|
1588
|
+
var import_jsx_runtime30 = require("react/jsx-runtime");
|
|
1589
|
+
function MediaControls(props) {
|
|
1590
|
+
const [isVolumeOpen, setIsVolumeOpen] = (0, import_react6.useState)(false);
|
|
1591
|
+
const { progress, currentTime, element } = (0, import_react_iiif_vault2.useMediaElements)();
|
|
1592
|
+
const { duration, isMuted, volume, isPlaying, playRequested } = (0, import_react_iiif_vault2.useMediaState)();
|
|
1593
|
+
const { setVolume, toggleMute, play, pause, setDurationPercent } = (0, import_react_iiif_vault2.useMediaActions)();
|
|
1594
|
+
const Volume = isMuted || volume === 0 ? VolumeOffIcon : volume > 50 ? VolumeUpIcon : VolumeDownIcon;
|
|
1595
|
+
(0, import_react6.useLayoutEffect)(() => {
|
|
1596
|
+
if (element.current) {
|
|
1597
|
+
const $el = element.current;
|
|
1598
|
+
if ($el.error && props.onError) {
|
|
1599
|
+
props.onError($el.error?.message || "Unknown error");
|
|
1600
|
+
return;
|
|
1601
|
+
}
|
|
1602
|
+
const onError = () => {
|
|
1603
|
+
if (props.onError) {
|
|
1604
|
+
props.onError($el.error?.message || "Unknown error");
|
|
1605
|
+
}
|
|
1606
|
+
};
|
|
1607
|
+
const loadedMetadata = () => {
|
|
1608
|
+
if ($el.duration && props.onDuration) {
|
|
1609
|
+
props.onDuration($el.duration);
|
|
1610
|
+
}
|
|
1611
|
+
if (props.onDimensions && $el instanceof HTMLVideoElement) {
|
|
1612
|
+
props.onDimensions($el.videoWidth, $el.videoHeight);
|
|
1613
|
+
}
|
|
1614
|
+
};
|
|
1615
|
+
$el.addEventListener("loadedmetadata", loadedMetadata);
|
|
1616
|
+
$el.addEventListener("error", onError);
|
|
1617
|
+
return () => {
|
|
1618
|
+
$el.removeEventListener("loadedmetadata", loadedMetadata);
|
|
1619
|
+
$el.removeEventListener("error", onError);
|
|
1620
|
+
};
|
|
1621
|
+
}
|
|
1622
|
+
}, []);
|
|
1623
|
+
return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(AudioPlayerContainer, { children: [
|
|
1624
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
1625
|
+
PlayButton,
|
|
1626
|
+
{
|
|
1627
|
+
disabled: playRequested,
|
|
1628
|
+
onClick: () => {
|
|
1629
|
+
if (isPlaying) {
|
|
1630
|
+
pause();
|
|
1631
|
+
} else {
|
|
1632
|
+
play();
|
|
1633
|
+
}
|
|
1634
|
+
},
|
|
1635
|
+
children: playRequested ? /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(Spinner, { stroke: "#999" }) : isPlaying ? /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(PauseIcon, { title: "Pause" }) : /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(PlayIcon, { title: "Play" })
|
|
1636
|
+
}
|
|
1637
|
+
),
|
|
1638
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(TimeDisplay, { ref: currentTime, children: "0:00" }),
|
|
1639
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
|
|
1640
|
+
ProgressContainer,
|
|
1641
|
+
{
|
|
1642
|
+
onClick: (e) => {
|
|
1643
|
+
const { left, width } = e.currentTarget.getBoundingClientRect();
|
|
1644
|
+
const percent = (e.pageX - left) / width;
|
|
1645
|
+
setDurationPercent(percent);
|
|
1646
|
+
},
|
|
1647
|
+
children: [
|
|
1648
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(ProgressBackground, {}),
|
|
1649
|
+
duration ? /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(ProgressCurrent, { ref: progress }) : null
|
|
1650
|
+
]
|
|
1651
|
+
}
|
|
1652
|
+
),
|
|
1653
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(TimeDisplay, { children: (0, import_react_iiif_vault2.formatTime)(duration) }),
|
|
1654
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(SoundContainer, { onMouseEnter: () => setIsVolumeOpen(true), onMouseLeave: () => setIsVolumeOpen(false), children: [
|
|
1655
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(VolumeContainer, { $isOpen: isVolumeOpen, children: /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("span", { children: [
|
|
1656
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(VisuallyHiddenLabel, { htmlFor: "audio-slider", children: "Change volume" }),
|
|
1657
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
1658
|
+
VolumeSlider,
|
|
1659
|
+
{
|
|
1660
|
+
id: "audio-slider",
|
|
1661
|
+
role: "slider",
|
|
1662
|
+
disabled: isMuted,
|
|
1663
|
+
min: "0",
|
|
1664
|
+
max: "100",
|
|
1665
|
+
value: volume,
|
|
1666
|
+
onChange: (e) => setVolume(Number(e.currentTarget.value))
|
|
1667
|
+
}
|
|
1668
|
+
)
|
|
1669
|
+
] }) }),
|
|
1670
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(SoundButton, { onClick: () => toggleMute(), children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(Volume, { title: isMuted ? "Mute" : "Unmute" }) })
|
|
1671
|
+
] })
|
|
1672
|
+
] });
|
|
1673
|
+
}
|
|
1674
|
+
|
|
1675
|
+
// src/Annotation/AudioAnnotation/create-audio-annotation.tsx
|
|
1676
|
+
var import_react_iiif_vault3 = require("react-iiif-vault");
|
|
1677
|
+
var import_helpers2 = require("@iiif/helpers");
|
|
1678
|
+
var import_editors9 = require("@manifest-editor/editors");
|
|
1679
|
+
var import_jsx_runtime31 = require("react/jsx-runtime");
|
|
1680
|
+
async function createAudioAnnotation(data, ctx) {
|
|
1681
|
+
const annotation = {
|
|
1682
|
+
id: ctx.generateId("annotation"),
|
|
1683
|
+
type: "Annotation"
|
|
1684
|
+
};
|
|
1685
|
+
const targetType = ctx.options.targetType;
|
|
1686
|
+
const body = await ctx.embed({
|
|
1687
|
+
id: data.url,
|
|
1688
|
+
type: "Sound",
|
|
1689
|
+
format: "audio/mp4",
|
|
1690
|
+
duration: data.duration || 0
|
|
1691
|
+
});
|
|
1692
|
+
if (targetType === "Annotation") {
|
|
1693
|
+
return ctx.embed({
|
|
1694
|
+
...annotation,
|
|
1695
|
+
label: (0, import_helpers2.getValue)(data.label) && data.label,
|
|
1696
|
+
motivation: data.motivation || ctx.options.initialData?.motivation || "painting",
|
|
1697
|
+
body,
|
|
1698
|
+
target: ctx.getTarget()
|
|
1699
|
+
});
|
|
1700
|
+
}
|
|
1701
|
+
if (targetType === "Canvas") {
|
|
1702
|
+
const canvasId = ctx.generateId("canvas");
|
|
1703
|
+
const pageId = ctx.generateId("annotation-page", { id: canvasId, type: "Canvas" });
|
|
1704
|
+
const annotationResource = ctx.embed({
|
|
1705
|
+
...annotation,
|
|
1706
|
+
motivation: "painting",
|
|
1707
|
+
body,
|
|
1708
|
+
target: { type: "SpecificResource", source: { id: canvasId, type: "Canvas" } }
|
|
1709
|
+
});
|
|
1710
|
+
const page = ctx.embed({
|
|
1711
|
+
id: pageId,
|
|
1712
|
+
type: "AnnotationPage",
|
|
1713
|
+
items: [annotationResource]
|
|
1714
|
+
});
|
|
1715
|
+
return ctx.embed({
|
|
1716
|
+
id: canvasId,
|
|
1717
|
+
type: "Canvas",
|
|
1718
|
+
label: data.label || { en: ["Untitled HTML canvas"] },
|
|
1719
|
+
duration: data.duration || 0,
|
|
1720
|
+
items: [page]
|
|
1721
|
+
});
|
|
1722
|
+
}
|
|
1723
|
+
}
|
|
1724
|
+
function CreateAudioAnnotationForm(props) {
|
|
1725
|
+
const [url, setUrl] = (0, import_react7.useState)("");
|
|
1726
|
+
const [duration, setDuration] = (0, import_react7.useState)(0);
|
|
1727
|
+
const [error, setError] = (0, import_react7.useState)("");
|
|
1728
|
+
const [label, setLabel] = (0, import_react7.useState)({ en: [""] });
|
|
1729
|
+
const onSubmit = () => {
|
|
1730
|
+
props.runCreate({
|
|
1731
|
+
url,
|
|
1732
|
+
duration,
|
|
1733
|
+
label
|
|
1734
|
+
});
|
|
1735
|
+
};
|
|
1736
|
+
(0, import_react7.useEffect)(() => {
|
|
1737
|
+
setError("");
|
|
1738
|
+
setDuration(0);
|
|
1739
|
+
if (url) {
|
|
1740
|
+
const labelFromUrl = url.split("/").pop()?.split(".").shift();
|
|
1741
|
+
setLabel({ en: [labelFromUrl || ""] });
|
|
1742
|
+
}
|
|
1743
|
+
}, [url]);
|
|
1744
|
+
return /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(PaddedSidebarContainer, { children: [
|
|
1745
|
+
error ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(ErrorMessage, { children: error }) : null,
|
|
1746
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(import_editors9.InputContainer, { children: [
|
|
1747
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_editors9.InputLabel, { htmlFor: "audio-url", children: "URL" }),
|
|
1748
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_editors9.Input, { type: "text", id: "audio-url", value: url, onChange: (e) => setUrl(e.target.value) })
|
|
1749
|
+
] }),
|
|
1750
|
+
url && !error ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
|
|
1751
|
+
import_editors9.LanguageFieldEditor,
|
|
1752
|
+
{
|
|
1753
|
+
containerId: "label",
|
|
1754
|
+
focusId: "label_",
|
|
1755
|
+
label: "Label",
|
|
1756
|
+
fields: label,
|
|
1757
|
+
onSave: (e) => setLabel(e.toInternationalString())
|
|
1758
|
+
},
|
|
1759
|
+
url + "__" + duration
|
|
1760
|
+
) }) : null,
|
|
1761
|
+
url && !error ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_react_iiif_vault3.CanvasPanel.AudioHTML, { media: { url, duration, type: "Sound" }, children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
|
|
1762
|
+
MediaControls,
|
|
1763
|
+
{
|
|
1764
|
+
onError: (error2) => setError(error2),
|
|
1765
|
+
onDuration: (duration2) => setDuration(duration2)
|
|
1766
|
+
},
|
|
1767
|
+
url + "__" + duration
|
|
1768
|
+
) }, url + "__" + duration) : null,
|
|
1769
|
+
duration && !error ? /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(import_editors9.FormFieldWrapper, { children: [
|
|
1770
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_editors9.InputLabel, { htmlFor: "duration", children: "Duration" }),
|
|
1771
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_editors9.Input, { type: "number", id: "duration", value: duration, onChange: (e) => setDuration(e.target.valueAsNumber) })
|
|
1772
|
+
] }) : null,
|
|
1773
|
+
url && !error && /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(Button, { onClick: onSubmit, children: "Add audio" })
|
|
1774
|
+
] });
|
|
1775
|
+
}
|
|
1776
|
+
|
|
1777
|
+
// src/Annotation/AudioAnnotation/index.tsx
|
|
1778
|
+
var import_components9 = require("@manifest-editor/components");
|
|
1779
|
+
var import_jsx_runtime32 = require("react/jsx-runtime");
|
|
1780
|
+
var audioAnnotation = {
|
|
1781
|
+
id: "@manifest-editor/audio-annotation",
|
|
1782
|
+
create: createAudioAnnotation,
|
|
1783
|
+
label: "Audio",
|
|
1784
|
+
summary: "Audio annotation",
|
|
1785
|
+
icon: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_components9.AudioIcon, {}),
|
|
1786
|
+
render(ctx) {
|
|
1787
|
+
return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(CreateAudioAnnotationForm, { ...ctx });
|
|
1788
|
+
},
|
|
1789
|
+
resourceType: "Annotation",
|
|
1790
|
+
resourceFields: ["id", "type", "motivation", "body", "target"],
|
|
1791
|
+
additionalTypes: ["Canvas"],
|
|
1792
|
+
supports: {
|
|
1793
|
+
initialData: true,
|
|
1794
|
+
parentTypes: ["AnnotationPage", "Manifest"],
|
|
1795
|
+
parentFields: ["items"]
|
|
1796
|
+
},
|
|
1797
|
+
staticFields: {
|
|
1798
|
+
type: "Annotation"
|
|
1799
|
+
}
|
|
1800
|
+
};
|
|
1801
|
+
|
|
1802
|
+
// src/Annotation/VideoAnnotation/create-video-annotation.tsx
|
|
1803
|
+
var import_helpers3 = require("@iiif/helpers");
|
|
1804
|
+
var import_editors10 = require("@manifest-editor/editors");
|
|
1805
|
+
var import_react8 = require("react");
|
|
1806
|
+
|
|
1807
|
+
// ../ui/ui/VideoPlayer/VideoPlayer.tsx
|
|
1808
|
+
var import_react_iiif_vault4 = require("react-iiif-vault");
|
|
1809
|
+
var import_jsx_runtime33 = require("react/jsx-runtime");
|
|
1810
|
+
function VideoPlayer({
|
|
1811
|
+
media,
|
|
1812
|
+
onError,
|
|
1813
|
+
duration,
|
|
1814
|
+
onDuration,
|
|
1815
|
+
onDimensions
|
|
1816
|
+
}) {
|
|
1817
|
+
const [{ element, currentTime, progress }, state, actions] = (0, import_react_iiif_vault4.useSimpleMediaPlayer)({ duration });
|
|
1818
|
+
return /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(
|
|
1819
|
+
import_react_iiif_vault4.MediaPlayerProvider,
|
|
1820
|
+
{
|
|
1821
|
+
element,
|
|
1822
|
+
state,
|
|
1823
|
+
actions,
|
|
1824
|
+
currentTime,
|
|
1825
|
+
progress,
|
|
1826
|
+
children: [
|
|
1827
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
1828
|
+
"div",
|
|
1829
|
+
{
|
|
1830
|
+
style: {
|
|
1831
|
+
maxHeight: 400,
|
|
1832
|
+
aspectRatio: `${media.width}/${media.height}`,
|
|
1833
|
+
position: "relative"
|
|
1834
|
+
},
|
|
1835
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_react_iiif_vault4.CanvasPanel.VideoHTML, { element, media, playPause: actions.playPause })
|
|
1836
|
+
}
|
|
1837
|
+
),
|
|
1838
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)(MediaControls, { onError, onDuration, onDimensions })
|
|
1839
|
+
]
|
|
1840
|
+
}
|
|
1841
|
+
);
|
|
1842
|
+
}
|
|
1843
|
+
|
|
1844
|
+
// src/Annotation/VideoAnnotation/create-video-annotation.tsx
|
|
1845
|
+
var import_jsx_runtime34 = require("react/jsx-runtime");
|
|
1846
|
+
async function createVideoAnnotation(data, ctx) {
|
|
1847
|
+
const annotation = {
|
|
1848
|
+
id: ctx.generateId("annotation"),
|
|
1849
|
+
type: "Annotation"
|
|
1850
|
+
};
|
|
1851
|
+
const targetType = ctx.options.targetType;
|
|
1852
|
+
const body = await ctx.embed({
|
|
1853
|
+
id: data.url,
|
|
1854
|
+
type: "Video",
|
|
1855
|
+
format: "video/mp4",
|
|
1856
|
+
width: data.width,
|
|
1857
|
+
height: data.height,
|
|
1858
|
+
duration: data.duration || 0
|
|
1859
|
+
});
|
|
1860
|
+
if (targetType === "Annotation") {
|
|
1861
|
+
return ctx.embed({
|
|
1862
|
+
...annotation,
|
|
1863
|
+
label: (0, import_helpers3.getValue)(data.label) && data.label,
|
|
1864
|
+
motivation: data.motivation || ctx.options.initialData?.motivation || "painting",
|
|
1865
|
+
body,
|
|
1866
|
+
target: ctx.getTarget()
|
|
1867
|
+
});
|
|
1868
|
+
}
|
|
1869
|
+
if (targetType === "Canvas") {
|
|
1870
|
+
const canvasId = ctx.generateId("canvas");
|
|
1871
|
+
const pageId = ctx.generateId("annotation-page", { id: canvasId, type: "Canvas" });
|
|
1872
|
+
const annotationResource = ctx.embed({
|
|
1873
|
+
...annotation,
|
|
1874
|
+
motivation: "painting",
|
|
1875
|
+
body,
|
|
1876
|
+
target: { type: "SpecificResource", source: { id: canvasId, type: "Canvas" } }
|
|
1877
|
+
});
|
|
1878
|
+
const page = ctx.embed({
|
|
1879
|
+
id: pageId,
|
|
1880
|
+
type: "AnnotationPage",
|
|
1881
|
+
items: [annotationResource]
|
|
1882
|
+
});
|
|
1883
|
+
return ctx.embed({
|
|
1884
|
+
id: canvasId,
|
|
1885
|
+
type: "Canvas",
|
|
1886
|
+
label: data.label || { en: ["Untitled HTML canvas"] },
|
|
1887
|
+
duration: data.duration || 0,
|
|
1888
|
+
width: data.width,
|
|
1889
|
+
height: data.height,
|
|
1890
|
+
items: [page]
|
|
1891
|
+
});
|
|
1892
|
+
}
|
|
1893
|
+
}
|
|
1894
|
+
function CreateVideoAnnotationForm(props) {
|
|
1895
|
+
const [url, setUrl] = (0, import_react8.useState)("");
|
|
1896
|
+
const [duration, setDuration] = (0, import_react8.useState)(0);
|
|
1897
|
+
const [width, setWidth] = (0, import_react8.useState)(0);
|
|
1898
|
+
const [height, setHeight] = (0, import_react8.useState)(0);
|
|
1899
|
+
const [error, setError] = (0, import_react8.useState)("");
|
|
1900
|
+
const [label, setLabel] = (0, import_react8.useState)({ en: [""] });
|
|
1901
|
+
const onSubmit = () => {
|
|
1902
|
+
props.runCreate({
|
|
1903
|
+
url,
|
|
1904
|
+
duration,
|
|
1905
|
+
label,
|
|
1906
|
+
width,
|
|
1907
|
+
height
|
|
1908
|
+
});
|
|
1909
|
+
};
|
|
1910
|
+
(0, import_react8.useEffect)(() => {
|
|
1911
|
+
setError("");
|
|
1912
|
+
setDuration(0);
|
|
1913
|
+
if (url) {
|
|
1914
|
+
const labelFromUrl = url.split("/").pop()?.split(".").shift();
|
|
1915
|
+
setLabel({ en: [labelFromUrl || ""] });
|
|
1916
|
+
}
|
|
1917
|
+
}, [url]);
|
|
1918
|
+
return /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(PaddedSidebarContainer, { children: [
|
|
1919
|
+
error ? /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(ErrorMessage, { children: error }) : null,
|
|
1920
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(import_editors10.InputContainer, { children: [
|
|
1921
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_editors10.InputLabel, { htmlFor: "video-url", children: "URL" }),
|
|
1922
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_editors10.Input, { type: "text", id: "video-url", value: url, onChange: (e) => setUrl(e.target.value) })
|
|
1923
|
+
] }),
|
|
1924
|
+
url && !error ? /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
1925
|
+
import_editors10.LanguageFieldEditor,
|
|
1926
|
+
{
|
|
1927
|
+
containerId: "label",
|
|
1928
|
+
focusId: "label_",
|
|
1929
|
+
label: "Label",
|
|
1930
|
+
fields: label,
|
|
1931
|
+
onSave: (e) => setLabel(e.toInternationalString())
|
|
1932
|
+
},
|
|
1933
|
+
url + "__" + duration
|
|
1934
|
+
) }) : null,
|
|
1935
|
+
url && !error ? /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
1936
|
+
VideoPlayer,
|
|
1937
|
+
{
|
|
1938
|
+
duration,
|
|
1939
|
+
onDuration: (d) => setDuration(d),
|
|
1940
|
+
onError: (err) => setError(err),
|
|
1941
|
+
media: {
|
|
1942
|
+
url,
|
|
1943
|
+
duration,
|
|
1944
|
+
height,
|
|
1945
|
+
width,
|
|
1946
|
+
type: "Video"
|
|
1947
|
+
},
|
|
1948
|
+
onDimensions: (w, h) => {
|
|
1949
|
+
setWidth(w || 0);
|
|
1950
|
+
setHeight(h || 0);
|
|
1951
|
+
}
|
|
1952
|
+
}
|
|
1953
|
+
) : null,
|
|
1954
|
+
!error && (duration || width || height) ? /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_editors10.InputContainer, { $wide: true, children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
1955
|
+
import_editors10.DimensionsTriplet,
|
|
1956
|
+
{
|
|
1957
|
+
widthId: "width",
|
|
1958
|
+
width: width || 0,
|
|
1959
|
+
changeWidth: (v) => setWidth(v),
|
|
1960
|
+
heightId: "height",
|
|
1961
|
+
height: height || 0,
|
|
1962
|
+
changeHeight: (v) => setHeight(v),
|
|
1963
|
+
durationId: "duration",
|
|
1964
|
+
duration: duration || 0,
|
|
1965
|
+
changeDuration: (v) => setDuration(v)
|
|
1966
|
+
}
|
|
1967
|
+
) }) : null,
|
|
1968
|
+
url && !error && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(Button, { onClick: onSubmit, children: "Add video" })
|
|
1969
|
+
] });
|
|
1970
|
+
}
|
|
1971
|
+
|
|
1972
|
+
// src/Annotation/VideoAnnotation/index.tsx
|
|
1973
|
+
var import_components10 = require("@manifest-editor/components");
|
|
1974
|
+
var import_jsx_runtime35 = require("react/jsx-runtime");
|
|
1975
|
+
var videoAnnotation = {
|
|
1976
|
+
id: "@manifest-editor/video-annotation",
|
|
1977
|
+
create: createVideoAnnotation,
|
|
1978
|
+
label: "Video",
|
|
1979
|
+
summary: "Video annotation",
|
|
1980
|
+
icon: /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(import_components10.VideoIcon, {}),
|
|
1981
|
+
render(ctx) {
|
|
1982
|
+
return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(CreateVideoAnnotationForm, { ...ctx });
|
|
1983
|
+
},
|
|
1984
|
+
resourceType: "Annotation",
|
|
1985
|
+
resourceFields: ["id", "type", "motivation", "body", "target"],
|
|
1986
|
+
additionalTypes: ["Canvas"],
|
|
1987
|
+
supports: {
|
|
1988
|
+
initialData: true,
|
|
1989
|
+
parentTypes: ["AnnotationPage", "Manifest"],
|
|
1990
|
+
parentFields: ["items"]
|
|
1991
|
+
},
|
|
1992
|
+
staticFields: {
|
|
1993
|
+
type: "Annotation"
|
|
1994
|
+
}
|
|
1995
|
+
};
|
|
1996
|
+
|
|
1997
|
+
// src/Manifest/ManifestBrowserCreator/manifest-browser-creator.tsx
|
|
1998
|
+
var import_helpers4 = require("@iiif/helpers");
|
|
1999
|
+
var import_react9 = require("react");
|
|
2000
|
+
async function createFromManifestBrowserOutput(data, ctx) {
|
|
2001
|
+
const targetType = ctx.options.targetType;
|
|
2002
|
+
if (Array.isArray(data.output)) {
|
|
2003
|
+
throw new Error("Multiple items not yet supported");
|
|
2004
|
+
}
|
|
2005
|
+
const contentState = (0, import_helpers4.normaliseContentState)(
|
|
2006
|
+
typeof data.output === "string" ? (0, import_helpers4.parseContentState)(data.output) : data.output
|
|
2007
|
+
);
|
|
2008
|
+
const target = contentState.target[0];
|
|
2009
|
+
const previewVault = ctx.getPreviewVault();
|
|
2010
|
+
if (!target) {
|
|
2011
|
+
throw new Error("No target found in content state");
|
|
2012
|
+
}
|
|
2013
|
+
if (targetType === "Manifest") {
|
|
2014
|
+
const manifestId = target.source.id;
|
|
2015
|
+
invariant(manifestId, "Could not find Manifest ID");
|
|
2016
|
+
const manifest = await previewVault.get(manifestId);
|
|
2017
|
+
return ctx.embed({
|
|
2018
|
+
id: target.source.id,
|
|
2019
|
+
type: "Manifest",
|
|
2020
|
+
label: manifest.label
|
|
2021
|
+
});
|
|
2022
|
+
}
|
|
2023
|
+
if (targetType === "Collection") {
|
|
2024
|
+
const collectionId = target.source.id;
|
|
2025
|
+
invariant(collectionId, "Could not find Manifest ID");
|
|
2026
|
+
const collection = await previewVault.get(collectionId);
|
|
2027
|
+
return ctx.embed({
|
|
2028
|
+
id: target.source.id,
|
|
2029
|
+
type: "Collection",
|
|
2030
|
+
label: collection.label
|
|
2031
|
+
});
|
|
2032
|
+
}
|
|
2033
|
+
throw new Error("Not yet supported.");
|
|
2034
|
+
}
|
|
2035
|
+
var ManifestBrowserCreatorForm2 = (0, import_react9.lazy)(() => Promise.resolve().then(() => (init_manifest_browser_form_lazy(), manifest_browser_form_lazy_exports)));
|
|
2036
|
+
|
|
2037
|
+
// src/Manifest/ManifestBrowserCreator/index.tsx
|
|
2038
|
+
init_manifest_browser_form_lazy();
|
|
2039
|
+
var import_components11 = require("@manifest-editor/components");
|
|
2040
|
+
var import_jsx_runtime37 = require("react/jsx-runtime");
|
|
2041
|
+
var manifestBrowserCreator = {
|
|
2042
|
+
id: "@manifest-editor/manifest-browser-creator",
|
|
2043
|
+
create: createFromManifestBrowserOutput,
|
|
2044
|
+
label: "IIIF Browser",
|
|
2045
|
+
summary: "Browse IIIF Resources",
|
|
2046
|
+
icon: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(import_components11.IIIFBrowserIcon, {}),
|
|
2047
|
+
render(ctx) {
|
|
2048
|
+
return /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(ManifestBrowserCreatorForm, { ...ctx });
|
|
2049
|
+
},
|
|
2050
|
+
resourceType: "Manifest",
|
|
2051
|
+
resourceFields: ["id", "label"],
|
|
2052
|
+
additionalTypes: ["Collection"],
|
|
2053
|
+
supports: {
|
|
2054
|
+
parentTypes: ["Collection"],
|
|
2055
|
+
parentFieldMap: {
|
|
2056
|
+
Collection: ["items"]
|
|
2057
|
+
}
|
|
2058
|
+
},
|
|
2059
|
+
sideEffects: [],
|
|
2060
|
+
staticFields: {}
|
|
2061
|
+
};
|
|
2062
|
+
|
|
2063
|
+
// src/index.ts
|
|
2064
|
+
var allCreators = [
|
|
2065
|
+
// Images first.
|
|
2066
|
+
imageServiceCreator,
|
|
2067
|
+
imageServiceAnnotation,
|
|
2068
|
+
imageUrlCreator,
|
|
2069
|
+
imageUrlAnnotation,
|
|
2070
|
+
videoAnnotation,
|
|
2071
|
+
audioAnnotation,
|
|
2072
|
+
htmlBodyCreator,
|
|
2073
|
+
htmlAnnotation,
|
|
2074
|
+
youTubeBodyCreator,
|
|
2075
|
+
iiifBrowserCreator,
|
|
2076
|
+
emptyCanvas,
|
|
2077
|
+
plaintextCreator,
|
|
2078
|
+
webPageCreator,
|
|
2079
|
+
emptyAnnotationPage,
|
|
2080
|
+
noBodyAnnotation,
|
|
2081
|
+
internalCanvas
|
|
2082
|
+
];
|