react-iiif-vault 1.0.7 → 1.0.9

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.
Files changed (65) hide show
  1. package/.build/types/canvas-panel/Viewer.d.ts +1 -1
  2. package/.build/types/canvas-panel/index.d.ts +2 -1
  3. package/.build/types/canvas-panel/render/Audio.d.ts +1 -1
  4. package/.build/types/canvas-panel/render/Canvas.d.ts +2 -2
  5. package/.build/types/canvas-panel/render/CanvasBackground.d.ts +1 -1
  6. package/.build/types/canvas-panel/render/DefaultCanvasFallback.d.ts +1 -1
  7. package/.build/types/canvas-panel/render/Image.d.ts +1 -1
  8. package/.build/types/canvas-panel/render/Model.d.ts +1 -1
  9. package/.build/types/canvas-panel/render/Video.d.ts +1 -1
  10. package/.build/types/canvas-panel/render/VideoYouTube.d.ts +1 -1
  11. package/.build/types/components/CanvasAnnotations.d.ts +10 -0
  12. package/.build/types/components/CombinedMetadata.d.ts +4 -0
  13. package/.build/types/components/Image.d.ts +15 -0
  14. package/.build/types/components/ManifestMetadata.d.ts +4 -0
  15. package/.build/types/components/Metadata.d.ts +39 -0
  16. package/.build/types/components/SequenceThumbnails.d.ts +29 -0
  17. package/.build/types/components/SingleCanvasThumbnail.d.ts +20 -0
  18. package/.build/types/context/AnnotationContext.d.ts +1 -1
  19. package/.build/types/context/AnnotationPageContext.d.ts +1 -1
  20. package/.build/types/context/CanvasContext.d.ts +1 -1
  21. package/.build/types/context/CollectionContext.d.ts +1 -1
  22. package/.build/types/context/ContextBridge.d.ts +1 -1
  23. package/.build/types/context/ManifestContext.d.ts +1 -1
  24. package/.build/types/context/MediaContext.d.ts +1 -1
  25. package/.build/types/context/RangeContext.d.ts +1 -1
  26. package/.build/types/context/ResourceContext.d.ts +2 -2
  27. package/.build/types/context/VaultContext.d.ts +1 -1
  28. package/.build/types/demo/media-controls.d.ts +1 -1
  29. package/.build/types/demo/viewer-controls.d.ts +1 -1
  30. package/.build/types/features/rendering-strategy/3d-strategy.d.ts +1 -1
  31. package/.build/types/features/rendering-strategy/image-strategy.d.ts +1 -1
  32. package/.build/types/features/rendering-strategy/resource-types.d.ts +7 -7
  33. package/.build/types/features/rendering-strategy/strategies.d.ts +5 -5
  34. package/.build/types/features/rendering-strategy/textual-content-strategy.d.ts +1 -1
  35. package/.build/types/hooks/useEventListener.d.ts +1 -1
  36. package/.build/types/hooks/useExternalResource.d.ts +1 -1
  37. package/.build/types/hooks/useImage.d.ts +10 -0
  38. package/.build/types/hooks/useLoadImageService.d.ts +1 -1
  39. package/.build/types/hooks/useRenderingStrategy.d.ts +3 -3
  40. package/.build/types/hooks/useSimpleMediaPlayer.d.ts +2 -2
  41. package/.build/types/hooks/useVirtualAnnotationPageContext.d.ts +81 -81
  42. package/.build/types/index.d.ts +8 -0
  43. package/.build/types/utility/i18n-utils.d.ts +8 -6
  44. package/.build/types/viewers/SimpleViewerContext.d.ts +2 -2
  45. package/.build/types/viewers/SimpleViewerContext.hooks.d.ts +2 -0
  46. package/.build/types/viewers/SimpleViewerContext.types.d.ts +6 -4
  47. package/dist/bundle/cjs/index.js +7 -6
  48. package/dist/bundle/cjs/index.js.map +1 -1
  49. package/dist/bundle/esm/index.mjs +2388 -1171
  50. package/dist/bundle/esm/index.mjs.map +1 -1
  51. package/dist/canvas-panel/cjs/canvas-panel.js +5 -5
  52. package/dist/canvas-panel/cjs/canvas-panel.js.map +1 -1
  53. package/dist/canvas-panel/esm/canvas-panel.mjs +581 -520
  54. package/dist/canvas-panel/esm/canvas-panel.mjs.map +1 -1
  55. package/dist/index.umd.js +78 -76
  56. package/dist/index.umd.js.map +1 -1
  57. package/dist/react17/cjs/index.js +7 -6
  58. package/dist/react17/cjs/index.js.map +1 -1
  59. package/dist/react17/esm/index.mjs +2388 -1171
  60. package/dist/react17/esm/index.mjs.map +1 -1
  61. package/dist/utils/cjs/utils.js +1 -1
  62. package/dist/utils/cjs/utils.js.map +1 -1
  63. package/dist/utils/esm/utils.mjs +108 -107
  64. package/dist/utils/esm/utils.mjs.map +1 -1
  65. package/package.json +24 -22
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const T=require("@iiif/helpers"),w=require("@atlas-viewer/iiif-image-api"),g=require("@iiif/helpers/annotation-targets");function I(e){return e.type==="SpecificResource"?[e.source,{selector:e.selector}]:[e,{selector:null}]}function m(e,t){const{selector:i,source:o}=T.expandTarget(t);if(o.id!==e.id)return[null,o];const r={type:"BoxSelector",spatial:{x:0,y:0,width:Number(e.width),height:Number(e.height)}};return[i?i.type==="TemporalSelector"?{type:"TemporalBoxSelector",temporal:i.temporal,spatial:r.spatial}:i:null,o]}const R={makeChoice:()=>{}},f={type:"unknown"},n=e=>({type:"unknown",reason:e,annotations:{pages:[]}}),y=(e,t)=>({type:"empty",width:e,height:t,annotations:{pages:[]},image:null,images:[]}),O=["model/gltf-binary"];function N(e,t){const o=t.items[0].resource;return o.format?O.indexOf(o.format)===-1?n(`3D format: ${o.format} is unsupported`):{type:"3d-model",model:o}:n("Unknown format")}function k(e,t){var o;if(!e.duration)return n("No duration on canvas");if(t.items.length>1)return n("Only one audio source supported");const i=(o=t.items[0])==null?void 0:o.resource;return i?i.format?{type:"media",media:{annotationId:t.items[0].annotationId,duration:e.duration,url:i.id,type:"Sound",target:{type:"TemporalSelector",temporal:{startTime:0,endTime:e.duration}},format:i.format,selector:{type:"TemporalSelector",temporal:{startTime:0,endTime:e.duration}}},annotations:{pages:[]}}:n("Audio does not have format"):n("Unknown audio")}function B(e,t,i){const o=[];for(const r of t.items){const u=r.resource&&r.resource.type==="SpecificResource"?r.resource.source:r.resource;if(!u.id)return n("No resource Identifier");let s;if(u.service){const l=w.getImageServices(u);l[0]&&(s=i(l[0],e))}const c={type:"BoxSelector",spatial:{x:0,y:0,width:Number(e.width),height:Number(e.height)}},[a,S]=m(e,r.target);if(S.id!==e.id)continue;r.resource.width&&r.resource.height&&(r.resource.width,r.resource.height);let d=r.resource.type==="SpecificResource"?g.expandTarget(r.resource):null;if(r.selector){const l=g.expandTarget({type:"SpecificResource",source:r.resource,selector:r.selector});l&&(d=l)}const p=d&&d.selector&&(d.selector.type==="BoxSelector"||d.selector.type==="TemporalBoxSelector")?{type:"BoxSelector",spatial:{x:d.selector.spatial.x,y:d.selector.spatial.y,width:d.selector.spatial.width,height:d.selector.spatial.height}}:void 0;s&&!s.id&&(s.id=s["@id"]);const x={id:u.id,type:"Image",annotationId:r.annotationId,width:Number(a||p?u.width:e.width),height:Number(a||p?u.height:e.height),service:s,sizes:s&&s.sizes?s.sizes:u.width&&u.height?[{width:u.width,height:u.height}]:[],target:a&&a.type!=="PointSelector"?a:c,selector:p};o.push(x)}return{type:"images",image:o[0],images:o,choice:t.choice}}function h(e,t={},i){const o=e.language||i||"none";switch(e.type){case"TextualBody":{typeof e.value<"u"&&(t[o]=e.value);break}case"List":case"Composite":case"Choice":e.items&&e.items.forEach(r=>h(r,t,o))}return t}function v(e,t){const i=[];return t.items.forEach(o=>{if(o.resource){const[r]=m(e,o.target);i.push({annotationId:o.annotationId,text:h(o.resource),target:r})}}),{type:"textual-content",items:i}}const C=/^.*(?:(?:youtu\.be\/|v\/|vi\/|u\/\w\/|embed\/|shorts\/)|(?:(?:watch)?\?vi?=|&vi?=))([^#&?]*).*/;function b(e,t){var s;const i=t.items.filter(c=>c.type==="video");if(!e.duration)return n("No duration on canvas");if(i.length>1)return n("Only one video source supported");const o=(s=i[0])==null?void 0:s.resource,r=!!(o.service||[]).find(c=>(c.profile||"").includes("youtube.com"));if(!o)return n("Unknown video");if((!o.format||o.format==="text/html")&&!r)return n("Video does not have format");const u={annotationId:t.items[0].annotationId,duration:e.duration,url:o.id,type:"Video",items:[],target:{type:"TemporalSelector",temporal:{startTime:0,endTime:e.duration}},format:o.format,selector:{type:"TemporalSelector",temporal:{startTime:0,endTime:e.duration}}};if(r){u.type="VideoYouTube";const c=o.id.match(C);if(!c[1])return n("Video is not known youtube video");u.youTubeId=c[1]}return{type:"media",media:u,annotations:{pages:[]}}}function A({canvas:e,paintables:t,supports:i,loadImageService:o}){if(!e)return console.log("No canvas"),f;if(t.types.length===0)return i.indexOf("empty")!==-1?y(e.width,e.height):(console.log("No paintables"),f);if(t.types.length!==1)if(t.types.length===2&&t.types.indexOf("text")!==-1)t.types=t.types.filter(u=>u!=="text");else return i.indexOf("complex-timeline")===-1?n("Complex timeline not supported"):n("ComplexTimelineStrategy not yet supported");const r=t.types[0];return r==="image"?i.indexOf("images")===-1?n("Image not supported"):B(e,t,o):r==="Model"||r==="model"?i.indexOf("3d-model")===-1?n("3D not supported"):N(e,t):r==="textualbody"?i.indexOf("textual-content")===-1?n("Textual content not supported"):v(e,t):r==="sound"||r==="audio"?i.indexOf("media")===-1?n("Media not supported"):k(e,t):r==="video"?i.indexOf("media")===-1?n("Media not supported"):b(e,t):f}exports.emptyActions=R;exports.emptyStrategy=y;exports.getParsedTargetSelector=m;exports.getRenderingStrategy=A;exports.parseSpecificResource=I;exports.unknownResponse=f;exports.unsupportedStrategy=n;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const T=require("@iiif/helpers"),w=require("@atlas-viewer/iiif-image-api"),y=require("@iiif/helpers/annotation-targets");function I(e){return e.type==="SpecificResource"?[e.source,{selector:e.selector}]:[e,{selector:null}]}function m(e,o){const{selector:r,source:i}=T.expandTarget(o);if(i.id!==e.id)return[null,i];const t={type:"BoxSelector",spatial:{x:0,y:0,width:Number(e.width),height:Number(e.height)}};return[r?r.type==="TemporalSelector"?{type:"TemporalBoxSelector",temporal:r.temporal,spatial:t.spatial}:r:null,i]}const R={makeChoice:()=>{}},f={type:"unknown"},n=e=>({type:"unknown",reason:e,annotations:{pages:[]}}),h=(e,o)=>({type:"empty",width:e,height:o,annotations:{pages:[]},image:null,images:[]}),O=["model/gltf-binary"];function k(e,o){const i=o.items[0].resource;return i.format?O.indexOf(i.format)===-1?n(`3D format: ${i.format} is unsupported`):{type:"3d-model",model:i}:n("Unknown format")}function N(e,o){var i;if(!e.duration)return n("No duration on canvas");if(o.items.length>1)return n("Only one audio source supported");const r=(i=o.items[0])==null?void 0:i.resource;return r?r.format?{type:"media",media:{annotationId:o.items[0].annotationId,duration:e.duration,url:r.id,type:"Sound",target:{type:"TemporalSelector",temporal:{startTime:0,endTime:e.duration}},format:r.format,selector:{type:"TemporalSelector",temporal:{startTime:0,endTime:e.duration}}},annotations:{pages:[]}}:n("Audio does not have format"):n("Unknown audio")}function B(e,o,r){const i=[];for(const t of o.items){const u=t.resource&&t.resource.type==="SpecificResource"?t.resource.source:t.resource;if(!u.id)return n("No resource Identifier");let s;if(u.service){const a=w.getImageServices(u);a[0]&&(s=r(a[0],e))}const l={type:"BoxSelector",spatial:{x:0,y:0,width:Number(e.width),height:Number(e.height)}},[d,g]=m(e,t.target);if(!(g.id===e.id||decodeURIComponent(g.id||"")===(e.id||"")))continue;t.resource.width&&t.resource.height&&(t.resource.width,t.resource.height);let c=t.resource.type==="SpecificResource"?y.expandTarget(t.resource):null;if(t.selector){const a=y.expandTarget({type:"SpecificResource",source:t.resource,selector:t.selector});a&&(c=a)}const p=c&&c.selector&&(c.selector.type==="BoxSelector"||c.selector.type==="TemporalBoxSelector")?{type:"BoxSelector",spatial:{x:c.selector.spatial.x,y:c.selector.spatial.y,width:c.selector.spatial.width,height:c.selector.spatial.height}}:void 0;s&&!s.id&&(s.id=s["@id"]);const x={id:u.id,type:"Image",annotationId:t.annotationId,width:Number(d||p?u.width:e.width),height:Number(d||p?u.height:e.height),service:s,sizes:s&&s.sizes?s.sizes:u.width&&u.height?[{width:u.width,height:u.height}]:[],target:d&&d.type!=="PointSelector"?d:l,selector:p};i.push(x)}return{type:"images",image:i[0],images:i,choice:o.choice}}function S(e,o={},r){const i=e.language||r||"none";switch(e.type){case"TextualBody":{typeof e.value<"u"&&(o[i]=e.value);break}case"List":case"Composite":case"Choice":e.items&&e.items.forEach(t=>S(t,o,i))}return o}function v(e,o){const r=[];return o.items.forEach(i=>{if(i.resource){const[t]=m(e,i.target);r.push({annotationId:i.annotationId,text:S(i.resource),target:t})}}),{type:"textual-content",items:r}}const C=/^.*(?:(?:youtu\.be\/|v\/|vi\/|u\/\w\/|embed\/|shorts\/)|(?:(?:watch)?\?vi?=|&vi?=))([^#&?]*).*/;function V(e,o){var l;const r=o.items.filter(d=>d.type==="video");let i=!1;if(e.duration||(i=!0),r.length>1)return n("Only one video source supported");const t=(l=r[0])==null?void 0:l.resource,u=!!(t.service||[]).find(d=>(d.profile||"").includes("youtube.com"));if(!u&&i)return n("Video does not have duration");if(!t)return n("Unknown video");if((!t.format||t.format==="text/html")&&!u)return n("Video does not have format");const s={annotationId:o.items[0].annotationId,duration:e.duration,url:t.id,type:"Video",items:[],target:{type:"TemporalSelector",temporal:{startTime:0,endTime:e.duration}},format:t.format,selector:{type:"TemporalSelector",temporal:{startTime:0,endTime:e.duration}}};if(u){s.type="VideoYouTube";const d=t.id.match(C);if(!d[1])return n("Video is not known youtube video");s.youTubeId=d[1]}return{type:"media",media:s,annotations:{pages:[]}}}function b({canvas:e,paintables:o,supports:r,loadImageService:i}){if(!e)return console.log("No canvas"),f;if(o.types.length===0)return r.indexOf("empty")!==-1?h(e.width,e.height):(console.log("No paintables"),f);if(o.types.length!==1)if(o.types.length===2&&o.types.indexOf("text")!==-1)o.types=o.types.filter(u=>u!=="text");else return r.indexOf("complex-timeline")===-1?n("Complex timeline not supported"):n("ComplexTimelineStrategy not yet supported");const t=o.types[0];return t==="image"?r.indexOf("images")===-1?n("Image not supported"):B(e,o,i):t==="Model"||t==="model"?r.indexOf("3d-model")===-1?n("3D not supported"):k(e,o):t==="textualbody"?r.indexOf("textual-content")===-1?n("Textual content not supported"):v(e,o):t==="sound"||t==="audio"?r.indexOf("media")===-1?n("Media not supported"):N(e,o):t==="video"?r.indexOf("media")===-1?n("Media not supported"):V(e,o):f}exports.emptyActions=R;exports.emptyStrategy=h;exports.getParsedTargetSelector=m;exports.getRenderingStrategy=b;exports.parseSpecificResource=I;exports.unknownResponse=f;exports.unsupportedStrategy=n;
2
2
  //# sourceMappingURL=utils.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sources":["../../../src/features/rendering-strategy/rendering-utils.ts","../../../src/features/rendering-strategy/3d-strategy.ts","../../../src/features/rendering-strategy/audio-strategy.ts","../../../src/features/rendering-strategy/image-strategy.ts","../../../src/features/rendering-strategy/textual-content-strategy.ts","../../../src/features/rendering-strategy/video-strategy.ts","../../../src/features/rendering-strategy/get-rendering-strategy.ts"],"sourcesContent":["import { ContentResource, PointSelector, W3CAnnotationTarget } from '@iiif/presentation-3';\nimport { CanvasNormalized } from '@iiif/presentation-3-normalized';\nimport { UseRenderingStrategy } from '../../hooks/useRenderingStrategy';\nimport { BoxSelector, expandTarget, SupportedTarget, TemporalBoxSelector } from '@iiif/helpers';\n\n/**\n * Parse specific resource.\n *\n * This could be expanded to support pulling out more from the specific resource.\n *\n * @param resource\n */\nexport function parseSpecificResource(resource: ContentResource) {\n if (resource.type === 'SpecificResource') {\n return [resource.source, { selector: resource.selector }];\n }\n\n return [resource, { selector: null }];\n}\n\nexport function getParsedTargetSelector(\n canvas: CanvasNormalized,\n target: W3CAnnotationTarget | W3CAnnotationTarget[]\n): [TemporalBoxSelector | BoxSelector | PointSelector | null, SupportedTarget['source']] {\n const { selector: imageTarget, source } = expandTarget(target);\n\n if (source.id !== canvas.id) {\n // Skip invalid targets.\n return [null, source];\n }\n\n // Target is where it should be painted.\n const defaultTarget: BoxSelector = {\n type: 'BoxSelector',\n spatial: {\n x: 0,\n y: 0,\n width: Number(canvas.width),\n height: Number(canvas.height),\n },\n };\n\n return [\n imageTarget\n ? imageTarget.type === 'TemporalSelector'\n ? ({\n type: 'TemporalBoxSelector',\n temporal: imageTarget.temporal,\n spatial: defaultTarget.spatial,\n } as any)\n : imageTarget\n : null,\n source,\n ];\n}\n\nexport const emptyActions = {\n makeChoice: () => {\n // no-op\n },\n};\n\nexport const unknownResponse: UseRenderingStrategy[0] = { type: 'unknown' };\n\nexport const unsupportedStrategy = (reason: string): UseRenderingStrategy[0] => {\n return { type: 'unknown', reason, annotations: { pages: [] } };\n};\n\nexport const emptyStrategy = (width: number, height: number): UseRenderingStrategy[0] => {\n return { type: 'empty', width, height, annotations: { pages: [] }, image: null, images: [] };\n};\n","import { CanvasNormalized } from '@iiif/presentation-3-normalized';\nimport { unsupportedStrategy } from './rendering-utils';\nimport { AnnotationPageDescription } from './resource-types';\nimport { ExternalWebResource } from '@iiif/presentation-3';\nimport { RenderingStrategy } from './strategies';\nimport { ChoiceDescription, Paintables } from '@iiif/helpers';\n\nexport type Single3DModelStrategy = {\n type: '3d-model';\n model: ExternalWebResource;\n choice?: ChoiceDescription; // future\n annotations?: AnnotationPageDescription; // future\n};\n\nconst supportedFormats = ['model/gltf-binary'];\n\nexport function get3dStrategy(canvas: CanvasNormalized, paintables: Paintables): RenderingStrategy {\n const first = paintables.items[0];\n const resource = first.resource as ExternalWebResource;\n\n if (!resource.format) {\n return unsupportedStrategy('Unknown format');\n }\n\n if (supportedFormats.indexOf(resource.format) === -1) {\n return unsupportedStrategy(`3D format: ${resource.format} is unsupported`);\n }\n\n return {\n type: '3d-model',\n model: resource as any,\n } as Single3DModelStrategy;\n}\n","import { CanvasNormalized } from '@iiif/presentation-3-normalized';\nimport { unsupportedStrategy } from './rendering-utils';\nimport { MediaStrategy } from './strategies';\nimport { Paintables } from '@iiif/helpers';\n\nexport function getAudioStrategy(canvas: CanvasNormalized, paintables: Paintables) {\n if (!canvas.duration) {\n return unsupportedStrategy('No duration on canvas');\n }\n\n if (paintables.items.length > 1) {\n return unsupportedStrategy('Only one audio source supported');\n }\n\n const audioResource = paintables.items[0]?.resource as any; // @todo stronger type for what this might be.\n\n if (!audioResource) {\n return unsupportedStrategy('Unknown audio');\n }\n\n if (!audioResource.format) {\n return unsupportedStrategy('Audio does not have format');\n }\n\n return {\n type: 'media',\n media: {\n annotationId: paintables.items[0].annotationId,\n duration: canvas.duration,\n url: audioResource.id,\n type: 'Sound',\n target: {\n type: 'TemporalSelector',\n temporal: {\n startTime: 0,\n endTime: canvas.duration,\n },\n },\n format: audioResource.format,\n selector: {\n type: 'TemporalSelector',\n temporal: {\n startTime: 0,\n endTime: canvas.duration,\n },\n },\n },\n annotations: {\n pages: [],\n },\n } as MediaStrategy;\n}\n","import { IIIFExternalWebResource } from '@iiif/presentation-3';\nimport { CanvasNormalized } from '@iiif/presentation-3-normalized';\nimport { ImageServiceLoaderType } from '../../hooks/useLoadImageService';\nimport { AnnotationPageDescription, ImageWithOptionalService } from './resource-types';\nimport { getImageServices } from '@atlas-viewer/iiif-image-api';\nimport { getParsedTargetSelector, unsupportedStrategy } from './rendering-utils';\nimport { expandTarget } from '@iiif/helpers/annotation-targets';\nimport { BoxSelector, ChoiceDescription, Paintables } from '@iiif/helpers';\n\nexport type SingleImageStrategy = {\n type: 'images';\n image: ImageWithOptionalService;\n images: Array<ImageWithOptionalService>;\n choice?: ChoiceDescription;\n annotations?: AnnotationPageDescription;\n};\n\nexport function getImageStrategy(\n canvas: CanvasNormalized,\n paintables: Paintables,\n loadImageService: ImageServiceLoaderType\n) {\n const imageTypes: ImageWithOptionalService[] = [];\n for (const singleImage of paintables.items) {\n // SingleImageStrategy\n const resource: IIIFExternalWebResource =\n singleImage.resource && singleImage.resource.type === 'SpecificResource'\n ? singleImage.resource.source\n : singleImage.resource;\n\n // Validation.\n if (!resource.id) {\n // @todo we could skip this?\n return unsupportedStrategy('No resource Identifier');\n }\n\n let imageService = undefined;\n if (resource.service) {\n const imageServices = getImageServices(resource as any) as any[];\n if (imageServices[0]) {\n imageService = loadImageService(imageServices[0], canvas);\n }\n }\n\n // Target is where it should be painted.\n const defaultTarget: BoxSelector = {\n type: 'BoxSelector',\n spatial: {\n x: 0,\n y: 0,\n width: Number(canvas.width),\n height: Number(canvas.height),\n },\n };\n\n const [target, source] = getParsedTargetSelector(canvas, singleImage.target);\n if (source.id !== canvas.id) {\n // Skip invalid targets.\n continue;\n }\n\n // Support for cropping before painting an annotation.\n // @todo this isn't working.\n const defaultImageSelector =\n (singleImage.resource as any).width && (singleImage.resource as any).height\n ? ({\n type: 'BoxSelector',\n spatial: {\n x: 0,\n y: 0,\n width: (singleImage.resource as any).width,\n height: (singleImage.resource as any).height,\n },\n } as BoxSelector)\n : undefined;\n\n let imageSelector = singleImage.resource.type === 'SpecificResource' ? expandTarget(singleImage.resource) : null;\n\n if (singleImage.selector) {\n const found = expandTarget({\n type: 'SpecificResource',\n source: singleImage.resource,\n selector: singleImage.selector,\n });\n\n if (found) {\n imageSelector = found;\n }\n }\n\n const selector: undefined | BoxSelector =\n imageSelector &&\n imageSelector.selector &&\n (imageSelector.selector.type === 'BoxSelector' || imageSelector.selector.type === 'TemporalBoxSelector')\n ? {\n type: 'BoxSelector',\n spatial: {\n x: imageSelector.selector.spatial.x,\n y: imageSelector.selector.spatial.y,\n width: imageSelector.selector.spatial.width,\n height: imageSelector.selector.spatial.height,\n },\n }\n : undefined;\n\n if (imageService && !imageService.id) {\n (imageService as any).id = imageService['@id'];\n }\n\n const imageType: ImageWithOptionalService = {\n id: resource.id,\n type: 'Image',\n annotationId: (singleImage as any).annotationId,\n width: Number(target || selector ? resource.width : canvas.width),\n height: Number(target || selector ? resource.height : canvas.height),\n service: imageService,\n sizes:\n imageService && imageService.sizes\n ? imageService.sizes\n : resource.width && resource.height\n ? [{ width: resource.width, height: resource.height }]\n : [],\n target: target && target.type !== 'PointSelector' ? target : defaultTarget,\n selector: selector,\n };\n\n imageTypes.push(imageType);\n }\n\n return {\n type: 'images',\n image: imageTypes[0],\n images: imageTypes,\n choice: paintables.choice,\n } as SingleImageStrategy;\n}\n","import { InternationalString } from '@iiif/presentation-3';\nimport { CanvasNormalized } from '@iiif/presentation-3-normalized';\nimport { AnnotationPageDescription } from './resource-types';\nimport { getParsedTargetSelector } from './rendering-utils';\nimport { RenderingStrategy } from './strategies';\nimport { ChoiceDescription, Paintables, SupportedTarget } from '@iiif/helpers';\n\nexport type TextualContentStrategy = {\n type: 'textual-content';\n items: { annotationId: string; text: InternationalString; target: SupportedTarget | null }[];\n choice?: ChoiceDescription; // future\n annotations?: AnnotationPageDescription; // future\n};\n\nfunction parseType(item: any, languageMap: InternationalString = {}, lang?: string) {\n const language = item.language || lang || 'none';\n switch (item.type) {\n case 'TextualBody': {\n if (typeof item.value !== 'undefined') {\n languageMap[language] = item.value;\n }\n break;\n }\n case 'List':\n case 'Composite':\n case 'Choice': {\n if (item.items) {\n item.items.forEach((inner: any) => parseType(inner, languageMap, language));\n }\n }\n }\n return languageMap;\n}\n\nexport function getTextualContentStrategy(canvas: CanvasNormalized, paintables: Paintables): RenderingStrategy {\n const items: TextualContentStrategy['items'] = [];\n\n paintables.items.forEach((item) => {\n if (item.resource) {\n const [target] = getParsedTargetSelector(canvas, item.target);\n items.push({ annotationId: item.annotationId, text: parseType(item.resource), target: target as any });\n }\n });\n\n return {\n type: 'textual-content',\n items,\n } as TextualContentStrategy;\n}\n","import { CanvasNormalized } from '@iiif/presentation-3-normalized';\nimport { unsupportedStrategy } from './rendering-utils';\nimport { MediaStrategy } from './strategies';\nimport { Paintables } from '@iiif/helpers';\n\n// https://stackoverflow.com/a/27728417\nconst ytRegex = /^.*(?:(?:youtu\\.be\\/|v\\/|vi\\/|u\\/\\w\\/|embed\\/|shorts\\/)|(?:(?:watch)?\\?vi?=|&vi?=))([^#&?]*).*/;\n\nexport function getVideoStrategy(canvas: CanvasNormalized, paintables: Paintables) {\n const videoPaintables = paintables.items.filter((t) => t.type === 'video');\n\n if (!canvas.duration) {\n return unsupportedStrategy('No duration on canvas');\n }\n\n if (videoPaintables.length > 1) {\n return unsupportedStrategy('Only one video source supported');\n }\n\n const audioResource = videoPaintables[0]?.resource as any; // @todo stronger type for what this might be.\n const isYouTube = !!(audioResource.service || []).find((service: any) =>\n (service.profile || '').includes('youtube.com')\n );\n\n if (!audioResource) {\n return unsupportedStrategy('Unknown video');\n }\n\n if (!audioResource.format || audioResource.format === 'text/html') {\n if (!isYouTube) {\n return unsupportedStrategy('Video does not have format');\n }\n }\n\n const media = {\n annotationId: (paintables.items[0] as any).annotationId,\n duration: canvas.duration,\n url: audioResource.id,\n type: 'Video',\n items: [],\n target: {\n type: 'TemporalSelector',\n temporal: {\n startTime: 0,\n endTime: canvas.duration,\n },\n },\n format: audioResource.format,\n selector: {\n type: 'TemporalSelector',\n temporal: {\n startTime: 0,\n endTime: canvas.duration,\n },\n },\n };\n\n if (isYouTube) {\n media.type = 'VideoYouTube';\n const id = audioResource.id.match(ytRegex);\n if (!id[1]) {\n return unsupportedStrategy('Video is not known youtube video');\n }\n (media as any).youTubeId = id[1];\n }\n\n // @todo support VTT\n\n return {\n type: 'media',\n media,\n annotations: {\n pages: [],\n },\n } as MediaStrategy;\n}\n","import { get3dStrategy } from './3d-strategy';\nimport { getAudioStrategy } from './audio-strategy';\nimport { getImageStrategy } from './image-strategy';\nimport { emptyStrategy, unknownResponse, unsupportedStrategy } from './rendering-utils';\nimport { getTextualContentStrategy } from './textual-content-strategy';\nimport { getVideoStrategy } from './video-strategy';\nimport type { CanvasNormalized } from '@iiif/presentation-3-normalized';\nimport type { Paintables } from '@iiif/helpers/painting-annotations';\nimport type { ImageServiceLoaderType } from '../../hooks/useLoadImageService';\n\ninterface GetRenderStrategyOptions {\n canvas: CanvasNormalized | null | undefined;\n paintables: Paintables;\n supports: string[];\n loadImageService: ImageServiceLoaderType;\n}\n\nexport function getRenderingStrategy({ canvas, paintables, supports, loadImageService }: GetRenderStrategyOptions) {\n if (!canvas) {\n console.log('No canvas');\n return unknownResponse;\n }\n\n if (paintables.types.length === 0) {\n if (supports.indexOf('empty') !== -1) {\n return emptyStrategy(canvas.width, canvas.height);\n }\n console.log('No paintables');\n return unknownResponse;\n }\n\n if (paintables.types.length !== 1) {\n if (paintables.types.length === 2 && paintables.types.indexOf('text') !== -1) {\n paintables.types = paintables.types.filter((t) => t !== 'text');\n } else {\n if (supports.indexOf('complex-timeline') === -1) {\n return unsupportedStrategy('Complex timeline not supported');\n }\n return unsupportedStrategy('ComplexTimelineStrategy not yet supported');\n }\n }\n\n const mainType = paintables.types[0];\n\n // Image\n if (mainType === 'image') {\n if (supports.indexOf('images') === -1) {\n return unsupportedStrategy('Image not supported');\n }\n\n return getImageStrategy(canvas, paintables, loadImageService);\n }\n\n // 3D\n if (mainType === 'Model' || mainType === 'model') {\n if (supports.indexOf('3d-model') === -1) {\n return unsupportedStrategy('3D not supported');\n }\n\n return get3dStrategy(canvas, paintables);\n }\n\n if (mainType === 'textualbody') {\n if (supports.indexOf('textual-content') === -1) {\n return unsupportedStrategy('Textual content not supported');\n }\n\n return getTextualContentStrategy(canvas, paintables);\n }\n\n if (mainType === 'sound' || mainType === 'audio') {\n if (supports.indexOf('media') === -1) {\n return unsupportedStrategy('Media not supported');\n }\n\n // Media Strategy with audio or audio sequence.\n return getAudioStrategy(canvas, paintables);\n }\n\n if (mainType === 'video') {\n if (supports.indexOf('media') === -1) {\n return unsupportedStrategy('Media not supported');\n }\n\n // Media Strategy with video or video sequence.\n return getVideoStrategy(canvas, paintables);\n }\n\n // Unknown fallback.\n return unknownResponse;\n}\n"],"names":["parseSpecificResource","resource","getParsedTargetSelector","canvas","target","imageTarget","source","expandTarget","defaultTarget","emptyActions","unknownResponse","unsupportedStrategy","reason","emptyStrategy","width","height","supportedFormats","get3dStrategy","paintables","getAudioStrategy","audioResource","_a","getImageStrategy","loadImageService","imageTypes","singleImage","imageService","imageServices","getImageServices","imageSelector","found","selector","imageType","parseType","item","languageMap","lang","language","inner","getTextualContentStrategy","items","ytRegex","getVideoStrategy","videoPaintables","t","isYouTube","service","media","id","getRenderingStrategy","supports","mainType"],"mappings":"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"}
1
+ {"version":3,"file":"utils.js","sources":["../../../src/features/rendering-strategy/rendering-utils.ts","../../../src/features/rendering-strategy/3d-strategy.ts","../../../src/features/rendering-strategy/audio-strategy.ts","../../../src/features/rendering-strategy/image-strategy.ts","../../../src/features/rendering-strategy/textual-content-strategy.ts","../../../src/features/rendering-strategy/video-strategy.ts","../../../src/features/rendering-strategy/get-rendering-strategy.ts"],"sourcesContent":["import { ContentResource, PointSelector, W3CAnnotationTarget } from '@iiif/presentation-3';\nimport { CanvasNormalized } from '@iiif/presentation-3-normalized';\nimport { UseRenderingStrategy } from '../../hooks/useRenderingStrategy';\nimport { BoxSelector, expandTarget, SupportedTarget, TemporalBoxSelector } from '@iiif/helpers';\n\n/**\n * Parse specific resource.\n *\n * This could be expanded to support pulling out more from the specific resource.\n *\n * @param resource\n */\nexport function parseSpecificResource(resource: ContentResource) {\n if (resource.type === 'SpecificResource') {\n return [resource.source, { selector: resource.selector }];\n }\n\n return [resource, { selector: null }];\n}\n\nexport function getParsedTargetSelector(\n canvas: CanvasNormalized,\n target: W3CAnnotationTarget | W3CAnnotationTarget[]\n): [TemporalBoxSelector | BoxSelector | PointSelector | null, SupportedTarget['source']] {\n const { selector: imageTarget, source } = expandTarget(target);\n\n if (source.id !== canvas.id) {\n // Skip invalid targets.\n return [null, source];\n }\n\n // Target is where it should be painted.\n const defaultTarget: BoxSelector = {\n type: 'BoxSelector',\n spatial: {\n x: 0,\n y: 0,\n width: Number(canvas.width),\n height: Number(canvas.height),\n },\n };\n\n return [\n imageTarget\n ? imageTarget.type === 'TemporalSelector'\n ? ({\n type: 'TemporalBoxSelector',\n temporal: imageTarget.temporal,\n spatial: defaultTarget.spatial,\n } as any)\n : imageTarget\n : null,\n source,\n ];\n}\n\nexport const emptyActions = {\n makeChoice: () => {\n // no-op\n },\n};\n\nexport const unknownResponse: UseRenderingStrategy[0] = { type: 'unknown' };\n\nexport const unsupportedStrategy = (reason: string): UseRenderingStrategy[0] => {\n return { type: 'unknown', reason, annotations: { pages: [] } };\n};\n\nexport const emptyStrategy = (width: number, height: number): UseRenderingStrategy[0] => {\n return { type: 'empty', width, height, annotations: { pages: [] }, image: null, images: [] };\n};\n","import { CanvasNormalized } from '@iiif/presentation-3-normalized';\nimport { unsupportedStrategy } from './rendering-utils';\nimport { AnnotationPageDescription } from './resource-types';\nimport { ExternalWebResource } from '@iiif/presentation-3';\nimport { RenderingStrategy } from './strategies';\nimport { ChoiceDescription, Paintables } from '@iiif/helpers';\n\nexport type Single3DModelStrategy = {\n type: '3d-model';\n model: ExternalWebResource;\n choice?: ChoiceDescription; // future\n annotations?: AnnotationPageDescription; // future\n};\n\nconst supportedFormats = ['model/gltf-binary'];\n\nexport function get3dStrategy(canvas: CanvasNormalized, paintables: Paintables): RenderingStrategy {\n const first = paintables.items[0];\n const resource = first.resource as ExternalWebResource;\n\n if (!resource.format) {\n return unsupportedStrategy('Unknown format');\n }\n\n if (supportedFormats.indexOf(resource.format) === -1) {\n return unsupportedStrategy(`3D format: ${resource.format} is unsupported`);\n }\n\n return {\n type: '3d-model',\n model: resource as any,\n } as Single3DModelStrategy;\n}\n","import { CanvasNormalized } from '@iiif/presentation-3-normalized';\nimport { unsupportedStrategy } from './rendering-utils';\nimport { MediaStrategy } from './strategies';\nimport { Paintables } from '@iiif/helpers';\n\nexport function getAudioStrategy(canvas: CanvasNormalized, paintables: Paintables) {\n if (!canvas.duration) {\n return unsupportedStrategy('No duration on canvas');\n }\n\n if (paintables.items.length > 1) {\n return unsupportedStrategy('Only one audio source supported');\n }\n\n const audioResource = paintables.items[0]?.resource as any; // @todo stronger type for what this might be.\n\n if (!audioResource) {\n return unsupportedStrategy('Unknown audio');\n }\n\n if (!audioResource.format) {\n return unsupportedStrategy('Audio does not have format');\n }\n\n return {\n type: 'media',\n media: {\n annotationId: paintables.items[0].annotationId,\n duration: canvas.duration,\n url: audioResource.id,\n type: 'Sound',\n target: {\n type: 'TemporalSelector',\n temporal: {\n startTime: 0,\n endTime: canvas.duration,\n },\n },\n format: audioResource.format,\n selector: {\n type: 'TemporalSelector',\n temporal: {\n startTime: 0,\n endTime: canvas.duration,\n },\n },\n },\n annotations: {\n pages: [],\n },\n } as MediaStrategy;\n}\n","import { IIIFExternalWebResource } from '@iiif/presentation-3';\nimport { CanvasNormalized } from '@iiif/presentation-3-normalized';\nimport { ImageServiceLoaderType } from '../../hooks/useLoadImageService';\nimport { AnnotationPageDescription, ImageWithOptionalService } from './resource-types';\nimport { getImageServices } from '@atlas-viewer/iiif-image-api';\nimport { getParsedTargetSelector, unsupportedStrategy } from './rendering-utils';\nimport { expandTarget } from '@iiif/helpers/annotation-targets';\nimport { BoxSelector, ChoiceDescription, Paintables } from '@iiif/helpers';\n\nexport type SingleImageStrategy = {\n type: 'images';\n image: ImageWithOptionalService;\n images: Array<ImageWithOptionalService>;\n choice?: ChoiceDescription;\n annotations?: AnnotationPageDescription;\n};\n\nexport function getImageStrategy(\n canvas: CanvasNormalized,\n paintables: Paintables,\n loadImageService: ImageServiceLoaderType\n) {\n const imageTypes: ImageWithOptionalService[] = [];\n for (const singleImage of paintables.items) {\n // SingleImageStrategy\n const resource: IIIFExternalWebResource =\n singleImage.resource && singleImage.resource.type === 'SpecificResource'\n ? singleImage.resource.source\n : singleImage.resource;\n\n // Validation.\n if (!resource.id) {\n // @todo we could skip this?\n return unsupportedStrategy('No resource Identifier');\n }\n\n let imageService = undefined;\n if (resource.service) {\n const imageServices = getImageServices(resource as any) as any[];\n if (imageServices[0]) {\n imageService = loadImageService(imageServices[0], canvas);\n }\n }\n\n // Target is where it should be painted.\n const defaultTarget: BoxSelector = {\n type: 'BoxSelector',\n spatial: {\n x: 0,\n y: 0,\n width: Number(canvas.width),\n height: Number(canvas.height),\n },\n };\n\n const [target, source] = getParsedTargetSelector(canvas, singleImage.target);\n if (!(source.id === canvas.id || decodeURIComponent(source.id || '') === (canvas.id || ''))) {\n // Skip invalid targets.\n continue;\n }\n\n // Support for cropping before painting an annotation.\n // @todo this isn't working.\n const defaultImageSelector =\n (singleImage.resource as any).width && (singleImage.resource as any).height\n ? ({\n type: 'BoxSelector',\n spatial: {\n x: 0,\n y: 0,\n width: (singleImage.resource as any).width,\n height: (singleImage.resource as any).height,\n },\n } as BoxSelector)\n : undefined;\n\n let imageSelector = singleImage.resource.type === 'SpecificResource' ? expandTarget(singleImage.resource) : null;\n\n if (singleImage.selector) {\n const found = expandTarget({\n type: 'SpecificResource',\n source: singleImage.resource,\n selector: singleImage.selector,\n });\n\n if (found) {\n imageSelector = found;\n }\n }\n\n const selector: undefined | BoxSelector =\n imageSelector &&\n imageSelector.selector &&\n (imageSelector.selector.type === 'BoxSelector' || imageSelector.selector.type === 'TemporalBoxSelector')\n ? {\n type: 'BoxSelector',\n spatial: {\n x: imageSelector.selector.spatial.x,\n y: imageSelector.selector.spatial.y,\n width: imageSelector.selector.spatial.width,\n height: imageSelector.selector.spatial.height,\n },\n }\n : undefined;\n\n if (imageService && !imageService.id) {\n (imageService as any).id = imageService['@id'];\n }\n\n const imageType: ImageWithOptionalService = {\n id: resource.id,\n type: 'Image',\n annotationId: (singleImage as any).annotationId,\n width: Number(target || selector ? resource.width : canvas.width),\n height: Number(target || selector ? resource.height : canvas.height),\n service: imageService,\n sizes:\n imageService && imageService.sizes\n ? imageService.sizes\n : resource.width && resource.height\n ? [{ width: resource.width, height: resource.height }]\n : [],\n target: target && target.type !== 'PointSelector' ? target : defaultTarget,\n selector: selector,\n };\n\n imageTypes.push(imageType);\n }\n\n return {\n type: 'images',\n image: imageTypes[0],\n images: imageTypes,\n choice: paintables.choice,\n } as SingleImageStrategy;\n}\n","import { InternationalString } from '@iiif/presentation-3';\nimport { CanvasNormalized } from '@iiif/presentation-3-normalized';\nimport { AnnotationPageDescription } from './resource-types';\nimport { getParsedTargetSelector } from './rendering-utils';\nimport { RenderingStrategy } from './strategies';\nimport { ChoiceDescription, Paintables, SupportedTarget } from '@iiif/helpers';\n\nexport type TextualContentStrategy = {\n type: 'textual-content';\n items: { annotationId: string; text: InternationalString; target: SupportedTarget | null }[];\n choice?: ChoiceDescription; // future\n annotations?: AnnotationPageDescription; // future\n};\n\nfunction parseType(item: any, languageMap: InternationalString = {}, lang?: string) {\n const language = item.language || lang || 'none';\n switch (item.type) {\n case 'TextualBody': {\n if (typeof item.value !== 'undefined') {\n languageMap[language] = item.value;\n }\n break;\n }\n case 'List':\n case 'Composite':\n case 'Choice': {\n if (item.items) {\n item.items.forEach((inner: any) => parseType(inner, languageMap, language));\n }\n }\n }\n return languageMap;\n}\n\nexport function getTextualContentStrategy(canvas: CanvasNormalized, paintables: Paintables): RenderingStrategy {\n const items: TextualContentStrategy['items'] = [];\n\n paintables.items.forEach((item) => {\n if (item.resource) {\n const [target] = getParsedTargetSelector(canvas, item.target);\n items.push({ annotationId: item.annotationId, text: parseType(item.resource), target: target as any });\n }\n });\n\n return {\n type: 'textual-content',\n items,\n } as TextualContentStrategy;\n}\n","import { CanvasNormalized } from '@iiif/presentation-3-normalized';\nimport { unsupportedStrategy } from './rendering-utils';\nimport { MediaStrategy } from './strategies';\nimport { Paintables } from '@iiif/helpers';\n\n// https://stackoverflow.com/a/27728417\nconst ytRegex = /^.*(?:(?:youtu\\.be\\/|v\\/|vi\\/|u\\/\\w\\/|embed\\/|shorts\\/)|(?:(?:watch)?\\?vi?=|&vi?=))([^#&?]*).*/;\n\nexport function getVideoStrategy(canvas: CanvasNormalized, paintables: Paintables) {\n const videoPaintables = paintables.items.filter((t) => t.type === 'video');\n\n let noDuration = false;\n\n if (!canvas.duration) {\n noDuration = true;\n }\n\n if (videoPaintables.length > 1) {\n return unsupportedStrategy('Only one video source supported');\n }\n\n const videoResource = videoPaintables[0]?.resource as any; // @todo stronger type for what this might be.\n const isYouTube = !!(videoResource.service || []).find((service: any) =>\n (service.profile || '').includes('youtube.com')\n );\n\n if (!isYouTube && noDuration) {\n return unsupportedStrategy('Video does not have duration');\n }\n\n if (!videoResource) {\n return unsupportedStrategy('Unknown video');\n }\n\n if (!videoResource.format || videoResource.format === 'text/html') {\n if (!isYouTube) {\n return unsupportedStrategy('Video does not have format');\n }\n }\n\n const media = {\n annotationId: (paintables.items[0] as any).annotationId,\n duration: canvas.duration,\n url: videoResource.id,\n type: 'Video',\n items: [],\n target: {\n type: 'TemporalSelector',\n temporal: {\n startTime: 0,\n endTime: canvas.duration,\n },\n },\n format: videoResource.format,\n selector: {\n type: 'TemporalSelector',\n temporal: {\n startTime: 0,\n endTime: canvas.duration,\n },\n },\n };\n\n if (isYouTube) {\n media.type = 'VideoYouTube';\n const id = videoResource.id.match(ytRegex);\n if (!id[1]) {\n return unsupportedStrategy('Video is not known youtube video');\n }\n (media as any).youTubeId = id[1];\n }\n\n // @todo support VTT\n\n return {\n type: 'media',\n media,\n annotations: {\n pages: [],\n },\n } as MediaStrategy;\n}\n","import { get3dStrategy } from './3d-strategy';\nimport { getAudioStrategy } from './audio-strategy';\nimport { getImageStrategy } from './image-strategy';\nimport { emptyStrategy, unknownResponse, unsupportedStrategy } from './rendering-utils';\nimport { getTextualContentStrategy } from './textual-content-strategy';\nimport { getVideoStrategy } from './video-strategy';\nimport type { CanvasNormalized } from '@iiif/presentation-3-normalized';\nimport type { Paintables } from '@iiif/helpers/painting-annotations';\nimport type { ImageServiceLoaderType } from '../../hooks/useLoadImageService';\n\ninterface GetRenderStrategyOptions {\n canvas: CanvasNormalized | null | undefined;\n paintables: Paintables;\n supports: string[];\n loadImageService: ImageServiceLoaderType;\n}\n\nexport function getRenderingStrategy({ canvas, paintables, supports, loadImageService }: GetRenderStrategyOptions) {\n if (!canvas) {\n console.log('No canvas');\n return unknownResponse;\n }\n\n if (paintables.types.length === 0) {\n if (supports.indexOf('empty') !== -1) {\n return emptyStrategy(canvas.width, canvas.height);\n }\n console.log('No paintables');\n return unknownResponse;\n }\n\n if (paintables.types.length !== 1) {\n if (paintables.types.length === 2 && paintables.types.indexOf('text') !== -1) {\n paintables.types = paintables.types.filter((t) => t !== 'text');\n } else {\n if (supports.indexOf('complex-timeline') === -1) {\n return unsupportedStrategy('Complex timeline not supported');\n }\n return unsupportedStrategy('ComplexTimelineStrategy not yet supported');\n }\n }\n\n const mainType = paintables.types[0];\n\n // Image\n if (mainType === 'image') {\n if (supports.indexOf('images') === -1) {\n return unsupportedStrategy('Image not supported');\n }\n\n return getImageStrategy(canvas, paintables, loadImageService);\n }\n\n // 3D\n if (mainType === 'Model' || mainType === 'model') {\n if (supports.indexOf('3d-model') === -1) {\n return unsupportedStrategy('3D not supported');\n }\n\n return get3dStrategy(canvas, paintables);\n }\n\n if (mainType === 'textualbody') {\n if (supports.indexOf('textual-content') === -1) {\n return unsupportedStrategy('Textual content not supported');\n }\n\n return getTextualContentStrategy(canvas, paintables);\n }\n\n if (mainType === 'sound' || mainType === 'audio') {\n if (supports.indexOf('media') === -1) {\n return unsupportedStrategy('Media not supported');\n }\n\n // Media Strategy with audio or audio sequence.\n return getAudioStrategy(canvas, paintables);\n }\n\n if (mainType === 'video') {\n if (supports.indexOf('media') === -1) {\n return unsupportedStrategy('Media not supported');\n }\n\n // Media Strategy with video or video sequence.\n return getVideoStrategy(canvas, paintables);\n }\n\n // Unknown fallback.\n return unknownResponse;\n}\n"],"names":["parseSpecificResource","resource","getParsedTargetSelector","canvas","target","imageTarget","source","expandTarget","defaultTarget","emptyActions","unknownResponse","unsupportedStrategy","reason","emptyStrategy","width","height","supportedFormats","get3dStrategy","paintables","getAudioStrategy","audioResource","_a","getImageStrategy","loadImageService","imageTypes","singleImage","imageService","imageServices","getImageServices","imageSelector","found","selector","imageType","parseType","item","languageMap","lang","language","inner","getTextualContentStrategy","items","ytRegex","getVideoStrategy","videoPaintables","t","noDuration","videoResource","isYouTube","service","media","id","getRenderingStrategy","supports","mainType"],"mappings":"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"}
@@ -1,14 +1,14 @@
1
1
  import { expandTarget as S } from "@iiif/helpers";
2
2
  import { getImageServices as T } from "@atlas-viewer/iiif-image-api";
3
- import { expandTarget as p } from "@iiif/helpers/annotation-targets";
4
- function z(e) {
3
+ import { expandTarget as g } from "@iiif/helpers/annotation-targets";
4
+ function b(e) {
5
5
  return e.type === "SpecificResource" ? [e.source, { selector: e.selector }] : [e, { selector: null }];
6
6
  }
7
- function g(e, t) {
8
- const { selector: i, source: o } = S(t);
9
- if (o.id !== e.id)
10
- return [null, o];
11
- const r = {
7
+ function y(e, o) {
8
+ const { selector: r, source: i } = S(o);
9
+ if (i.id !== e.id)
10
+ return [null, i];
11
+ const t = {
12
12
  type: "BoxSelector",
13
13
  spatial: {
14
14
  x: 0,
@@ -18,38 +18,38 @@ function g(e, t) {
18
18
  }
19
19
  };
20
20
  return [
21
- i ? i.type === "TemporalSelector" ? {
21
+ r ? r.type === "TemporalSelector" ? {
22
22
  type: "TemporalBoxSelector",
23
- temporal: i.temporal,
24
- spatial: r.spatial
25
- } : i : null,
26
- o
23
+ temporal: r.temporal,
24
+ spatial: t.spatial
25
+ } : r : null,
26
+ i
27
27
  ];
28
28
  }
29
- const A = {
29
+ const z = {
30
30
  makeChoice: () => {
31
31
  }
32
- }, l = { type: "unknown" }, n = (e) => ({ type: "unknown", reason: e, annotations: { pages: [] } }), w = (e, t) => ({ type: "empty", width: e, height: t, annotations: { pages: [] }, image: null, images: [] }), I = ["model/gltf-binary"];
33
- function N(e, t) {
34
- const o = t.items[0].resource;
35
- return o.format ? I.indexOf(o.format) === -1 ? n(`3D format: ${o.format} is unsupported`) : {
32
+ }, m = { type: "unknown" }, n = (e) => ({ type: "unknown", reason: e, annotations: { pages: [] } }), w = (e, o) => ({ type: "empty", width: e, height: o, annotations: { pages: [] }, image: null, images: [] }), I = ["model/gltf-binary"];
33
+ function O(e, o) {
34
+ const i = o.items[0].resource;
35
+ return i.format ? I.indexOf(i.format) === -1 ? n(`3D format: ${i.format} is unsupported`) : {
36
36
  type: "3d-model",
37
- model: o
37
+ model: i
38
38
  } : n("Unknown format");
39
39
  }
40
- function O(e, t) {
41
- var o;
40
+ function R(e, o) {
41
+ var i;
42
42
  if (!e.duration)
43
43
  return n("No duration on canvas");
44
- if (t.items.length > 1)
44
+ if (o.items.length > 1)
45
45
  return n("Only one audio source supported");
46
- const i = (o = t.items[0]) == null ? void 0 : o.resource;
47
- return i ? i.format ? {
46
+ const r = (i = o.items[0]) == null ? void 0 : i.resource;
47
+ return r ? r.format ? {
48
48
  type: "media",
49
49
  media: {
50
- annotationId: t.items[0].annotationId,
50
+ annotationId: o.items[0].annotationId,
51
51
  duration: e.duration,
52
- url: i.id,
52
+ url: r.id,
53
53
  type: "Sound",
54
54
  target: {
55
55
  type: "TemporalSelector",
@@ -58,7 +58,7 @@ function O(e, t) {
58
58
  endTime: e.duration
59
59
  }
60
60
  },
61
- format: i.format,
61
+ format: r.format,
62
62
  selector: {
63
63
  type: "TemporalSelector",
64
64
  temporal: {
@@ -72,18 +72,18 @@ function O(e, t) {
72
72
  }
73
73
  } : n("Audio does not have format") : n("Unknown audio");
74
74
  }
75
- function R(e, t, i) {
76
- const o = [];
77
- for (const r of t.items) {
78
- const u = r.resource && r.resource.type === "SpecificResource" ? r.resource.source : r.resource;
75
+ function N(e, o, r) {
76
+ const i = [];
77
+ for (const t of o.items) {
78
+ const u = t.resource && t.resource.type === "SpecificResource" ? t.resource.source : t.resource;
79
79
  if (!u.id)
80
80
  return n("No resource Identifier");
81
- let s;
81
+ let d;
82
82
  if (u.service) {
83
- const f = T(u);
84
- f[0] && (s = i(f[0], e));
83
+ const a = T(u);
84
+ a[0] && (d = r(a[0], e));
85
85
  }
86
- const c = {
86
+ const f = {
87
87
  type: "BoxSelector",
88
88
  spatial: {
89
89
  x: 0,
@@ -91,94 +91,95 @@ function R(e, t, i) {
91
91
  width: Number(e.width),
92
92
  height: Number(e.height)
93
93
  }
94
- }, [a, h] = g(e, r.target);
95
- if (h.id !== e.id)
94
+ }, [s, p] = y(e, t.target);
95
+ if (!(p.id === e.id || decodeURIComponent(p.id || "") === (e.id || "")))
96
96
  continue;
97
- r.resource.width && r.resource.height && (r.resource.width, r.resource.height);
98
- let d = r.resource.type === "SpecificResource" ? p(r.resource) : null;
99
- if (r.selector) {
100
- const f = p({
97
+ t.resource.width && t.resource.height && (t.resource.width, t.resource.height);
98
+ let c = t.resource.type === "SpecificResource" ? g(t.resource) : null;
99
+ if (t.selector) {
100
+ const a = g({
101
101
  type: "SpecificResource",
102
- source: r.resource,
103
- selector: r.selector
102
+ source: t.resource,
103
+ selector: t.selector
104
104
  });
105
- f && (d = f);
105
+ a && (c = a);
106
106
  }
107
- const m = d && d.selector && (d.selector.type === "BoxSelector" || d.selector.type === "TemporalBoxSelector") ? {
107
+ const l = c && c.selector && (c.selector.type === "BoxSelector" || c.selector.type === "TemporalBoxSelector") ? {
108
108
  type: "BoxSelector",
109
109
  spatial: {
110
- x: d.selector.spatial.x,
111
- y: d.selector.spatial.y,
112
- width: d.selector.spatial.width,
113
- height: d.selector.spatial.height
110
+ x: c.selector.spatial.x,
111
+ y: c.selector.spatial.y,
112
+ width: c.selector.spatial.width,
113
+ height: c.selector.spatial.height
114
114
  }
115
115
  } : void 0;
116
- s && !s.id && (s.id = s["@id"]);
116
+ d && !d.id && (d.id = d["@id"]);
117
117
  const x = {
118
118
  id: u.id,
119
119
  type: "Image",
120
- annotationId: r.annotationId,
121
- width: Number(a || m ? u.width : e.width),
122
- height: Number(a || m ? u.height : e.height),
123
- service: s,
124
- sizes: s && s.sizes ? s.sizes : u.width && u.height ? [{ width: u.width, height: u.height }] : [],
125
- target: a && a.type !== "PointSelector" ? a : c,
126
- selector: m
120
+ annotationId: t.annotationId,
121
+ width: Number(s || l ? u.width : e.width),
122
+ height: Number(s || l ? u.height : e.height),
123
+ service: d,
124
+ sizes: d && d.sizes ? d.sizes : u.width && u.height ? [{ width: u.width, height: u.height }] : [],
125
+ target: s && s.type !== "PointSelector" ? s : f,
126
+ selector: l
127
127
  };
128
- o.push(x);
128
+ i.push(x);
129
129
  }
130
130
  return {
131
131
  type: "images",
132
- image: o[0],
133
- images: o,
134
- choice: t.choice
132
+ image: i[0],
133
+ images: i,
134
+ choice: o.choice
135
135
  };
136
136
  }
137
- function y(e, t = {}, i) {
138
- const o = e.language || i || "none";
137
+ function h(e, o = {}, r) {
138
+ const i = e.language || r || "none";
139
139
  switch (e.type) {
140
140
  case "TextualBody": {
141
- typeof e.value < "u" && (t[o] = e.value);
141
+ typeof e.value < "u" && (o[i] = e.value);
142
142
  break;
143
143
  }
144
144
  case "List":
145
145
  case "Composite":
146
146
  case "Choice":
147
- e.items && e.items.forEach((r) => y(r, t, o));
147
+ e.items && e.items.forEach((t) => h(t, o, i));
148
148
  }
149
- return t;
149
+ return o;
150
150
  }
151
- function k(e, t) {
152
- const i = [];
153
- return t.items.forEach((o) => {
154
- if (o.resource) {
155
- const [r] = g(e, o.target);
156
- i.push({ annotationId: o.annotationId, text: y(o.resource), target: r });
151
+ function k(e, o) {
152
+ const r = [];
153
+ return o.items.forEach((i) => {
154
+ if (i.resource) {
155
+ const [t] = y(e, i.target);
156
+ r.push({ annotationId: i.annotationId, text: h(i.resource), target: t });
157
157
  }
158
158
  }), {
159
159
  type: "textual-content",
160
- items: i
160
+ items: r
161
161
  };
162
162
  }
163
163
  const B = /^.*(?:(?:youtu\.be\/|v\/|vi\/|u\/\w\/|embed\/|shorts\/)|(?:(?:watch)?\?vi?=|&vi?=))([^#&?]*).*/;
164
- function v(e, t) {
165
- var s;
166
- const i = t.items.filter((c) => c.type === "video");
167
- if (!e.duration)
168
- return n("No duration on canvas");
169
- if (i.length > 1)
164
+ function C(e, o) {
165
+ var f;
166
+ const r = o.items.filter((s) => s.type === "video");
167
+ let i = !1;
168
+ if (e.duration || (i = !0), r.length > 1)
170
169
  return n("Only one video source supported");
171
- const o = (s = i[0]) == null ? void 0 : s.resource, r = !!(o.service || []).find(
172
- (c) => (c.profile || "").includes("youtube.com")
170
+ const t = (f = r[0]) == null ? void 0 : f.resource, u = !!(t.service || []).find(
171
+ (s) => (s.profile || "").includes("youtube.com")
173
172
  );
174
- if (!o)
173
+ if (!u && i)
174
+ return n("Video does not have duration");
175
+ if (!t)
175
176
  return n("Unknown video");
176
- if ((!o.format || o.format === "text/html") && !r)
177
+ if ((!t.format || t.format === "text/html") && !u)
177
178
  return n("Video does not have format");
178
- const u = {
179
- annotationId: t.items[0].annotationId,
179
+ const d = {
180
+ annotationId: o.items[0].annotationId,
180
181
  duration: e.duration,
181
- url: o.id,
182
+ url: t.id,
182
183
  type: "Video",
183
184
  items: [],
184
185
  target: {
@@ -188,7 +189,7 @@ function v(e, t) {
188
189
  endTime: e.duration
189
190
  }
190
191
  },
191
- format: o.format,
192
+ format: t.format,
192
193
  selector: {
193
194
  type: "TemporalSelector",
194
195
  temporal: {
@@ -197,41 +198,41 @@ function v(e, t) {
197
198
  }
198
199
  }
199
200
  };
200
- if (r) {
201
- u.type = "VideoYouTube";
202
- const c = o.id.match(B);
203
- if (!c[1])
201
+ if (u) {
202
+ d.type = "VideoYouTube";
203
+ const s = t.id.match(B);
204
+ if (!s[1])
204
205
  return n("Video is not known youtube video");
205
- u.youTubeId = c[1];
206
+ d.youTubeId = s[1];
206
207
  }
207
208
  return {
208
209
  type: "media",
209
- media: u,
210
+ media: d,
210
211
  annotations: {
211
212
  pages: []
212
213
  }
213
214
  };
214
215
  }
215
- function P({ canvas: e, paintables: t, supports: i, loadImageService: o }) {
216
+ function A({ canvas: e, paintables: o, supports: r, loadImageService: i }) {
216
217
  if (!e)
217
- return console.log("No canvas"), l;
218
- if (t.types.length === 0)
219
- return i.indexOf("empty") !== -1 ? w(e.width, e.height) : (console.log("No paintables"), l);
220
- if (t.types.length !== 1)
221
- if (t.types.length === 2 && t.types.indexOf("text") !== -1)
222
- t.types = t.types.filter((u) => u !== "text");
218
+ return console.log("No canvas"), m;
219
+ if (o.types.length === 0)
220
+ return r.indexOf("empty") !== -1 ? w(e.width, e.height) : (console.log("No paintables"), m);
221
+ if (o.types.length !== 1)
222
+ if (o.types.length === 2 && o.types.indexOf("text") !== -1)
223
+ o.types = o.types.filter((u) => u !== "text");
223
224
  else
224
- return i.indexOf("complex-timeline") === -1 ? n("Complex timeline not supported") : n("ComplexTimelineStrategy not yet supported");
225
- const r = t.types[0];
226
- return r === "image" ? i.indexOf("images") === -1 ? n("Image not supported") : R(e, t, o) : r === "Model" || r === "model" ? i.indexOf("3d-model") === -1 ? n("3D not supported") : N(e, t) : r === "textualbody" ? i.indexOf("textual-content") === -1 ? n("Textual content not supported") : k(e, t) : r === "sound" || r === "audio" ? i.indexOf("media") === -1 ? n("Media not supported") : O(e, t) : r === "video" ? i.indexOf("media") === -1 ? n("Media not supported") : v(e, t) : l;
225
+ return r.indexOf("complex-timeline") === -1 ? n("Complex timeline not supported") : n("ComplexTimelineStrategy not yet supported");
226
+ const t = o.types[0];
227
+ return t === "image" ? r.indexOf("images") === -1 ? n("Image not supported") : N(e, o, i) : t === "Model" || t === "model" ? r.indexOf("3d-model") === -1 ? n("3D not supported") : O(e, o) : t === "textualbody" ? r.indexOf("textual-content") === -1 ? n("Textual content not supported") : k(e, o) : t === "sound" || t === "audio" ? r.indexOf("media") === -1 ? n("Media not supported") : R(e, o) : t === "video" ? r.indexOf("media") === -1 ? n("Media not supported") : C(e, o) : m;
227
228
  }
228
229
  export {
229
- A as emptyActions,
230
+ z as emptyActions,
230
231
  w as emptyStrategy,
231
- g as getParsedTargetSelector,
232
- P as getRenderingStrategy,
233
- z as parseSpecificResource,
234
- l as unknownResponse,
232
+ y as getParsedTargetSelector,
233
+ A as getRenderingStrategy,
234
+ b as parseSpecificResource,
235
+ m as unknownResponse,
235
236
  n as unsupportedStrategy
236
237
  };
237
238
  //# sourceMappingURL=utils.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.mjs","sources":["../../../src/features/rendering-strategy/rendering-utils.ts","../../../src/features/rendering-strategy/3d-strategy.ts","../../../src/features/rendering-strategy/audio-strategy.ts","../../../src/features/rendering-strategy/image-strategy.ts","../../../src/features/rendering-strategy/textual-content-strategy.ts","../../../src/features/rendering-strategy/video-strategy.ts","../../../src/features/rendering-strategy/get-rendering-strategy.ts"],"sourcesContent":["import { ContentResource, PointSelector, W3CAnnotationTarget } from '@iiif/presentation-3';\nimport { CanvasNormalized } from '@iiif/presentation-3-normalized';\nimport { UseRenderingStrategy } from '../../hooks/useRenderingStrategy';\nimport { BoxSelector, expandTarget, SupportedTarget, TemporalBoxSelector } from '@iiif/helpers';\n\n/**\n * Parse specific resource.\n *\n * This could be expanded to support pulling out more from the specific resource.\n *\n * @param resource\n */\nexport function parseSpecificResource(resource: ContentResource) {\n if (resource.type === 'SpecificResource') {\n return [resource.source, { selector: resource.selector }];\n }\n\n return [resource, { selector: null }];\n}\n\nexport function getParsedTargetSelector(\n canvas: CanvasNormalized,\n target: W3CAnnotationTarget | W3CAnnotationTarget[]\n): [TemporalBoxSelector | BoxSelector | PointSelector | null, SupportedTarget['source']] {\n const { selector: imageTarget, source } = expandTarget(target);\n\n if (source.id !== canvas.id) {\n // Skip invalid targets.\n return [null, source];\n }\n\n // Target is where it should be painted.\n const defaultTarget: BoxSelector = {\n type: 'BoxSelector',\n spatial: {\n x: 0,\n y: 0,\n width: Number(canvas.width),\n height: Number(canvas.height),\n },\n };\n\n return [\n imageTarget\n ? imageTarget.type === 'TemporalSelector'\n ? ({\n type: 'TemporalBoxSelector',\n temporal: imageTarget.temporal,\n spatial: defaultTarget.spatial,\n } as any)\n : imageTarget\n : null,\n source,\n ];\n}\n\nexport const emptyActions = {\n makeChoice: () => {\n // no-op\n },\n};\n\nexport const unknownResponse: UseRenderingStrategy[0] = { type: 'unknown' };\n\nexport const unsupportedStrategy = (reason: string): UseRenderingStrategy[0] => {\n return { type: 'unknown', reason, annotations: { pages: [] } };\n};\n\nexport const emptyStrategy = (width: number, height: number): UseRenderingStrategy[0] => {\n return { type: 'empty', width, height, annotations: { pages: [] }, image: null, images: [] };\n};\n","import { CanvasNormalized } from '@iiif/presentation-3-normalized';\nimport { unsupportedStrategy } from './rendering-utils';\nimport { AnnotationPageDescription } from './resource-types';\nimport { ExternalWebResource } from '@iiif/presentation-3';\nimport { RenderingStrategy } from './strategies';\nimport { ChoiceDescription, Paintables } from '@iiif/helpers';\n\nexport type Single3DModelStrategy = {\n type: '3d-model';\n model: ExternalWebResource;\n choice?: ChoiceDescription; // future\n annotations?: AnnotationPageDescription; // future\n};\n\nconst supportedFormats = ['model/gltf-binary'];\n\nexport function get3dStrategy(canvas: CanvasNormalized, paintables: Paintables): RenderingStrategy {\n const first = paintables.items[0];\n const resource = first.resource as ExternalWebResource;\n\n if (!resource.format) {\n return unsupportedStrategy('Unknown format');\n }\n\n if (supportedFormats.indexOf(resource.format) === -1) {\n return unsupportedStrategy(`3D format: ${resource.format} is unsupported`);\n }\n\n return {\n type: '3d-model',\n model: resource as any,\n } as Single3DModelStrategy;\n}\n","import { CanvasNormalized } from '@iiif/presentation-3-normalized';\nimport { unsupportedStrategy } from './rendering-utils';\nimport { MediaStrategy } from './strategies';\nimport { Paintables } from '@iiif/helpers';\n\nexport function getAudioStrategy(canvas: CanvasNormalized, paintables: Paintables) {\n if (!canvas.duration) {\n return unsupportedStrategy('No duration on canvas');\n }\n\n if (paintables.items.length > 1) {\n return unsupportedStrategy('Only one audio source supported');\n }\n\n const audioResource = paintables.items[0]?.resource as any; // @todo stronger type for what this might be.\n\n if (!audioResource) {\n return unsupportedStrategy('Unknown audio');\n }\n\n if (!audioResource.format) {\n return unsupportedStrategy('Audio does not have format');\n }\n\n return {\n type: 'media',\n media: {\n annotationId: paintables.items[0].annotationId,\n duration: canvas.duration,\n url: audioResource.id,\n type: 'Sound',\n target: {\n type: 'TemporalSelector',\n temporal: {\n startTime: 0,\n endTime: canvas.duration,\n },\n },\n format: audioResource.format,\n selector: {\n type: 'TemporalSelector',\n temporal: {\n startTime: 0,\n endTime: canvas.duration,\n },\n },\n },\n annotations: {\n pages: [],\n },\n } as MediaStrategy;\n}\n","import { IIIFExternalWebResource } from '@iiif/presentation-3';\nimport { CanvasNormalized } from '@iiif/presentation-3-normalized';\nimport { ImageServiceLoaderType } from '../../hooks/useLoadImageService';\nimport { AnnotationPageDescription, ImageWithOptionalService } from './resource-types';\nimport { getImageServices } from '@atlas-viewer/iiif-image-api';\nimport { getParsedTargetSelector, unsupportedStrategy } from './rendering-utils';\nimport { expandTarget } from '@iiif/helpers/annotation-targets';\nimport { BoxSelector, ChoiceDescription, Paintables } from '@iiif/helpers';\n\nexport type SingleImageStrategy = {\n type: 'images';\n image: ImageWithOptionalService;\n images: Array<ImageWithOptionalService>;\n choice?: ChoiceDescription;\n annotations?: AnnotationPageDescription;\n};\n\nexport function getImageStrategy(\n canvas: CanvasNormalized,\n paintables: Paintables,\n loadImageService: ImageServiceLoaderType\n) {\n const imageTypes: ImageWithOptionalService[] = [];\n for (const singleImage of paintables.items) {\n // SingleImageStrategy\n const resource: IIIFExternalWebResource =\n singleImage.resource && singleImage.resource.type === 'SpecificResource'\n ? singleImage.resource.source\n : singleImage.resource;\n\n // Validation.\n if (!resource.id) {\n // @todo we could skip this?\n return unsupportedStrategy('No resource Identifier');\n }\n\n let imageService = undefined;\n if (resource.service) {\n const imageServices = getImageServices(resource as any) as any[];\n if (imageServices[0]) {\n imageService = loadImageService(imageServices[0], canvas);\n }\n }\n\n // Target is where it should be painted.\n const defaultTarget: BoxSelector = {\n type: 'BoxSelector',\n spatial: {\n x: 0,\n y: 0,\n width: Number(canvas.width),\n height: Number(canvas.height),\n },\n };\n\n const [target, source] = getParsedTargetSelector(canvas, singleImage.target);\n if (source.id !== canvas.id) {\n // Skip invalid targets.\n continue;\n }\n\n // Support for cropping before painting an annotation.\n // @todo this isn't working.\n const defaultImageSelector =\n (singleImage.resource as any).width && (singleImage.resource as any).height\n ? ({\n type: 'BoxSelector',\n spatial: {\n x: 0,\n y: 0,\n width: (singleImage.resource as any).width,\n height: (singleImage.resource as any).height,\n },\n } as BoxSelector)\n : undefined;\n\n let imageSelector = singleImage.resource.type === 'SpecificResource' ? expandTarget(singleImage.resource) : null;\n\n if (singleImage.selector) {\n const found = expandTarget({\n type: 'SpecificResource',\n source: singleImage.resource,\n selector: singleImage.selector,\n });\n\n if (found) {\n imageSelector = found;\n }\n }\n\n const selector: undefined | BoxSelector =\n imageSelector &&\n imageSelector.selector &&\n (imageSelector.selector.type === 'BoxSelector' || imageSelector.selector.type === 'TemporalBoxSelector')\n ? {\n type: 'BoxSelector',\n spatial: {\n x: imageSelector.selector.spatial.x,\n y: imageSelector.selector.spatial.y,\n width: imageSelector.selector.spatial.width,\n height: imageSelector.selector.spatial.height,\n },\n }\n : undefined;\n\n if (imageService && !imageService.id) {\n (imageService as any).id = imageService['@id'];\n }\n\n const imageType: ImageWithOptionalService = {\n id: resource.id,\n type: 'Image',\n annotationId: (singleImage as any).annotationId,\n width: Number(target || selector ? resource.width : canvas.width),\n height: Number(target || selector ? resource.height : canvas.height),\n service: imageService,\n sizes:\n imageService && imageService.sizes\n ? imageService.sizes\n : resource.width && resource.height\n ? [{ width: resource.width, height: resource.height }]\n : [],\n target: target && target.type !== 'PointSelector' ? target : defaultTarget,\n selector: selector,\n };\n\n imageTypes.push(imageType);\n }\n\n return {\n type: 'images',\n image: imageTypes[0],\n images: imageTypes,\n choice: paintables.choice,\n } as SingleImageStrategy;\n}\n","import { InternationalString } from '@iiif/presentation-3';\nimport { CanvasNormalized } from '@iiif/presentation-3-normalized';\nimport { AnnotationPageDescription } from './resource-types';\nimport { getParsedTargetSelector } from './rendering-utils';\nimport { RenderingStrategy } from './strategies';\nimport { ChoiceDescription, Paintables, SupportedTarget } from '@iiif/helpers';\n\nexport type TextualContentStrategy = {\n type: 'textual-content';\n items: { annotationId: string; text: InternationalString; target: SupportedTarget | null }[];\n choice?: ChoiceDescription; // future\n annotations?: AnnotationPageDescription; // future\n};\n\nfunction parseType(item: any, languageMap: InternationalString = {}, lang?: string) {\n const language = item.language || lang || 'none';\n switch (item.type) {\n case 'TextualBody': {\n if (typeof item.value !== 'undefined') {\n languageMap[language] = item.value;\n }\n break;\n }\n case 'List':\n case 'Composite':\n case 'Choice': {\n if (item.items) {\n item.items.forEach((inner: any) => parseType(inner, languageMap, language));\n }\n }\n }\n return languageMap;\n}\n\nexport function getTextualContentStrategy(canvas: CanvasNormalized, paintables: Paintables): RenderingStrategy {\n const items: TextualContentStrategy['items'] = [];\n\n paintables.items.forEach((item) => {\n if (item.resource) {\n const [target] = getParsedTargetSelector(canvas, item.target);\n items.push({ annotationId: item.annotationId, text: parseType(item.resource), target: target as any });\n }\n });\n\n return {\n type: 'textual-content',\n items,\n } as TextualContentStrategy;\n}\n","import { CanvasNormalized } from '@iiif/presentation-3-normalized';\nimport { unsupportedStrategy } from './rendering-utils';\nimport { MediaStrategy } from './strategies';\nimport { Paintables } from '@iiif/helpers';\n\n// https://stackoverflow.com/a/27728417\nconst ytRegex = /^.*(?:(?:youtu\\.be\\/|v\\/|vi\\/|u\\/\\w\\/|embed\\/|shorts\\/)|(?:(?:watch)?\\?vi?=|&vi?=))([^#&?]*).*/;\n\nexport function getVideoStrategy(canvas: CanvasNormalized, paintables: Paintables) {\n const videoPaintables = paintables.items.filter((t) => t.type === 'video');\n\n if (!canvas.duration) {\n return unsupportedStrategy('No duration on canvas');\n }\n\n if (videoPaintables.length > 1) {\n return unsupportedStrategy('Only one video source supported');\n }\n\n const audioResource = videoPaintables[0]?.resource as any; // @todo stronger type for what this might be.\n const isYouTube = !!(audioResource.service || []).find((service: any) =>\n (service.profile || '').includes('youtube.com')\n );\n\n if (!audioResource) {\n return unsupportedStrategy('Unknown video');\n }\n\n if (!audioResource.format || audioResource.format === 'text/html') {\n if (!isYouTube) {\n return unsupportedStrategy('Video does not have format');\n }\n }\n\n const media = {\n annotationId: (paintables.items[0] as any).annotationId,\n duration: canvas.duration,\n url: audioResource.id,\n type: 'Video',\n items: [],\n target: {\n type: 'TemporalSelector',\n temporal: {\n startTime: 0,\n endTime: canvas.duration,\n },\n },\n format: audioResource.format,\n selector: {\n type: 'TemporalSelector',\n temporal: {\n startTime: 0,\n endTime: canvas.duration,\n },\n },\n };\n\n if (isYouTube) {\n media.type = 'VideoYouTube';\n const id = audioResource.id.match(ytRegex);\n if (!id[1]) {\n return unsupportedStrategy('Video is not known youtube video');\n }\n (media as any).youTubeId = id[1];\n }\n\n // @todo support VTT\n\n return {\n type: 'media',\n media,\n annotations: {\n pages: [],\n },\n } as MediaStrategy;\n}\n","import { get3dStrategy } from './3d-strategy';\nimport { getAudioStrategy } from './audio-strategy';\nimport { getImageStrategy } from './image-strategy';\nimport { emptyStrategy, unknownResponse, unsupportedStrategy } from './rendering-utils';\nimport { getTextualContentStrategy } from './textual-content-strategy';\nimport { getVideoStrategy } from './video-strategy';\nimport type { CanvasNormalized } from '@iiif/presentation-3-normalized';\nimport type { Paintables } from '@iiif/helpers/painting-annotations';\nimport type { ImageServiceLoaderType } from '../../hooks/useLoadImageService';\n\ninterface GetRenderStrategyOptions {\n canvas: CanvasNormalized | null | undefined;\n paintables: Paintables;\n supports: string[];\n loadImageService: ImageServiceLoaderType;\n}\n\nexport function getRenderingStrategy({ canvas, paintables, supports, loadImageService }: GetRenderStrategyOptions) {\n if (!canvas) {\n console.log('No canvas');\n return unknownResponse;\n }\n\n if (paintables.types.length === 0) {\n if (supports.indexOf('empty') !== -1) {\n return emptyStrategy(canvas.width, canvas.height);\n }\n console.log('No paintables');\n return unknownResponse;\n }\n\n if (paintables.types.length !== 1) {\n if (paintables.types.length === 2 && paintables.types.indexOf('text') !== -1) {\n paintables.types = paintables.types.filter((t) => t !== 'text');\n } else {\n if (supports.indexOf('complex-timeline') === -1) {\n return unsupportedStrategy('Complex timeline not supported');\n }\n return unsupportedStrategy('ComplexTimelineStrategy not yet supported');\n }\n }\n\n const mainType = paintables.types[0];\n\n // Image\n if (mainType === 'image') {\n if (supports.indexOf('images') === -1) {\n return unsupportedStrategy('Image not supported');\n }\n\n return getImageStrategy(canvas, paintables, loadImageService);\n }\n\n // 3D\n if (mainType === 'Model' || mainType === 'model') {\n if (supports.indexOf('3d-model') === -1) {\n return unsupportedStrategy('3D not supported');\n }\n\n return get3dStrategy(canvas, paintables);\n }\n\n if (mainType === 'textualbody') {\n if (supports.indexOf('textual-content') === -1) {\n return unsupportedStrategy('Textual content not supported');\n }\n\n return getTextualContentStrategy(canvas, paintables);\n }\n\n if (mainType === 'sound' || mainType === 'audio') {\n if (supports.indexOf('media') === -1) {\n return unsupportedStrategy('Media not supported');\n }\n\n // Media Strategy with audio or audio sequence.\n return getAudioStrategy(canvas, paintables);\n }\n\n if (mainType === 'video') {\n if (supports.indexOf('media') === -1) {\n return unsupportedStrategy('Media not supported');\n }\n\n // Media Strategy with video or video sequence.\n return getVideoStrategy(canvas, paintables);\n }\n\n // Unknown fallback.\n return unknownResponse;\n}\n"],"names":["parseSpecificResource","resource","getParsedTargetSelector","canvas","target","imageTarget","source","expandTarget","defaultTarget","emptyActions","unknownResponse","unsupportedStrategy","reason","emptyStrategy","width","height","supportedFormats","get3dStrategy","paintables","getAudioStrategy","audioResource","_a","getImageStrategy","loadImageService","imageTypes","singleImage","imageService","imageServices","getImageServices","imageSelector","found","selector","imageType","parseType","item","languageMap","lang","language","inner","getTextualContentStrategy","items","ytRegex","getVideoStrategy","videoPaintables","t","isYouTube","service","media","id","getRenderingStrategy","supports","mainType"],"mappings":"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"}
1
+ {"version":3,"file":"utils.mjs","sources":["../../../src/features/rendering-strategy/rendering-utils.ts","../../../src/features/rendering-strategy/3d-strategy.ts","../../../src/features/rendering-strategy/audio-strategy.ts","../../../src/features/rendering-strategy/image-strategy.ts","../../../src/features/rendering-strategy/textual-content-strategy.ts","../../../src/features/rendering-strategy/video-strategy.ts","../../../src/features/rendering-strategy/get-rendering-strategy.ts"],"sourcesContent":["import { ContentResource, PointSelector, W3CAnnotationTarget } from '@iiif/presentation-3';\nimport { CanvasNormalized } from '@iiif/presentation-3-normalized';\nimport { UseRenderingStrategy } from '../../hooks/useRenderingStrategy';\nimport { BoxSelector, expandTarget, SupportedTarget, TemporalBoxSelector } from '@iiif/helpers';\n\n/**\n * Parse specific resource.\n *\n * This could be expanded to support pulling out more from the specific resource.\n *\n * @param resource\n */\nexport function parseSpecificResource(resource: ContentResource) {\n if (resource.type === 'SpecificResource') {\n return [resource.source, { selector: resource.selector }];\n }\n\n return [resource, { selector: null }];\n}\n\nexport function getParsedTargetSelector(\n canvas: CanvasNormalized,\n target: W3CAnnotationTarget | W3CAnnotationTarget[]\n): [TemporalBoxSelector | BoxSelector | PointSelector | null, SupportedTarget['source']] {\n const { selector: imageTarget, source } = expandTarget(target);\n\n if (source.id !== canvas.id) {\n // Skip invalid targets.\n return [null, source];\n }\n\n // Target is where it should be painted.\n const defaultTarget: BoxSelector = {\n type: 'BoxSelector',\n spatial: {\n x: 0,\n y: 0,\n width: Number(canvas.width),\n height: Number(canvas.height),\n },\n };\n\n return [\n imageTarget\n ? imageTarget.type === 'TemporalSelector'\n ? ({\n type: 'TemporalBoxSelector',\n temporal: imageTarget.temporal,\n spatial: defaultTarget.spatial,\n } as any)\n : imageTarget\n : null,\n source,\n ];\n}\n\nexport const emptyActions = {\n makeChoice: () => {\n // no-op\n },\n};\n\nexport const unknownResponse: UseRenderingStrategy[0] = { type: 'unknown' };\n\nexport const unsupportedStrategy = (reason: string): UseRenderingStrategy[0] => {\n return { type: 'unknown', reason, annotations: { pages: [] } };\n};\n\nexport const emptyStrategy = (width: number, height: number): UseRenderingStrategy[0] => {\n return { type: 'empty', width, height, annotations: { pages: [] }, image: null, images: [] };\n};\n","import { CanvasNormalized } from '@iiif/presentation-3-normalized';\nimport { unsupportedStrategy } from './rendering-utils';\nimport { AnnotationPageDescription } from './resource-types';\nimport { ExternalWebResource } from '@iiif/presentation-3';\nimport { RenderingStrategy } from './strategies';\nimport { ChoiceDescription, Paintables } from '@iiif/helpers';\n\nexport type Single3DModelStrategy = {\n type: '3d-model';\n model: ExternalWebResource;\n choice?: ChoiceDescription; // future\n annotations?: AnnotationPageDescription; // future\n};\n\nconst supportedFormats = ['model/gltf-binary'];\n\nexport function get3dStrategy(canvas: CanvasNormalized, paintables: Paintables): RenderingStrategy {\n const first = paintables.items[0];\n const resource = first.resource as ExternalWebResource;\n\n if (!resource.format) {\n return unsupportedStrategy('Unknown format');\n }\n\n if (supportedFormats.indexOf(resource.format) === -1) {\n return unsupportedStrategy(`3D format: ${resource.format} is unsupported`);\n }\n\n return {\n type: '3d-model',\n model: resource as any,\n } as Single3DModelStrategy;\n}\n","import { CanvasNormalized } from '@iiif/presentation-3-normalized';\nimport { unsupportedStrategy } from './rendering-utils';\nimport { MediaStrategy } from './strategies';\nimport { Paintables } from '@iiif/helpers';\n\nexport function getAudioStrategy(canvas: CanvasNormalized, paintables: Paintables) {\n if (!canvas.duration) {\n return unsupportedStrategy('No duration on canvas');\n }\n\n if (paintables.items.length > 1) {\n return unsupportedStrategy('Only one audio source supported');\n }\n\n const audioResource = paintables.items[0]?.resource as any; // @todo stronger type for what this might be.\n\n if (!audioResource) {\n return unsupportedStrategy('Unknown audio');\n }\n\n if (!audioResource.format) {\n return unsupportedStrategy('Audio does not have format');\n }\n\n return {\n type: 'media',\n media: {\n annotationId: paintables.items[0].annotationId,\n duration: canvas.duration,\n url: audioResource.id,\n type: 'Sound',\n target: {\n type: 'TemporalSelector',\n temporal: {\n startTime: 0,\n endTime: canvas.duration,\n },\n },\n format: audioResource.format,\n selector: {\n type: 'TemporalSelector',\n temporal: {\n startTime: 0,\n endTime: canvas.duration,\n },\n },\n },\n annotations: {\n pages: [],\n },\n } as MediaStrategy;\n}\n","import { IIIFExternalWebResource } from '@iiif/presentation-3';\nimport { CanvasNormalized } from '@iiif/presentation-3-normalized';\nimport { ImageServiceLoaderType } from '../../hooks/useLoadImageService';\nimport { AnnotationPageDescription, ImageWithOptionalService } from './resource-types';\nimport { getImageServices } from '@atlas-viewer/iiif-image-api';\nimport { getParsedTargetSelector, unsupportedStrategy } from './rendering-utils';\nimport { expandTarget } from '@iiif/helpers/annotation-targets';\nimport { BoxSelector, ChoiceDescription, Paintables } from '@iiif/helpers';\n\nexport type SingleImageStrategy = {\n type: 'images';\n image: ImageWithOptionalService;\n images: Array<ImageWithOptionalService>;\n choice?: ChoiceDescription;\n annotations?: AnnotationPageDescription;\n};\n\nexport function getImageStrategy(\n canvas: CanvasNormalized,\n paintables: Paintables,\n loadImageService: ImageServiceLoaderType\n) {\n const imageTypes: ImageWithOptionalService[] = [];\n for (const singleImage of paintables.items) {\n // SingleImageStrategy\n const resource: IIIFExternalWebResource =\n singleImage.resource && singleImage.resource.type === 'SpecificResource'\n ? singleImage.resource.source\n : singleImage.resource;\n\n // Validation.\n if (!resource.id) {\n // @todo we could skip this?\n return unsupportedStrategy('No resource Identifier');\n }\n\n let imageService = undefined;\n if (resource.service) {\n const imageServices = getImageServices(resource as any) as any[];\n if (imageServices[0]) {\n imageService = loadImageService(imageServices[0], canvas);\n }\n }\n\n // Target is where it should be painted.\n const defaultTarget: BoxSelector = {\n type: 'BoxSelector',\n spatial: {\n x: 0,\n y: 0,\n width: Number(canvas.width),\n height: Number(canvas.height),\n },\n };\n\n const [target, source] = getParsedTargetSelector(canvas, singleImage.target);\n if (!(source.id === canvas.id || decodeURIComponent(source.id || '') === (canvas.id || ''))) {\n // Skip invalid targets.\n continue;\n }\n\n // Support for cropping before painting an annotation.\n // @todo this isn't working.\n const defaultImageSelector =\n (singleImage.resource as any).width && (singleImage.resource as any).height\n ? ({\n type: 'BoxSelector',\n spatial: {\n x: 0,\n y: 0,\n width: (singleImage.resource as any).width,\n height: (singleImage.resource as any).height,\n },\n } as BoxSelector)\n : undefined;\n\n let imageSelector = singleImage.resource.type === 'SpecificResource' ? expandTarget(singleImage.resource) : null;\n\n if (singleImage.selector) {\n const found = expandTarget({\n type: 'SpecificResource',\n source: singleImage.resource,\n selector: singleImage.selector,\n });\n\n if (found) {\n imageSelector = found;\n }\n }\n\n const selector: undefined | BoxSelector =\n imageSelector &&\n imageSelector.selector &&\n (imageSelector.selector.type === 'BoxSelector' || imageSelector.selector.type === 'TemporalBoxSelector')\n ? {\n type: 'BoxSelector',\n spatial: {\n x: imageSelector.selector.spatial.x,\n y: imageSelector.selector.spatial.y,\n width: imageSelector.selector.spatial.width,\n height: imageSelector.selector.spatial.height,\n },\n }\n : undefined;\n\n if (imageService && !imageService.id) {\n (imageService as any).id = imageService['@id'];\n }\n\n const imageType: ImageWithOptionalService = {\n id: resource.id,\n type: 'Image',\n annotationId: (singleImage as any).annotationId,\n width: Number(target || selector ? resource.width : canvas.width),\n height: Number(target || selector ? resource.height : canvas.height),\n service: imageService,\n sizes:\n imageService && imageService.sizes\n ? imageService.sizes\n : resource.width && resource.height\n ? [{ width: resource.width, height: resource.height }]\n : [],\n target: target && target.type !== 'PointSelector' ? target : defaultTarget,\n selector: selector,\n };\n\n imageTypes.push(imageType);\n }\n\n return {\n type: 'images',\n image: imageTypes[0],\n images: imageTypes,\n choice: paintables.choice,\n } as SingleImageStrategy;\n}\n","import { InternationalString } from '@iiif/presentation-3';\nimport { CanvasNormalized } from '@iiif/presentation-3-normalized';\nimport { AnnotationPageDescription } from './resource-types';\nimport { getParsedTargetSelector } from './rendering-utils';\nimport { RenderingStrategy } from './strategies';\nimport { ChoiceDescription, Paintables, SupportedTarget } from '@iiif/helpers';\n\nexport type TextualContentStrategy = {\n type: 'textual-content';\n items: { annotationId: string; text: InternationalString; target: SupportedTarget | null }[];\n choice?: ChoiceDescription; // future\n annotations?: AnnotationPageDescription; // future\n};\n\nfunction parseType(item: any, languageMap: InternationalString = {}, lang?: string) {\n const language = item.language || lang || 'none';\n switch (item.type) {\n case 'TextualBody': {\n if (typeof item.value !== 'undefined') {\n languageMap[language] = item.value;\n }\n break;\n }\n case 'List':\n case 'Composite':\n case 'Choice': {\n if (item.items) {\n item.items.forEach((inner: any) => parseType(inner, languageMap, language));\n }\n }\n }\n return languageMap;\n}\n\nexport function getTextualContentStrategy(canvas: CanvasNormalized, paintables: Paintables): RenderingStrategy {\n const items: TextualContentStrategy['items'] = [];\n\n paintables.items.forEach((item) => {\n if (item.resource) {\n const [target] = getParsedTargetSelector(canvas, item.target);\n items.push({ annotationId: item.annotationId, text: parseType(item.resource), target: target as any });\n }\n });\n\n return {\n type: 'textual-content',\n items,\n } as TextualContentStrategy;\n}\n","import { CanvasNormalized } from '@iiif/presentation-3-normalized';\nimport { unsupportedStrategy } from './rendering-utils';\nimport { MediaStrategy } from './strategies';\nimport { Paintables } from '@iiif/helpers';\n\n// https://stackoverflow.com/a/27728417\nconst ytRegex = /^.*(?:(?:youtu\\.be\\/|v\\/|vi\\/|u\\/\\w\\/|embed\\/|shorts\\/)|(?:(?:watch)?\\?vi?=|&vi?=))([^#&?]*).*/;\n\nexport function getVideoStrategy(canvas: CanvasNormalized, paintables: Paintables) {\n const videoPaintables = paintables.items.filter((t) => t.type === 'video');\n\n let noDuration = false;\n\n if (!canvas.duration) {\n noDuration = true;\n }\n\n if (videoPaintables.length > 1) {\n return unsupportedStrategy('Only one video source supported');\n }\n\n const videoResource = videoPaintables[0]?.resource as any; // @todo stronger type for what this might be.\n const isYouTube = !!(videoResource.service || []).find((service: any) =>\n (service.profile || '').includes('youtube.com')\n );\n\n if (!isYouTube && noDuration) {\n return unsupportedStrategy('Video does not have duration');\n }\n\n if (!videoResource) {\n return unsupportedStrategy('Unknown video');\n }\n\n if (!videoResource.format || videoResource.format === 'text/html') {\n if (!isYouTube) {\n return unsupportedStrategy('Video does not have format');\n }\n }\n\n const media = {\n annotationId: (paintables.items[0] as any).annotationId,\n duration: canvas.duration,\n url: videoResource.id,\n type: 'Video',\n items: [],\n target: {\n type: 'TemporalSelector',\n temporal: {\n startTime: 0,\n endTime: canvas.duration,\n },\n },\n format: videoResource.format,\n selector: {\n type: 'TemporalSelector',\n temporal: {\n startTime: 0,\n endTime: canvas.duration,\n },\n },\n };\n\n if (isYouTube) {\n media.type = 'VideoYouTube';\n const id = videoResource.id.match(ytRegex);\n if (!id[1]) {\n return unsupportedStrategy('Video is not known youtube video');\n }\n (media as any).youTubeId = id[1];\n }\n\n // @todo support VTT\n\n return {\n type: 'media',\n media,\n annotations: {\n pages: [],\n },\n } as MediaStrategy;\n}\n","import { get3dStrategy } from './3d-strategy';\nimport { getAudioStrategy } from './audio-strategy';\nimport { getImageStrategy } from './image-strategy';\nimport { emptyStrategy, unknownResponse, unsupportedStrategy } from './rendering-utils';\nimport { getTextualContentStrategy } from './textual-content-strategy';\nimport { getVideoStrategy } from './video-strategy';\nimport type { CanvasNormalized } from '@iiif/presentation-3-normalized';\nimport type { Paintables } from '@iiif/helpers/painting-annotations';\nimport type { ImageServiceLoaderType } from '../../hooks/useLoadImageService';\n\ninterface GetRenderStrategyOptions {\n canvas: CanvasNormalized | null | undefined;\n paintables: Paintables;\n supports: string[];\n loadImageService: ImageServiceLoaderType;\n}\n\nexport function getRenderingStrategy({ canvas, paintables, supports, loadImageService }: GetRenderStrategyOptions) {\n if (!canvas) {\n console.log('No canvas');\n return unknownResponse;\n }\n\n if (paintables.types.length === 0) {\n if (supports.indexOf('empty') !== -1) {\n return emptyStrategy(canvas.width, canvas.height);\n }\n console.log('No paintables');\n return unknownResponse;\n }\n\n if (paintables.types.length !== 1) {\n if (paintables.types.length === 2 && paintables.types.indexOf('text') !== -1) {\n paintables.types = paintables.types.filter((t) => t !== 'text');\n } else {\n if (supports.indexOf('complex-timeline') === -1) {\n return unsupportedStrategy('Complex timeline not supported');\n }\n return unsupportedStrategy('ComplexTimelineStrategy not yet supported');\n }\n }\n\n const mainType = paintables.types[0];\n\n // Image\n if (mainType === 'image') {\n if (supports.indexOf('images') === -1) {\n return unsupportedStrategy('Image not supported');\n }\n\n return getImageStrategy(canvas, paintables, loadImageService);\n }\n\n // 3D\n if (mainType === 'Model' || mainType === 'model') {\n if (supports.indexOf('3d-model') === -1) {\n return unsupportedStrategy('3D not supported');\n }\n\n return get3dStrategy(canvas, paintables);\n }\n\n if (mainType === 'textualbody') {\n if (supports.indexOf('textual-content') === -1) {\n return unsupportedStrategy('Textual content not supported');\n }\n\n return getTextualContentStrategy(canvas, paintables);\n }\n\n if (mainType === 'sound' || mainType === 'audio') {\n if (supports.indexOf('media') === -1) {\n return unsupportedStrategy('Media not supported');\n }\n\n // Media Strategy with audio or audio sequence.\n return getAudioStrategy(canvas, paintables);\n }\n\n if (mainType === 'video') {\n if (supports.indexOf('media') === -1) {\n return unsupportedStrategy('Media not supported');\n }\n\n // Media Strategy with video or video sequence.\n return getVideoStrategy(canvas, paintables);\n }\n\n // Unknown fallback.\n return unknownResponse;\n}\n"],"names":["parseSpecificResource","resource","getParsedTargetSelector","canvas","target","imageTarget","source","expandTarget","defaultTarget","emptyActions","unknownResponse","unsupportedStrategy","reason","emptyStrategy","width","height","supportedFormats","get3dStrategy","paintables","getAudioStrategy","audioResource","_a","getImageStrategy","loadImageService","imageTypes","singleImage","imageService","imageServices","getImageServices","imageSelector","found","selector","imageType","parseType","item","languageMap","lang","language","inner","getTextualContentStrategy","items","ytRegex","getVideoStrategy","videoPaintables","t","noDuration","videoResource","isYouTube","service","media","id","getRenderingStrategy","supports","mainType"],"mappings":"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"}