cozy-iiif 0.7.1 → 0.7.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/core/image-service.d.ts +2 -2
- package/dist/index.js +148 -145
- package/dist/types.d.ts +2 -2
- package/package.json +4 -4
- package/src/core/image-service.ts +6 -5
- package/src/types.ts +2 -2
|
@@ -11,11 +11,11 @@ export declare const getStaticImagePixelSize: (url: string) => () => Promise<{
|
|
|
11
11
|
width: number;
|
|
12
12
|
height: number;
|
|
13
13
|
}>;
|
|
14
|
-
export declare const getImageURLFromService: (service: Service, width: number, height: number) => string;
|
|
14
|
+
export declare const getImageURLFromService: (service: Service, width: number, height: number, rotation?: number) => string;
|
|
15
15
|
export declare const getRegionURLFromService: (service: Service, bounds: Bounds, rotation?: number, // 0, 90, 180, 270
|
|
16
16
|
opts?: GetRegionURLOpts) => string | undefined;
|
|
17
17
|
export declare const getRegionURL: (image: CozyImageResource) => (bounds: Bounds, rotation?: number, opts?: GetRegionURLOpts) => string | undefined;
|
|
18
|
-
export declare const getImageURL: (width: number | undefined, height: number | undefined, service: Service) => (minSize?: number) => string | undefined;
|
|
18
|
+
export declare const getImageURL: (width: number | undefined, height: number | undefined, service: Service) => (minSize?: number, rotation?: number) => string | undefined;
|
|
19
19
|
export declare const getPixelSizeFromServiceUrl: (serviceUrl: string) => () => Promise<{
|
|
20
20
|
width: number;
|
|
21
21
|
height: number;
|
package/dist/index.js
CHANGED
|
@@ -119,8 +119,8 @@ var N = class F {
|
|
|
119
119
|
return t.type === "Choice" && (t.items = t.items.map((i) => this.traverseContentResource(i, t))), j(t) ? this.traverseSpecificResource(t, "ContentResource") : this.traverseType(this.traverseInlineAnnotationPages(this.traverseContentResourceLinking(t)), { parent: r }, this.traversals.contentResource);
|
|
120
120
|
}
|
|
121
121
|
traverseSpecificResource(t, r, i) {
|
|
122
|
-
let
|
|
123
|
-
return typeof t.source == "string" && (
|
|
122
|
+
let s = t.source;
|
|
123
|
+
return typeof t.source == "string" && (s = { id: t.source, type: r || "unknown" }), this.traverseType({ ...t, source: r === "Canvas" || s.type === "Canvas" ? this.traverseType(s, { parent: i }, this.traversals.canvas) : r === "ContentResource" ? this.traverseContentResource(s, { parent: i }) : this.traverseUnknown(s, { parent: i, typeHint: r }) }, { parent: i }, this.traversals.specificResource);
|
|
124
124
|
}
|
|
125
125
|
traverseRangeRanges(t) {
|
|
126
126
|
return t.items &&= t.items.map((r) => typeof r == "string" ? this.traverseCanvas({ id: r, type: "Canvas" }, t) : j(r) ? this.traverseSpecificResource(r, "Canvas", t) : r.type === "Manifest" ? this.traverseManifest(r, t) : this.traverseRange(r, t)), t;
|
|
@@ -132,18 +132,18 @@ var N = class F {
|
|
|
132
132
|
return this.traverseType(this.traverseDescriptive(this.traverseLinking(t)), { parent: r }, this.traversals.agent);
|
|
133
133
|
}
|
|
134
134
|
traverseType(t, r, i) {
|
|
135
|
-
return i.reduce((
|
|
136
|
-
let a = s
|
|
137
|
-
return a === void 0 && !this.options.allowUndefinedReturn ?
|
|
135
|
+
return i.reduce((s, n) => {
|
|
136
|
+
let a = n(s, r);
|
|
137
|
+
return a === void 0 && !this.options.allowUndefinedReturn ? s : a;
|
|
138
138
|
}, t);
|
|
139
139
|
}
|
|
140
140
|
traverseService(t, r) {
|
|
141
141
|
let i = Object.assign({}, t);
|
|
142
|
-
return i && i.service && (i.service = A(i.service).map((
|
|
142
|
+
return i && i.service && (i.service = A(i.service).map((s) => this.traverseService(s))), this.traverseType(i, { parent: r }, this.traversals.service);
|
|
143
143
|
}
|
|
144
144
|
traverseUnknown(t, { parent: r, typeHint: i } = {}) {
|
|
145
|
-
let
|
|
146
|
-
switch (
|
|
145
|
+
let s = dt(t, i);
|
|
146
|
+
switch (s) {
|
|
147
147
|
case "Collection":
|
|
148
148
|
return this.traverseCollection(t, r);
|
|
149
149
|
case "Manifest":
|
|
@@ -163,7 +163,7 @@ var N = class F {
|
|
|
163
163
|
case "Agent":
|
|
164
164
|
return this.traverseAgent(t, r);
|
|
165
165
|
default:
|
|
166
|
-
throw Error(`Unknown or unsupported resource type of ${
|
|
166
|
+
throw Error(`Unknown or unsupported resource type of ${s}`);
|
|
167
167
|
}
|
|
168
168
|
}
|
|
169
169
|
};
|
|
@@ -192,10 +192,13 @@ var zt = class et {
|
|
|
192
192
|
}
|
|
193
193
|
traverseCollectionItems(t) {
|
|
194
194
|
if (this.options.mergeMemberProperties) {
|
|
195
|
-
let r = [...(t.manifests || []).map((
|
|
196
|
-
delete t.collections, delete t.manifests, t.members =
|
|
195
|
+
let r = [...(t.manifests || []).map((n) => typeof n == "string" ? { "@id": n, "@type": "sc:Manifest" } : (n["@type"] ||= "sc:Manifest", n)), ...(t.collections || []).map((n) => typeof n == "string" ? { "@id": n, "@type": "sc:Collection" } : n), ...t.members || []], i = [], s = r.filter((n) => i.includes(n["@id"]) ? !1 : (i.push(n["@id"]), !0));
|
|
196
|
+
delete t.collections, delete t.manifests, t.members = s;
|
|
197
197
|
}
|
|
198
|
-
return t.manifests &&= t.manifests.map((r) =>
|
|
198
|
+
return t.manifests &&= t.manifests.map((r) => {
|
|
199
|
+
let i = r;
|
|
200
|
+
return typeof r == "string" && (i = { "@id": r, "@type": "sc:Manifest" }), i["@type"] ||= "sc:Manifest", this.traverseManifest(i);
|
|
201
|
+
}), t.collections &&= t.collections.map((r) => this.traverseCollection(typeof r == "string" ? { "@id": r, "@type": "sc:Collection" } : r)), t.members &&= t.members.map((r) => typeof r == "string" ? r : r["@type"] === "sc:Collection" ? this.traverseCollection(r) : r["@type"] === "sc:Manifest" ? this.traverseManifest(r) : this.traverseUnknown(r)), t;
|
|
199
202
|
}
|
|
200
203
|
traverseManifest(t) {
|
|
201
204
|
return this.traverseType(this.traverseDescriptive(this.traverseLinking(this.traverseManifestItems(t))), this.traversals.manifest);
|
|
@@ -285,17 +288,17 @@ var zt = class et {
|
|
|
285
288
|
return t.profile ? this.traverseService(t) : t;
|
|
286
289
|
}
|
|
287
290
|
traverseImageResource(t) {
|
|
288
|
-
let r = Array.isArray(t), i = Array.isArray(t) ? t : [t],
|
|
289
|
-
for (let
|
|
290
|
-
return !r && !this.options.convertPropsToArray ?
|
|
291
|
+
let r = Array.isArray(t), i = Array.isArray(t) ? t : [t], s = [];
|
|
292
|
+
for (let n of i) typeof n == "string" ? s.push(this.traverseContentResource({ "@id": n, "@type": "dctypes:Image" })) : s.push(this.traverseContentResource(n));
|
|
293
|
+
return !r && !this.options.convertPropsToArray ? s[0] : s;
|
|
291
294
|
}
|
|
292
295
|
traverseDescriptive(t) {
|
|
293
296
|
return t.thumbnail &&= this.traverseImageResource(t.thumbnail), t.logo &&= this.traverseImageResource(t.logo), t;
|
|
294
297
|
}
|
|
295
298
|
traverseOneOrMoreServices(t) {
|
|
296
|
-
let r = Array.isArray(t), i = Array.isArray(t) ? t : [t],
|
|
297
|
-
for (let
|
|
298
|
-
return !r && !this.options.convertPropsToArray ?
|
|
299
|
+
let r = Array.isArray(t), i = Array.isArray(t) ? t : [t], s = [];
|
|
300
|
+
for (let n of i) s.push(this.traverseService(n));
|
|
301
|
+
return !r && !this.options.convertPropsToArray ? s[0] : s;
|
|
299
302
|
}
|
|
300
303
|
traverseLinking(t) {
|
|
301
304
|
return t.related &&= this.traverseOneOrManyType(t.related, this.traversals.contentResource), t.rendering &&= this.traverseOneOrManyType(t.rendering, this.traversals.contentResource), t.service &&= this.traverseOneOrMoreServices(t.service), t.seeAlso &&= this.traverseOneOrManyType(t.seeAlso, this.traversals.contentResource), t.within && (typeof t.within == "string" || (t.within = this.traverseOneOrManyType(t.within, this.traversals.contentResource))), t.startCanvas && (typeof t.startCanvas == "string" ? t.startCanvas = this.traverseType({ "@id": t.startCanvas, "@type": "sc:Canvas" }, this.traversals.canvas) : t.startCanvas && this.traverseType(t.startCanvas, this.traversals.canvas)), t.contentLayer && (typeof t.contentLayer == "string" ? t.contentLayer = this.traverseLayer({ "@id": t.contentLayer, "@type": "sc:Layer" }) : t.contentLayer = this.traverseLayer(t.contentLayer)), t;
|
|
@@ -306,9 +309,9 @@ var zt = class et {
|
|
|
306
309
|
return t.map((i) => this.traverseType(i, r));
|
|
307
310
|
}
|
|
308
311
|
traverseType(t, r) {
|
|
309
|
-
return r.reduce((i,
|
|
310
|
-
let
|
|
311
|
-
return
|
|
312
|
+
return r.reduce((i, s) => {
|
|
313
|
+
let n = s(i);
|
|
314
|
+
return n === void 0 && !this.options.allowUndefinedReturn ? i : n;
|
|
312
315
|
}, t);
|
|
313
316
|
}
|
|
314
317
|
};
|
|
@@ -329,17 +332,17 @@ function Ft(e) {
|
|
|
329
332
|
function I(e, t = "none") {
|
|
330
333
|
if (!e) return { none: [""] };
|
|
331
334
|
let r = Ft(e), i = {};
|
|
332
|
-
for (let
|
|
333
|
-
if (typeof
|
|
334
|
-
i[t] = i[t] ? i[t] : [], i[t].push(
|
|
335
|
+
for (let s of r) {
|
|
336
|
+
if (typeof s == "string") {
|
|
337
|
+
i[t] = i[t] ? i[t] : [], i[t].push(s || "");
|
|
335
338
|
continue;
|
|
336
339
|
}
|
|
337
|
-
if (!
|
|
338
|
-
i[t] = i[t] ? i[t] : [], i[t].push(
|
|
340
|
+
if (!s["@language"]) {
|
|
341
|
+
i[t] = i[t] ? i[t] : [], i[t].push(s["@value"] || "");
|
|
339
342
|
continue;
|
|
340
343
|
}
|
|
341
|
-
let
|
|
342
|
-
i[
|
|
344
|
+
let n = s["@language"];
|
|
345
|
+
i[n] = i[n] ? i[n] : [], i[n].push(s["@value"] || "");
|
|
343
346
|
}
|
|
344
347
|
return Object.keys(i).length === 0 ? { none: [""] } : i;
|
|
345
348
|
}
|
|
@@ -398,14 +401,14 @@ function V(e) {
|
|
|
398
401
|
}
|
|
399
402
|
const Jt = ["Collection", "Manifest", "Annotation", "AnnotationPage", "Range", "Service"];
|
|
400
403
|
function E(e) {
|
|
401
|
-
let t = e["@id"] || e.id, r = e["@type"] || e.type, i = e.profile || void 0,
|
|
404
|
+
let t = e["@id"] || e.id, r = e["@type"] || e.type, i = e.profile || void 0, s = e["@context"] || void 0;
|
|
402
405
|
if (i) {
|
|
403
|
-
let
|
|
404
|
-
if (
|
|
406
|
+
let n = Ht(i);
|
|
407
|
+
if (n) return n;
|
|
405
408
|
}
|
|
406
|
-
if (
|
|
407
|
-
let
|
|
408
|
-
if (
|
|
409
|
+
if (s) {
|
|
410
|
+
let n = Wt(s);
|
|
411
|
+
if (n) return n;
|
|
409
412
|
}
|
|
410
413
|
if (r) {
|
|
411
414
|
if (Array.isArray(r)) {
|
|
@@ -413,8 +416,8 @@ function E(e) {
|
|
|
413
416
|
if (r.indexOf("cnt:ContentAsText") !== -1) return "TextualBody";
|
|
414
417
|
r = r[0];
|
|
415
418
|
}
|
|
416
|
-
for (let
|
|
417
|
-
r = r.slice(
|
|
419
|
+
for (let n of ["sc", "oa", "dcterms", "dctypes", "iiif"]) if (r.startsWith(`${n}:`)) {
|
|
420
|
+
r = r.slice(n.length + 1);
|
|
418
421
|
break;
|
|
419
422
|
}
|
|
420
423
|
switch (r) {
|
|
@@ -440,16 +443,16 @@ function Kt(e) {
|
|
|
440
443
|
return t ? t[0] : e;
|
|
441
444
|
}
|
|
442
445
|
function Xt(e, t = "Rights/License", r = "none") {
|
|
443
|
-
let i = null,
|
|
444
|
-
for (let a of
|
|
445
|
-
let
|
|
446
|
-
if (
|
|
447
|
-
i =
|
|
446
|
+
let i = null, s = [], n = Array.isArray(e) ? e : [e];
|
|
447
|
+
for (let a of n) {
|
|
448
|
+
let l = a ? Kt(a) : void 0;
|
|
449
|
+
if (l && (l.indexOf("creativecommons.org") !== -1 || l.indexOf("rightsstatements.org") !== -1)) {
|
|
450
|
+
i = l.startsWith("https://") ? `http://${l.slice(8)}` : l;
|
|
448
451
|
continue;
|
|
449
452
|
}
|
|
450
|
-
|
|
453
|
+
l && s.push({ label: { [r]: [t] }, value: { [r]: [l] } });
|
|
451
454
|
}
|
|
452
|
-
return [i,
|
|
455
|
+
return [i, s];
|
|
453
456
|
}
|
|
454
457
|
const Yt = ["http://iiif.io/api/presentation/2/context.json", "http://iiif.io/api/image/2/context.json", "http://iiif.io/api/image/1/context.json", "http://library.stanford.edu/iiif/image-api/1.1/context.json", "http://iiif.io/api/search/1/context.json", "http://iiif.io/api/search/0/context.json", "http://iiif.io/api/auth/1/context.json", "http://iiif.io/api/auth/0/context.json", "http://iiif.io/api/annex/openannotation/context.json"];
|
|
455
458
|
function Qt(e) {
|
|
@@ -525,10 +528,10 @@ function se(e) {
|
|
|
525
528
|
return y({ ...C(e), ...b(e), ...S(e), ...ie(e), items: ne(e.members) });
|
|
526
529
|
}
|
|
527
530
|
function ae(e) {
|
|
528
|
-
let t = [], r = [], i,
|
|
529
|
-
for (let a of e.sequences || []) a.canvases.length && t.push(...a.canvases), a.behavior && r.push(...a.behavior), a.viewingDirection && (
|
|
530
|
-
let
|
|
531
|
-
return r.length && (
|
|
531
|
+
let t = [], r = [], i, s;
|
|
532
|
+
for (let a of e.sequences || []) a.canvases.length && t.push(...a.canvases), a.behavior && r.push(...a.behavior), a.viewingDirection && (s = a.viewingDirection), a.startCanvas && (i = a.startCanvas);
|
|
533
|
+
let n = C(e);
|
|
534
|
+
return r.length && (n.behavior ? n.behavior.push(...r) : n.behavior = r), y({ ...n, ...b(e), ...S(e), viewingDirection: s, start: i, items: t, structures: oe(e.structures) });
|
|
532
535
|
}
|
|
533
536
|
function oe(e) {
|
|
534
537
|
if (!e) return e;
|
|
@@ -536,8 +539,8 @@ function oe(e) {
|
|
|
536
539
|
for (let i of e) t.set(i.id, i);
|
|
537
540
|
let r = [];
|
|
538
541
|
for (let i of e) if (i.items) {
|
|
539
|
-
let
|
|
540
|
-
i.items =
|
|
542
|
+
let s = i.items.map((n) => typeof n == "string" ? (r.push(n), t.get(n) || n) : n && n.id ? (r.push(n.id), t.get(n.id) || n) : n);
|
|
543
|
+
i.items = s;
|
|
541
544
|
}
|
|
542
545
|
return e.filter((i) => r.indexOf(i.id) === -1);
|
|
543
546
|
}
|
|
@@ -583,8 +586,8 @@ function he(e) {
|
|
|
583
586
|
return y({ ...C(e), ...b(e), ...S(e), items: e.members });
|
|
584
587
|
}
|
|
585
588
|
function fe(e) {
|
|
586
|
-
let { "@id": t, "@type": r, "@context": i, profile:
|
|
587
|
-
return t && (a["@id"] = t), a["@type"] = E(e), a["@type"] === "unknown" && (i && i.length && (a["@context"] = i), a["@type"] = "Service"),
|
|
589
|
+
let { "@id": t, "@type": r, "@context": i, profile: s, ...n } = e, a = {};
|
|
590
|
+
return t && (a["@id"] = t), a["@type"] = E(e), a["@type"] === "unknown" && (i && i.length && (a["@context"] = i), a["@type"] = "Service"), s && (a.profile = rt(s)), y({ ...a, ...n });
|
|
588
591
|
}
|
|
589
592
|
function ge(e) {
|
|
590
593
|
return y({ ...C(e), ...b(e), ...S(e) });
|
|
@@ -600,85 +603,85 @@ function O(e) {
|
|
|
600
603
|
if (e["@type"] == "iiif:ImageApiSelector") return { type: "ImageApiSelector", region: "region" in e ? e.region : void 0, rotation: "rotation" in e ? e.rotation : void 0 };
|
|
601
604
|
throw Error(`Unsupported selector type: ${e["@type"]}`);
|
|
602
605
|
}
|
|
603
|
-
const at = (e) => e.endsWith("/info.json") ? e : `${e.endsWith("/") ? e : `${e}/`}info.json`, ot = (e) => d(e, "type")
|
|
606
|
+
const at = (e) => e.endsWith("/info.json") ? e : `${e.endsWith("/") ? e : `${e}/`}info.json`, ot = (e) => d(e, "type")?.startsWith("ImageService") || e.profile?.toString().includes("iiif.io/api/image/"), ct = (e) => {
|
|
604
607
|
const t = d(e, "type"), r = d(e, "context");
|
|
605
608
|
if (t === "ImageService2" || r?.includes("image/2")) {
|
|
606
|
-
const
|
|
607
|
-
return { majorVersion: 2, profileLevel: (Array.isArray(
|
|
609
|
+
const s = d(e, "profile"), n = ["level0", "level1", "level2"];
|
|
610
|
+
return { majorVersion: 2, profileLevel: (Array.isArray(s) ? s : s ? [s] : []).map((c) => n.findIndex((o) => c.toString().includes(o))).filter((c) => c > -1).sort((c, o) => o - c)[0] };
|
|
608
611
|
} else if (t || r)
|
|
609
612
|
return { majorVersion: 3, profileLevel: parseInt(e.profile) };
|
|
610
613
|
}, lt = (e) => () => {
|
|
611
614
|
const t = typeof window < "u";
|
|
612
615
|
return fetch(e).then((r) => r.blob()).then((r) => t ? createImageBitmap(r).then((i) => {
|
|
613
|
-
const { width:
|
|
614
|
-
return i.close(), { width:
|
|
616
|
+
const { width: s, height: n } = i;
|
|
617
|
+
return i.close(), { width: s, height: n };
|
|
615
618
|
}) : r.arrayBuffer().then((i) => ft(new Uint8Array(i))));
|
|
616
|
-
}, D = (e, t, r) => {
|
|
617
|
-
const
|
|
619
|
+
}, D = (e, t, r, i = 0) => {
|
|
620
|
+
const s = d(e, "id"), n = e.profile || "";
|
|
618
621
|
if (typeof n == "string" && (n.includes("level0") || n.includes("level:0"))) {
|
|
619
622
|
if ("sizes" in e && Array.isArray(e.sizes)) {
|
|
620
|
-
const
|
|
621
|
-
if (
|
|
622
|
-
return `${
|
|
623
|
+
const l = e.sizes.sort((c, o) => o.width * o.height - c.width * c.height).filter((c) => c.width * c.height >= t * r)[0];
|
|
624
|
+
if (l)
|
|
625
|
+
return `${s}/full/${l.width},${l.height}/0/default.jpg`;
|
|
623
626
|
}
|
|
624
|
-
return `${
|
|
627
|
+
return `${s}/full/full/0/default.jpg`;
|
|
625
628
|
}
|
|
626
|
-
return `${
|
|
629
|
+
return `${s}/full/!${t},${r}/${i}/default.jpg`;
|
|
627
630
|
}, de = (e, t, r = 0, i = { minSize: 400 }) => {
|
|
628
|
-
const
|
|
629
|
-
if (typeof
|
|
630
|
-
console.warn(`Level 0 image service does not support custom region URLs: ${
|
|
631
|
+
const s = d(e, "id"), n = e.profile || "";
|
|
632
|
+
if (typeof n == "string" && (n.includes("level0") || n.includes("level:0"))) {
|
|
633
|
+
console.warn(`Level 0 image service does not support custom region URLs: ${s}`);
|
|
631
634
|
return;
|
|
632
635
|
}
|
|
633
|
-
const { x:
|
|
634
|
-
return `${
|
|
636
|
+
const { x: l, y: c, w: o, h: v } = t, { minSize: u = 400, maxSize: f } = i, p = u / Math.min(o, v), g = f ? Math.max(p, f / Math.max(o, v)) : p, w = Math.round(o * g), h = Math.round(v * g), R = (r % 360 + 360) % 360, m = `${Math.round(l)},${Math.round(c)},${Math.round(o)},${Math.round(v)}`;
|
|
637
|
+
return `${s}/${m}/!${w},${h}/${R}/default.jpg`;
|
|
635
638
|
}, pt = (e) => (t, r = 0, i = { minSize: 400 }) => {
|
|
636
639
|
if (e.type === "dynamic")
|
|
637
640
|
return de(e.service, t, r, i);
|
|
638
641
|
console.error("Level 0 or static image canvas: unsupported");
|
|
639
|
-
}, vt = (e, t, r) => (i = 800) => {
|
|
642
|
+
}, vt = (e, t, r) => (i = 800, s = 0) => {
|
|
640
643
|
if (!e || !t) return;
|
|
641
|
-
const n = e / t,
|
|
642
|
-
return D(r, c,
|
|
644
|
+
const n = e / t, a = n < 1, l = Math.ceil(a ? i / n : i), c = Math.ceil(a ? i : i / n);
|
|
645
|
+
return D(r, c, l, s);
|
|
643
646
|
}, ut = (e) => () => fetch(e).then((t) => t.json()).then((t) => {
|
|
644
647
|
const r = t.width, i = t.height;
|
|
645
648
|
return r !== void 0 && i !== void 0 ? { width: r, height: i } : void 0;
|
|
646
649
|
}), ye = (e, t = []) => (r = 400) => {
|
|
647
|
-
const { width: i, height:
|
|
648
|
-
if (!i || !
|
|
649
|
-
const
|
|
650
|
+
const { width: i, height: s } = e;
|
|
651
|
+
if (!i || !s) return;
|
|
652
|
+
const n = i / s, a = n < 1, l = Math.ceil(a ? r / n : r), c = Math.ceil(a ? r : r / n);
|
|
650
653
|
if (e.thumbnail && e.thumbnail.length > 0) {
|
|
651
654
|
const o = e.thumbnail[0];
|
|
652
655
|
if ("service" in o && Array.isArray(o.service)) {
|
|
653
656
|
const v = o.service.find((u) => ot(u));
|
|
654
657
|
if (v)
|
|
655
|
-
return D(v,
|
|
658
|
+
return D(v, c, l);
|
|
656
659
|
}
|
|
657
660
|
if ("id" in o) return o.id;
|
|
658
661
|
}
|
|
659
662
|
for (const o of t) {
|
|
660
663
|
if (o.type === "dynamic" || o.type === "level0")
|
|
661
|
-
return D(o.service,
|
|
664
|
+
return D(o.service, c, l);
|
|
662
665
|
if (o.type === "static")
|
|
663
666
|
return o.url;
|
|
664
667
|
}
|
|
665
668
|
}, Ae = (e) => {
|
|
666
|
-
const { format: t, height: r, width: i } = e,
|
|
667
|
-
if (
|
|
668
|
-
const
|
|
669
|
+
const { format: t, height: r, width: i } = e, s = d(e, "id"), n = (e.service || []).find(ot), a = n ? ct(n) : void 0;
|
|
670
|
+
if (n && a) {
|
|
671
|
+
const l = at(d(n, "id")), c = {
|
|
669
672
|
source: e,
|
|
670
673
|
type: a.profileLevel === 0 ? "level0" : "dynamic",
|
|
671
|
-
service:
|
|
674
|
+
service: n,
|
|
672
675
|
width: i,
|
|
673
676
|
height: r,
|
|
674
677
|
majorVersion: a.majorVersion,
|
|
675
|
-
serviceUrl:
|
|
676
|
-
getImageURL: vt(i, r,
|
|
677
|
-
getPixelSize: ut(
|
|
678
|
+
serviceUrl: l,
|
|
679
|
+
getImageURL: vt(i, r, n),
|
|
680
|
+
getPixelSize: ut(l)
|
|
678
681
|
};
|
|
679
|
-
return a.profileLevel === 0 ?
|
|
680
|
-
...
|
|
681
|
-
getRegionURL: pt(
|
|
682
|
+
return a.profileLevel === 0 ? c : {
|
|
683
|
+
...c,
|
|
684
|
+
getRegionURL: pt(c)
|
|
682
685
|
};
|
|
683
686
|
} else
|
|
684
687
|
return {
|
|
@@ -686,18 +689,18 @@ const at = (e) => e.endsWith("/info.json") ? e : `${e.endsWith("/") ? e : `${e}/
|
|
|
686
689
|
type: "static",
|
|
687
690
|
width: i,
|
|
688
691
|
height: r,
|
|
689
|
-
url:
|
|
692
|
+
url: s,
|
|
690
693
|
format: t,
|
|
691
|
-
getImageURL: () =>
|
|
692
|
-
getPixelSize: lt(
|
|
694
|
+
getImageURL: () => s,
|
|
695
|
+
getPixelSize: lt(s)
|
|
693
696
|
};
|
|
694
697
|
}, Ce = (e) => {
|
|
695
698
|
const t = [];
|
|
696
699
|
return new N({
|
|
697
700
|
annotation: [(i) => {
|
|
698
701
|
if (i.motivation === "painting" || !i.motivation) {
|
|
699
|
-
const
|
|
700
|
-
t.push(...
|
|
702
|
+
const n = (i.body ? Array.isArray(i.body) ? i.body : [i.body] : []).filter((a) => a.type === "Image");
|
|
703
|
+
t.push(...n.map((a) => Ae(a)));
|
|
701
704
|
}
|
|
702
705
|
}]
|
|
703
706
|
}).traverseCanvas(e), t;
|
|
@@ -733,7 +736,7 @@ const at = (e) => e.endsWith("/info.json") ? e : `${e.endsWith("/") ? e : `${e}/
|
|
|
733
736
|
f.children.push(R), t.set(R.id, R);
|
|
734
737
|
}
|
|
735
738
|
});
|
|
736
|
-
const
|
|
739
|
+
const p = f.children.map((h) => h.type === "canvas" ? h.source : h.children.length === 1 && h.children[0].type === "canvas" ? h.children[0].source : h.source), g = p.filter((h) => h.source.type === "Canvas"), w = p.filter((h) => h.source.type === "Range");
|
|
737
740
|
return f.navItems.push(...g), f.navSections.push(...w), t.set(f.id, f), f;
|
|
738
741
|
};
|
|
739
742
|
return { root: e.filter((o) => o.source.behavior?.includes("top")).map((o) => r(o, void 0)), enumerateNodes: (o) => {
|
|
@@ -742,7 +745,7 @@ const at = (e) => e.endsWith("/info.json") ? e : `${e.endsWith("/") ? e : `${e}/
|
|
|
742
745
|
}, getBreadcrumbs: (o) => {
|
|
743
746
|
const v = t.get(o);
|
|
744
747
|
if (!v) return [];
|
|
745
|
-
const u = (f,
|
|
748
|
+
const u = (f, p = []) => f.parent ? u(f.parent, [f, ...p]) : [f, ...p];
|
|
746
749
|
return u(v);
|
|
747
750
|
}, getNavParent: (o) => {
|
|
748
751
|
const v = t.get(o);
|
|
@@ -797,7 +800,7 @@ const at = (e) => e.endsWith("/info.json") ? e : `${e.endsWith("/") ? e : `${e}/
|
|
|
797
800
|
};
|
|
798
801
|
}
|
|
799
802
|
}, ht = (e, t) => {
|
|
800
|
-
const r = Array.isArray(e["@context"]) ? e["@context"].find((
|
|
803
|
+
const r = Array.isArray(e["@context"]) ? e["@context"].find((s) => s.includes("iiif.io/api/presentation") || s.includes("iiif.io/api/image") || s.includes("shared-canvas")) : e["@context"];
|
|
801
804
|
if (!r)
|
|
802
805
|
return {
|
|
803
806
|
type: "error",
|
|
@@ -812,23 +815,23 @@ const at = (e) => e.endsWith("/info.json") ? e : `${e.endsWith("/") ? e : `${e}/
|
|
|
812
815
|
message: "Missing id property"
|
|
813
816
|
};
|
|
814
817
|
if (r.includes("presentation/2") || r.includes("presentation/3") || r.includes("shared-canvas")) {
|
|
815
|
-
const
|
|
818
|
+
const s = r.includes("presentation/3") ? 3 : 2;
|
|
816
819
|
return d(e, "type").includes("Collection") ? {
|
|
817
820
|
type: "collection",
|
|
818
821
|
url: t || i,
|
|
819
|
-
resource: Le(e,
|
|
822
|
+
resource: Le(e, s)
|
|
820
823
|
} : {
|
|
821
824
|
type: "manifest",
|
|
822
825
|
url: t || i,
|
|
823
|
-
resource: Se(e,
|
|
826
|
+
resource: Se(e, s)
|
|
824
827
|
};
|
|
825
828
|
}
|
|
826
829
|
if (r.includes("image/2") || r.includes("image/3")) {
|
|
827
|
-
const
|
|
828
|
-
return
|
|
830
|
+
const s = Ie(e);
|
|
831
|
+
return s ? {
|
|
829
832
|
type: "iiif-image",
|
|
830
833
|
url: t || i,
|
|
831
|
-
resource:
|
|
834
|
+
resource: s
|
|
832
835
|
} : {
|
|
833
836
|
type: "error",
|
|
834
837
|
code: "INVALID_MANIFEST",
|
|
@@ -841,92 +844,92 @@ const at = (e) => e.endsWith("/info.json") ? e : `${e.endsWith("/") ? e : `${e}/
|
|
|
841
844
|
message: "JSON resource is not a recognized IIIF format"
|
|
842
845
|
};
|
|
843
846
|
}, Le = (e, t) => {
|
|
844
|
-
const r = (
|
|
847
|
+
const r = (n) => {
|
|
845
848
|
const a = [];
|
|
846
849
|
return new N({
|
|
847
|
-
manifest: [(
|
|
848
|
-
}).traverseCollection(
|
|
849
|
-
id:
|
|
850
|
-
type:
|
|
851
|
-
getLabel: x(
|
|
852
|
-
source:
|
|
850
|
+
manifest: [(c) => a.push(c)]
|
|
851
|
+
}).traverseCollection(n), a.map((c) => ({
|
|
852
|
+
id: c.id,
|
|
853
|
+
type: c.type,
|
|
854
|
+
getLabel: x(c),
|
|
855
|
+
source: c
|
|
853
856
|
}));
|
|
854
|
-
}, i = t === 2 ? st(e) : e,
|
|
857
|
+
}, i = t === 2 ? st(e) : e, s = r(i);
|
|
855
858
|
return {
|
|
856
859
|
source: i,
|
|
857
860
|
id: i.id,
|
|
858
861
|
majorVersion: t,
|
|
859
|
-
items:
|
|
862
|
+
items: s,
|
|
860
863
|
getLabel: x(i),
|
|
861
864
|
getMetadata: k(i)
|
|
862
865
|
};
|
|
863
866
|
}, Se = (e, t) => {
|
|
864
867
|
const r = (a) => {
|
|
865
|
-
const
|
|
868
|
+
const l = [], c = [];
|
|
866
869
|
new N({
|
|
867
|
-
canvas: [(
|
|
868
|
-
|
|
870
|
+
canvas: [(p) => {
|
|
871
|
+
p.items && l.push(p);
|
|
869
872
|
}],
|
|
870
|
-
range: [(
|
|
871
|
-
|
|
873
|
+
range: [(p) => {
|
|
874
|
+
p.type === "Range" && c.push(p);
|
|
872
875
|
}]
|
|
873
876
|
}).traverseManifest(a);
|
|
874
|
-
const v =
|
|
875
|
-
const g = Ce(
|
|
877
|
+
const v = l.map((p) => {
|
|
878
|
+
const g = Ce(p);
|
|
876
879
|
return {
|
|
877
|
-
source:
|
|
878
|
-
id:
|
|
879
|
-
width:
|
|
880
|
-
height:
|
|
880
|
+
source: p,
|
|
881
|
+
id: p.id,
|
|
882
|
+
width: p.width,
|
|
883
|
+
height: p.height,
|
|
881
884
|
images: g,
|
|
882
|
-
annotations:
|
|
885
|
+
annotations: p.annotations || [],
|
|
883
886
|
getImageURL: g.length > 0 ? g[0].getImageURL : () => {
|
|
884
887
|
},
|
|
885
|
-
getLabel: x(
|
|
886
|
-
getMetadata: k(
|
|
887
|
-
getThumbnailURL: ye(
|
|
888
|
+
getLabel: x(p),
|
|
889
|
+
getMetadata: k(p),
|
|
890
|
+
getThumbnailURL: ye(p, g)
|
|
888
891
|
};
|
|
889
|
-
}), u = (
|
|
890
|
-
const g =
|
|
892
|
+
}), u = (p) => {
|
|
893
|
+
const g = p.items || [], w = g.filter((m) => m.type === "Canvas").map((m) => v.find((M) => M.id === m.id)).filter(Boolean), h = g.filter((m) => m.type === "Range").map((m) => u(m)), R = [...w, ...h];
|
|
891
894
|
return {
|
|
892
|
-
source:
|
|
893
|
-
id:
|
|
895
|
+
source: p,
|
|
896
|
+
id: p.id,
|
|
894
897
|
// Maintain original order
|
|
895
898
|
items: g.map((m) => R.find((M) => M.id === m.id)),
|
|
896
899
|
canvases: w,
|
|
897
900
|
ranges: h,
|
|
898
|
-
getLabel: x(
|
|
901
|
+
getLabel: x(p)
|
|
899
902
|
};
|
|
900
|
-
}, f =
|
|
903
|
+
}, f = c.map((p) => u(p));
|
|
901
904
|
return { canvases: v, ranges: f };
|
|
902
|
-
}, i = t === 2 ? st(e) : e, { canvases:
|
|
905
|
+
}, i = t === 2 ? st(e) : e, { canvases: s, ranges: n } = r(i);
|
|
903
906
|
return {
|
|
904
907
|
source: i,
|
|
905
908
|
id: i.id,
|
|
906
909
|
majorVersion: t,
|
|
907
|
-
canvases:
|
|
908
|
-
structure:
|
|
910
|
+
canvases: s,
|
|
911
|
+
structure: n,
|
|
909
912
|
getLabel: x(i),
|
|
910
913
|
getMetadata: k(i),
|
|
911
|
-
getTableOfContents: be(
|
|
914
|
+
getTableOfContents: be(n)
|
|
912
915
|
};
|
|
913
916
|
}, Ie = (e) => {
|
|
914
|
-
const { width: t, height: r, format: i } = e,
|
|
915
|
-
if (
|
|
916
|
-
const a = at(d(e, "id")),
|
|
917
|
+
const { width: t, height: r, format: i } = e, s = d(e, "id"), n = ct(e);
|
|
918
|
+
if (n) {
|
|
919
|
+
const a = at(d(e, "id")), l = {
|
|
917
920
|
source: e,
|
|
918
|
-
type:
|
|
921
|
+
type: n.profileLevel === 0 ? "level0" : "dynamic",
|
|
919
922
|
service: e,
|
|
920
923
|
width: t,
|
|
921
924
|
height: r,
|
|
922
|
-
majorVersion:
|
|
925
|
+
majorVersion: n.majorVersion,
|
|
923
926
|
serviceUrl: a,
|
|
924
927
|
getImageURL: vt(t, r, e),
|
|
925
928
|
getPixelSize: ut(a)
|
|
926
929
|
};
|
|
927
|
-
return
|
|
928
|
-
...
|
|
929
|
-
getRegionURL: pt(
|
|
930
|
+
return n.profileLevel === 0 ? l : {
|
|
931
|
+
...l,
|
|
932
|
+
getRegionURL: pt(l)
|
|
930
933
|
};
|
|
931
934
|
} else
|
|
932
935
|
return {
|
|
@@ -934,10 +937,10 @@ const at = (e) => e.endsWith("/info.json") ? e : `${e.endsWith("/") ? e : `${e}/
|
|
|
934
937
|
type: "static",
|
|
935
938
|
width: t,
|
|
936
939
|
height: r,
|
|
937
|
-
url:
|
|
940
|
+
url: s,
|
|
938
941
|
format: i,
|
|
939
|
-
getImageURL: () =>
|
|
940
|
-
getPixelSize: lt(
|
|
942
|
+
getImageURL: () => s,
|
|
943
|
+
getPixelSize: lt(s)
|
|
941
944
|
};
|
|
942
945
|
}, Te = { parse: ht, parseURL: Re };
|
|
943
946
|
export {
|
package/dist/types.d.ts
CHANGED
|
@@ -61,7 +61,7 @@ export interface CozyCanvas {
|
|
|
61
61
|
readonly height: number;
|
|
62
62
|
readonly images: CozyImageResource[];
|
|
63
63
|
readonly annotations: AnnotationPage[];
|
|
64
|
-
getImageURL(minSize?: number): string;
|
|
64
|
+
getImageURL(minSize?: number, rotation?: number): string;
|
|
65
65
|
getLabel(locale?: string): string;
|
|
66
66
|
getMetadata(locale?: string): CozyMetadata[];
|
|
67
67
|
getThumbnailURL(minSize?: number): string;
|
|
@@ -95,7 +95,7 @@ interface BaseImageResource {
|
|
|
95
95
|
readonly type: 'static' | 'dynamic' | 'level0';
|
|
96
96
|
readonly width: number;
|
|
97
97
|
readonly height: number;
|
|
98
|
-
getImageURL(minSize?: number): string;
|
|
98
|
+
getImageURL(minSize?: number, rotation?: number): string;
|
|
99
99
|
getPixelSize(): Promise<{
|
|
100
100
|
width: number;
|
|
101
101
|
height: number;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cozy-iiif",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.3",
|
|
4
4
|
"description": "A developer-friendly collection of abstractions and utilities built on top of @iiif/presentation-3 and @iiif/parser",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Rainer Simon",
|
|
@@ -29,11 +29,11 @@
|
|
|
29
29
|
},
|
|
30
30
|
"devDependencies": {
|
|
31
31
|
"typescript": "^5.9.3",
|
|
32
|
-
"vite": "^7.3.
|
|
33
|
-
"vitest": "^4.
|
|
32
|
+
"vite": "^7.3.2",
|
|
33
|
+
"vitest": "^4.1.2"
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@iiif/parser": "^2.2.
|
|
36
|
+
"@iiif/parser": "^2.2.10",
|
|
37
37
|
"@iiif/presentation-3": "^2.2.3",
|
|
38
38
|
"image-size": "^2.0.2",
|
|
39
39
|
"p-throttle": "^8.1.0",
|
|
@@ -11,7 +11,7 @@ export const normalizeServiceUrl = (url: string) =>
|
|
|
11
11
|
export const isImageService = (data: any): data is ImageService => {
|
|
12
12
|
const t = getPropertyValue<string>(data, 'type');
|
|
13
13
|
|
|
14
|
-
return t
|
|
14
|
+
return t?.startsWith('ImageService') || (
|
|
15
15
|
data.profile?.toString().includes('iiif.io/api/image/')
|
|
16
16
|
);
|
|
17
17
|
}
|
|
@@ -60,7 +60,8 @@ export const getStaticImagePixelSize = (url: string) => () => {
|
|
|
60
60
|
export const getImageURLFromService = (
|
|
61
61
|
service: Service,
|
|
62
62
|
width: number,
|
|
63
|
-
height: number
|
|
63
|
+
height: number,
|
|
64
|
+
rotation: number = 0
|
|
64
65
|
): string => {
|
|
65
66
|
const id = getPropertyValue(service, 'id');
|
|
66
67
|
|
|
@@ -84,7 +85,7 @@ export const getImageURLFromService = (
|
|
|
84
85
|
return `${id}/full/full/0/default.jpg`;
|
|
85
86
|
}
|
|
86
87
|
|
|
87
|
-
return `${id}/full/!${width},${height}/
|
|
88
|
+
return `${id}/full/!${width},${height}/${rotation}/default.jpg`;
|
|
88
89
|
}
|
|
89
90
|
|
|
90
91
|
export const getRegionURLFromService = (
|
|
@@ -141,7 +142,7 @@ export const getImageURL = (
|
|
|
141
142
|
width: number | undefined,
|
|
142
143
|
height: number | undefined,
|
|
143
144
|
service: Service
|
|
144
|
-
) => (minSize = 800) => {
|
|
145
|
+
) => (minSize = 800, rotation = 0) => {
|
|
145
146
|
if (!width || !height) return;
|
|
146
147
|
|
|
147
148
|
const aspect = width / height;
|
|
@@ -150,7 +151,7 @@ export const getImageURL = (
|
|
|
150
151
|
const h = Math.ceil(isPortrait ? minSize / aspect : minSize);
|
|
151
152
|
const w = Math.ceil(isPortrait ? minSize : minSize / aspect);
|
|
152
153
|
|
|
153
|
-
return getImageURLFromService(service!, w, h);
|
|
154
|
+
return getImageURLFromService(service!, w, h, rotation);
|
|
154
155
|
}
|
|
155
156
|
|
|
156
157
|
export const getPixelSizeFromServiceUrl = (serviceUrl: string) => () =>
|
package/src/types.ts
CHANGED
|
@@ -98,7 +98,7 @@ export interface CozyCanvas {
|
|
|
98
98
|
|
|
99
99
|
readonly annotations: AnnotationPage[];
|
|
100
100
|
|
|
101
|
-
getImageURL(minSize?: number): string;
|
|
101
|
+
getImageURL(minSize?: number, rotation?: number): string;
|
|
102
102
|
|
|
103
103
|
getLabel(locale?: string): string;
|
|
104
104
|
|
|
@@ -170,7 +170,7 @@ interface BaseImageResource {
|
|
|
170
170
|
|
|
171
171
|
readonly height: number;
|
|
172
172
|
|
|
173
|
-
getImageURL(minSize?: number): string;
|
|
173
|
+
getImageURL(minSize?: number, rotation?: number): string;
|
|
174
174
|
|
|
175
175
|
getPixelSize(): Promise<{ width: number, height: number }>;
|
|
176
176
|
|