@manifest-editor/annotations 2.1.0 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +2 -1
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +0 -1
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.ts +0 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +13 -13
package/dist/index.cjs
CHANGED
|
@@ -1 +1,2 @@
|
|
|
1
|
-
Object.defineProperty(exports,`__esModule`,{value:!0});let e=require(`@manifest-editor/editors`),t=require(`react-iiif-vault`),n=require(`@manifest-editor/components`),r=require(`@manifest-editor/shell`),i=require(`react/jsx-runtime`),a=require(`react`),o=require(`zustand`),s=require(`@iiif/helpers/vault/actions`),c=require(`@iiif/parser/presentation-2`);const l=`@manifest-editor/annotations`,u=`@manifest-editor/canvas-annotation-listing`,d=`@manifest-editor/canvas-annotations`,f=`@manifest-editor/annotations/bulk-import-pages`;function p(e){return(0,i.jsx)(`svg`,{xmlns:`http://www.w3.org/2000/svg`,width:`1em`,height:`1em`,viewBox:`0 0 24 24`,...e,children:(0,i.jsx)(`path`,{fill:`currentColor`,d:`M20 2H4c-1.1 0-1.99.9-1.99 2L2 22l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2m0 14H5.17l-.59.59l-.58.58V4h16zm-9.5-2H18v-2h-5.5zm3.86-5.87c.2-.2.2-.51 0-.71l-1.77-1.77c-.2-.2-.51-.2-.71 0L6 11.53V14h2.47z`})})}function m(e){return(0,i.jsx)(`svg`,{xmlns:`http://www.w3.org/2000/svg`,width:`1em`,height:`1em`,viewBox:`0 0 24 24`,...e,children:(0,i.jsx)(`path`,{fill:`currentColor`,d:`M9 22a1 1 0 0 1-1-1v-3H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2h-6.1l-3.7 3.71c-.2.19-.45.29-.7.29zm1-6v3.08L13.08 16H20V4H4v12zm1-10h2v3h3v2h-3v3h-2v-3H8V9h3z`})})}const h=[{id:`@manifest-editor/ocr-docling/run-ocr`,label:`Run Local OCR`,preparingLabel:`Preparing OCR`,queuedLabel:`OCR queued`,pendingLabel:`OCR in progress`},{id:`@manifest-editor/remote-inference/action`,label:`Run remote OCR`,preparingLabel:`Preparing local OCR`,queuedLabel:`OCR queued`,pendingLabel:`OCR in progress`},{id:`@manifest-editor/remote-inference/structured-output`,label:`Run structured output`,preparingLabel:`Preparing structured output`,queuedLabel:`Structured output queued`,pendingLabel:`Structured output in progress`}];function g(){let e=(0,r.useBackgroundActionsStoreApi)(),a=(0,r.useAvailableBackgroundActions)(),o=(0,t.useCanvas)(),s=(0,r.useCanvasProgressStatus)(o),c=a.flatMap(e=>e.actions),l=h.map(e=>{let t=c.find(t=>t.definition.id===e.id);return t?{...e,action:t}:null}).filter(e=>!!e);if(!l.length)return null;let u=l.find(({action:e})=>{let t=e.instance?.status;return t===`preparing`||t===`running`?s===`queued`||s===`pending`?!0:e.context.currentCanvas?.id===o?.id:!1});return(0,i.jsxs)(`div`,{className:`mt-5 flex w-full flex-col items-stretch gap-2 border-t border-gray-200 pt-4`,children:[(0,i.jsx)(`div`,{className:`text-center text-xs font-semibold uppercase tracking-wide text-gray-500`,children:`OCR and structured output`}),u?(0,i.jsxs)(`div`,{className:`rounded border border-amber-200 bg-amber-50 px-3 py-2 text-center text-sm text-amber-800`,children:[(0,i.jsx)(`div`,{className:`font-medium`,children:s===`queued`?u.queuedLabel:s===`pending`?u.pendingLabel:u.preparingLabel}),(0,i.jsx)(`div`,{className:`mt-1 text-xs text-amber-700`,children:u.action.instance?.statusText||u.label})]}):null,u?null:l.map(({id:t,label:a,action:o})=>{let s=o.instance?.status===`preparing`||o.instance?.status===`running`;return(0,i.jsx)(n.ActionButton,{large:!0,isDisabled:s,onPress:()=>{s||(0,r.runBackgroundAction)({store:e,context:o.context,prepareData:{scope:`selected`}})},children:a},t)})]})}function _(){let a=(0,e.useInStack)(`Canvas`)?.resource.source?.id,o=(0,t.useCanvas)({id:a}),s=(0,r.useInlineCreator)(),c=()=>{o&&s.create(`@manifest-editor/empty-annotation-page`,{label:{en:[`Inline annotations`]}},{target:{id:o.id,type:`Canvas`},targetType:`AnnotationPage`,parent:{property:`annotations`,resource:{id:o.id,type:`Canvas`}}})};return(0,i.jsxs)(n.Sidebar,{children:[(0,i.jsx)(n.SidebarHeader,{title:`Annotations`,actions:[{icon:(0,i.jsx)(m,{className:`text-2xl`}),title:`Add annotation`,disabled:!0,onClick:()=>void 0}]}),(0,i.jsx)(n.SidebarContent,{children:(0,i.jsxs)(`div`,{className:`flex flex-col items-center justify-center p-4`,children:[(0,i.jsx)(`div`,{className:`p-4 opacity-50 text-center`,children:`This canvas does not yet have any inline annotations. To add inline annotations, an AnnotationPage is created which will be linked to this canvas, and can then used to add your annotations. Simply use the link below to start adding your annotations`}),(0,i.jsxs)(n.ActionButton,{large:!0,primary:!0,onPress:()=>c(),children:[(0,i.jsx)(n.AddIcon,{className:`text-xl`}),` Create empty page`]}),(0,i.jsx)(g,{})]})})]})}function ee(){let n=(0,t.useAnnotation)(),a=(0,t.useCanvas)(),s=(0,t.useAtlasStore)(),{edit:c}=(0,r.useLayoutActions)(),l=(0,o.useStore)(s,e=>a?.id?e.canvasViewports[a.id]:null);return!n||!a||!l?null:(0,i.jsxs)(`div`,{className:`p-2`,children:[(0,i.jsx)(t.LocaleString,{as:`div`,defaultText:(0,i.jsx)(`span`,{className:`opacity-50`,children:`Untitled`}),className:`whitespace-nowrap overflow-ellipsis w-full overflow-x-hidden`,children:n?.label}),(0,i.jsx)(t.LocaleString,{className:`text-gray-500 text-sm bg-white line-clamp-2 mb-4`,as:`div`,children:n?.summary}),(0,i.jsx)(e.CanvasTargetContext,{children:(0,i.jsx)(e.AnnotationPreview,{viewport:l,onClick:()=>c(n,void 0,{forceOpen:!0})})})]})}function v(){let{isPending:o,cancelRequest:s,busy:c,requestAnnotationFromTarget:l,deleteAnnotation:u}=(0,e.useAnnotationEditor)(),[d,{highlightProps:f,annotationTarget:p}]=(0,e.useAnnotationInfo)(),{edit:m}=(0,r.useLayoutActions)(),h=d?.body||[],g=!d||h.length===0,[_,v]=(0,a.useState)(!1);return(0,i.jsxs)(`div`,{...f,className:`border border-gray-300 hover:border-me-500 shadow-sm rounded bg-white relative`,children:[(0,i.jsx)(`div`,{className:`relative`,children:p?(0,i.jsx)(t.AnnotationContext,{annotation:p,children:(0,i.jsx)(ee,{})}):g?(0,i.jsx)(`div`,{className:`flex items-center justify-center px-4 py-6 text-gray-400 text-sm`,children:`This annotation has no body.`}):_?(0,i.jsx)(e.HTMLAnnotationEditor,{className:`border-none`}):(0,i.jsx)(n.HTMLAnnotationBodyRender,{className:`px-3 pt-3 line-clamp-3 prose-p:text-slate-600`,locale:`en`})}),(0,i.jsxs)(`div`,{className:`flex gap-2 p-2`,children:[p?(0,i.jsx)(n.ActionButton,{onPress:()=>m({id:p,type:`Annotation`},void 0,{forceOpen:!0}),children:`Edit painting annotation`}):_&&o?(0,i.jsxs)(n.ActionButton,{primary:!0,onPress:()=>{v(!1),s()},children:[(0,i.jsx)(n.CheckIcon,{}),` Finish editing`]}):(0,i.jsxs)(n.ActionButton,{isDisabled:c,onPress:()=>{v(!0),l().then(()=>{v(!1)})},children:[(0,i.jsx)(n.EditTextIcon,{}),` `,g?`Edit target`:`Edit`]}),(0,i.jsxs)(n.ActionButton,{className:`gap-2 flex`,onPress:()=>u(),children:[(0,i.jsx)(n.DeleteIcon,{}),` Delete`]})]})]})}function y(){let r=(0,t.useCanvas)(),a=(0,t.useAnnotationPage)(),{requestAnnotation:o,isActive:s,busy:c,cancelRequest:l}=(0,t.useRequestAnnotation)(),[u]=(0,t.useRenderingStrategy)();if(u.type!==`images`)return(0,i.jsx)(`div`,{children:`Not supported`});if(!a)return null;let d=()=>o({type:`box`,annotationPopup:(0,i.jsx)(e.AnnotationCreationPopup,{annotationPageId:a.id,canvasId:r.id})});return(0,i.jsxs)(n.Sidebar,{children:[(0,i.jsx)(n.SidebarHeader,{title:`Annotations`,actions:[{icon:(0,i.jsx)(m,{className:`text-2xl`}),title:`Add annotation`,disabled:s||c,onClick:d}]}),s?(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(`button`,{"aria-label":`cancel add annotation`,className:`m-2 rounded border border-gray-300 bg-white px-3 py-2 text-sm text-gray-700`,type:`button`,onClick:()=>l(),children:`Exit edit mode`}),(0,i.jsxs)(`div`,{className:`flex flex-col gap-5 text-center p-4 items-center justify-center`,children:[(0,i.jsx)(n.TargetIcon,{className:`w-32 h-32 text-gray-300`}),(0,i.jsx)(`p`,{className:`text-gray-500`,children:`Draw a box on the canvas`})]})]}):null,(0,i.jsxs)(n.SidebarContent,{className:`w-full p-2 flex flex-col gap-2`,children:[a.items.map(e=>(0,i.jsx)(t.AnnotationContext,{annotation:e.id,children:(0,i.jsx)(v,{})},e.id)),!s&&a.items.length===0?(0,i.jsxs)(`div`,{className:`flex flex-col items-center justify-center p-4`,children:[(0,i.jsx)(`div`,{className:`p-4 opacity-50 text-center`,children:`This canvas does not yet have any inline annotations.`}),(0,i.jsxs)(n.ActionButton,{large:!0,primary:!0,isDisabled:s,onPress:()=>d(),children:[(0,i.jsx)(m,{className:`text-xl`}),` Add annotation`]}),(0,i.jsx)(g,{})]}):null]})]})}const te={id:u,label:`Annotations`,icon:(0,i.jsx)(p,{}),focusedMode:{closeOnMainPanelClick:!1},render:()=>(0,i.jsx)(ne,{})};function ne(){let n=(0,e.useInStack)(`Canvas`)?.resource.source?.id,r=(0,t.useCanvas)({id:n}),a=r?.annotations[0];return r?a?(0,i.jsx)(t.AnnotationPageContext,{annotationPage:a.id,children:(0,i.jsx)(t.CanvasContext,{canvas:r.id,children:(0,i.jsx)(y,{})})}):(0,i.jsx)(t.CanvasContext,{canvas:r.id,children:(0,i.jsx)(_,{})}):(0,i.jsxs)(`div`,{className:`flex flex-col gap-5 text-center p-4 items-center justify-center`,children:[(0,i.jsx)(p,{className:`w-32 h-32 text-gray-300`}),(0,i.jsx)(`p`,{className:`text-gray-500`,children:`Annotations are associated with Canvases in a IIIF Manifest. To view or add annotations, first create a Canvas and then select the Annotations link`})]})}const re={id:d,label:`Canvas annotations`,render:()=>(0,i.jsx)(ie,{})};function ie(){let n=(0,t.useCanvas)(),a=(0,o.useStore)((0,r.useAtlasStore)(),e=>e.tool.enabled),{leftPanel:s}=(0,r.useLayoutState)(),c=s.current===u,l=n?.annotations[0];return!n||a||!l||!c?null:(0,i.jsx)(t.AnnotationPageContext,{annotationPage:l.id,children:(0,i.jsx)(e.ViewerAnnotationPage,{})})}const b=`@manifest-editor/annotations:bulk-import-config`,ae=[`commenting`,`supplementing`,`tagging`,`describing`,`linking`,`painting`,`highlighting`,`classifying`,`identifying`,`replying`];function oe(e){return new Promise(t=>{if(e.signal?.aborted){t(!1);return}let n=!1,r=r=>{n||(n=!0,e.signal?.removeEventListener(`abort`,i),t(r))},i=()=>r(!1);e.signal?.addEventListener(`abort`,i,{once:!0}),window.dispatchEvent(new CustomEvent(b,{detail:{...e,resolve:r}}))})}function se(e){return(0,i.jsx)(S,{actionId:e})}function x(){return{scope:`all`,motivationMode:`all`,motivations:[]}}function S({actionId:e}){let[t,r]=(0,a.useState)(null),[o,s]=(0,a.useState)(x()),[c,l]=(0,a.useState)(``);(0,a.useEffect)(()=>{let t=t=>{let n=t.detail;n?.actionId===e&&(r(n),s(C(n.defaults,n.tags)),l(``))};return window.addEventListener(b,t),()=>window.removeEventListener(b,t)},[e]),(0,a.useEffect)(()=>{if(!t?.signal)return;if(t.signal.aborted){r(null);return}let e=()=>r(null);return t.signal.addEventListener(`abort`,e,{once:!0}),()=>t.signal?.removeEventListener(`abort`,e)},[t]);let u=(0,a.useMemo)(()=>t?.tags.find(e=>e.key===o.tagKey),[t?.tags,o.tagKey]),d=o.scope===`tag`?u?.externalPageCount||0:t?.totalExternalPages||0,f=(0,a.useMemo)(()=>ce(o,c),[c,o]),p=o.motivationMode===`selected`&&f.length===0;if(!t)return null;let m=e=>{t.resolve(e),r(null)},h=!t.tags.length;return(0,i.jsx)(n.Modal,{title:`Import External Annotation Pages`,onClose:()=>m(!1),className:`max-w-2xl`,actions:(0,i.jsxs)(`div`,{className:`flex gap-2`,children:[(0,i.jsx)(`button`,{type:`button`,className:`rounded border border-zinc-300 bg-white px-3 py-2 text-sm text-zinc-700`,onClick:()=>m(!1),children:`Cancel`}),(0,i.jsx)(`button`,{type:`button`,className:`rounded border border-me-primary-500 bg-me-primary-500 px-3 py-2 text-sm text-white disabled:cursor-not-allowed disabled:opacity-50`,disabled:d===0||p,onClick:()=>m({...o,motivations:o.motivationMode===`selected`?f:[]}),children:`Import pages`})]}),children:(0,i.jsxs)(`div`,{className:`flex min-h-0 flex-col gap-4 p-4 text-sm text-zinc-700`,children:[(0,i.jsxs)(`fieldset`,{className:`grid gap-2`,children:[(0,i.jsx)(`legend`,{className:`font-medium text-zinc-900`,children:`Canvases`}),(0,i.jsxs)(`label`,{className:`flex items-center gap-2`,children:[(0,i.jsx)(`input`,{type:`radio`,checked:o.scope===`all`,onChange:()=>s(e=>({...e,scope:`all`}))}),(0,i.jsxs)(`span`,{children:[`All canvases with external annotation pages (`,t.totalExternalPages,`)`]})]}),(0,i.jsxs)(`label`,{className:`flex items-center gap-2`,children:[(0,i.jsx)(`input`,{type:`radio`,checked:o.scope===`tag`,disabled:h,onChange:()=>s(e=>({...e,scope:`tag`,tagKey:e.tagKey||t.tags[0]?.key}))}),(0,i.jsx)(`span`,{children:`Only canvases with tag`})]}),(0,i.jsx)(`select`,{className:`rounded border border-zinc-300 bg-white p-2 disabled:bg-zinc-100`,disabled:o.scope!==`tag`||h,value:o.tagKey||``,onChange:e=>s(t=>({...t,tagKey:e.target.value})),children:t.tags.map(e=>(0,i.jsxs)(`option`,{value:e.key,children:[e.label,` (`,e.externalPageCount,`)`]},e.key))})]}),(0,i.jsxs)(`fieldset`,{className:`grid gap-2`,children:[(0,i.jsx)(`legend`,{className:`font-medium text-zinc-900`,children:`Motivations`}),(0,i.jsxs)(`label`,{className:`flex items-center gap-2`,children:[(0,i.jsx)(`input`,{type:`radio`,checked:o.motivationMode===`all`,onChange:()=>s(e=>({...e,motivationMode:`all`}))}),(0,i.jsx)(`span`,{children:`All motivations`})]}),(0,i.jsxs)(`label`,{className:`flex items-center gap-2`,children:[(0,i.jsx)(`input`,{type:`radio`,checked:o.motivationMode===`selected`,onChange:()=>s(e=>({...e,motivationMode:`selected`,motivations:e.motivations.length?e.motivations:[`commenting`]}))}),(0,i.jsx)(`span`,{children:`Only selected motivations`})]}),(0,i.jsx)(`div`,{className:`grid grid-cols-2 gap-2 rounded border border-zinc-200 p-3`,children:ae.map(e=>(0,i.jsxs)(`label`,{className:`flex items-center gap-2`,children:[(0,i.jsx)(`input`,{type:`checkbox`,disabled:o.motivationMode!==`selected`,checked:o.motivations.includes(e),onChange:t=>s(n=>({...n,motivationMode:`selected`,motivations:t.target.checked?w([...n.motivations,e]):n.motivations.filter(t=>t!==e)}))}),(0,i.jsx)(`span`,{children:e})]},e))}),(0,i.jsxs)(`label`,{className:`grid gap-1`,children:[(0,i.jsx)(`span`,{className:`font-medium text-zinc-900`,children:`Additional motivations`}),(0,i.jsx)(`input`,{type:`text`,className:`rounded border border-zinc-300 p-2`,disabled:o.motivationMode!==`selected`,value:c,placeholder:`transcribing, reviewing`,onChange:e=>l(e.target.value)})]})]}),(0,i.jsxs)(`div`,{className:`rounded border border-zinc-200 bg-white p-3 text-zinc-600`,children:[d,` external annotation page`,d===1?``:`s`,` selected.`,o.motivationMode===`selected`?(0,i.jsxs)(i.Fragment,{children:[` `,f.length,` motivation`,f.length===1?``:`s`,` selected.`]}):null]})]})})}function C(e,t){let n=e.tagKey?t.some(t=>t.key===e.tagKey):!1;return{scope:e.scope===`tag`&&t.length?`tag`:`all`,tagKey:n?e.tagKey:t[0]?.key,motivationMode:e.motivationMode===`selected`?`selected`:`all`,motivations:w(e.motivations||[])}}function ce(e,t){return e.motivationMode===`selected`?w([...e.motivations,...le(t)]):[]}function le(e){return e.split(/[,\n]/).map(e=>e.trim()).filter(Boolean)}function w(e){return Array.from(new Set(e.map(e=>e.trim()).filter(Boolean)))}const T=`iiif-parser:isExternal`,E=`iiif-parser:hasPart`,ue=[`Annotation`,`AnnotationPage`,`ContentResource`,`Canvas`,`Manifest`,`Range`];function D(e,t){let n=[];for(let r of t)!r?.id||!Array.isArray(r.annotations)||r.annotations.forEach((t,i)=>{let a=B(t);if(!a)return;let o=e.get({id:a,type:`AnnotationPage`})||e.get(t)||t;de(o)&&n.push({key:`${r.id}:annotations:${i}:${a}`,canvasId:r.id,canvasLabel:be(r.label)||r.id,pageId:a,annotationPageIndex:i,existingPage:o})});return n}function O(e){let t=[],n=[],r=[],i=new Set,a=me(e.motivationFilter),o=0;for(let s of e.loadedPages){let{reference:e}=s;if(i.has(e.pageId)){n.push(j(e,`External annotation page is referenced more than once.`));continue}if(i.add(e.pageId),s.error){n.push(j(e,s.error));continue}let c=fe(s.json,e);if(c.warning&&r.push(c.warning),!c.page){n.push(j(e,c.error));continue}let l=c.page;if(!Array.isArray(l.items)){n.push(j(e,`Fetched annotation page does not contain an items array.`));continue}let u=l.items.filter(e=>e?.type===`Annotation`),d=u.filter(e=>he(e,a)),f=l.items.length-u.length,p=u.length-d.length;if(f&&r.push(`${e.pageId}: skipped ${f} non-Annotation item${f===1?``:`s`}.`),p&&r.push(`${e.pageId}: skipped ${p} annotation${p===1?``:`s`} outside the selected motivation filter.`),!d.length){n.push(j(e,pe(l.items.length,u.length,a)));continue}o+=d.length,t.push({reference:e,page:l,annotations:d,skippedAnnotations:f,skippedByMotivation:p})}return{totalExternalPages:e.loadedPages.length,totalAnnotations:o,pages:t,skippedPages:n,warnings:r,errors:[]}}function k(e,t){let n={AnnotationPage:{},Annotation:{},ContentResource:{}},r=[],i=ve(e),a=new Set,o=0;for(let e of t.pages){let{reference:t}=e,c=t.pageId,l=W(e.page);l.id=c,l.type=`AnnotationPage`,l.items=[],l[T]=!1,t.existingPage?.[E]&&(l[E]=W(t.existingPage[E])),n.AnnotationPage[c]=l,a.add(t.canvasId),r.push((0,s.modifyEntityField)({id:c,type:`AnnotationPage`,key:T,value:!1}));for(let a of e.annotations){let e=W(a),l=i.preserveOrCreate(B(e),`Annotation`,t.canvasId,`external-annotation`),u=F(e.body,i,t.canvasId,l);e.id=l,e.type=`Annotation`,e.body=u.body,e.target=A(e.target,t.canvasId),Object.assign(n.ContentResource,u.entities),n.Annotation[l]=e,r.push((0,s.addReference)({id:c,type:`AnnotationPage`,key:`items`,reference:{id:l,type:`Annotation`}})),o+=1}}let c=[(0,s.importEntities)({entities:Se(n)}),...r];return(r.length||Object.values(n).some(e=>Object.keys(e).length))&&e.dispatch((0,s.batchActions)({actions:c})),{totalExternalPages:t.totalExternalPages,pagesInlined:t.pages.length,canvasesUpdated:a.size,annotationsWritten:o,skippedPages:t.skippedPages,warnings:t.warnings}}function A(e,t){if(Array.isArray(e))return e.map(e=>A(e,t));if(typeof e==`string`)return z(e,t);if(!e||typeof e!=`object`)return e;let n=W(e);return typeof n.source==`string`?(n.source=z(n.source,t),n):n.source&&typeof n.source==`object`?(n.source={...n.source,id:t,type:n.source.type||`Canvas`},n):(typeof n.id==`string`&&(n.id=z(n.id,t)),n)}function de(e){return!!e?.[T]}function j(e,t){return{key:e.key,canvasId:e.canvasId,canvasLabel:e.canvasLabel,pageId:e.pageId,reason:t}}function fe(e,t){if(!e||typeof e!=`object`)return{error:`Fetched resource is not a JSON object.`};let n=e;if(n.type===`AnnotationPage`)return{page:n,error:``};if(P(n))try{let e=(0,c.convertPresentation2)(n);return e?.type===`AnnotationPage`?{page:e,error:``,warning:`${t.pageId}: upgraded Presentation 2 sc:AnnotationList to AnnotationPage.`}:{error:`IIIF upgrade produced ${e?.type||`missing a type`}, not AnnotationPage.`}}catch(e){return{error:`Unable to upgrade Presentation 2 sc:AnnotationList: ${e instanceof Error?e.message:String(e)}`}}return{error:`Fetched resource is ${n.type||n[`@type`]||`missing a type`}, not AnnotationPage.`}}function pe(e,t,n){return e?t?n?.size?`No annotations matched the selected motivation filter (${Array.from(n).join(`, `)}).`:`Fetched annotation page does not contain importable annotations.`:`Fetched annotation page does not contain Annotation items.`:`Fetched annotation page is empty.`}function me(e){let t=H((e||[]).map(N).filter(Boolean));return t.length?new Set(t):null}function he(e,t){return t?.size?M(e).some(e=>t.has(e)):!0}function M(e){return H(U(e?.motivation).map(N).filter(Boolean))}function N(e){if(typeof e!=`string`)return``;let t=e.trim().toLowerCase(),n=t.includes(`:`)?t.slice(t.lastIndexOf(`:`)+1):t,r=n.lastIndexOf(`/`),i=n.lastIndexOf(`#`),a=Math.max(r,i);return a>=0?n.slice(a+1):n}function P(e){let t=e?.[`@type`]||e?.type;return t===`sc:AnnotationList`||t===`AnnotationList`}function F(e,t,n,r){let i=e==null?[]:U(e),a={};return{body:i.length>1&&i.every(_e)?[L({type:`Choice`,items:i},t,n,r,`body-choice`,a)]:i.map((e,i)=>I(e,t,n,r,`body-${i+1}`,a)),entities:a}}function I(e,t,n,r,i,a){if(ge(e))return L(e,t,n,r,i,a);let o=t.preserveOrCreate(e&&typeof e==`object`?B(e):void 0,`ContentResource`,n,`${r}-${i}`);if(typeof e==`string`)return a[o]={id:o,type:`TextualBody`,format:`text/plain`,value:e},{id:o,type:`ContentResource`};if(e&&typeof e==`object`){let t=R(e);return a[o]={...t,id:o,type:t.type||`ContentResource`},{id:o,type:`ContentResource`}}return a[o]={id:o,type:`TextualBody`,format:`text/plain`,value:String(e)},{id:o,type:`ContentResource`}}function L(e,t,n,r,i,a){let o=t.preserveOrCreate(B(e),`ContentResource`,n,`${r}-${i}`),s=U(e.items).map((e,o)=>I(e,t,n,r,`${i}-item-${o+1}`,a));return a[o]={...W(e),id:o,type:`Choice`,items:s},{id:o,type:`ContentResource`}}function R(e){let t=W(e);return typeof t.chars==`string`&&t.value===void 0&&(t.value=t.chars,delete t.chars,t.type===`Text`&&(t.type=`TextualBody`)),t}function ge(e){return!!e&&typeof e==`object`&&e.type===`Choice`}function _e(e){if(typeof e==`string`)return!0;if(!e||typeof e!=`object`)return!1;let t=e.type;return t===`TextualBody`||t===`Text`}function ve(e){let t=new Set,n=0;function r(n){return t.has(n)?!0:ue.some(t=>!!e.get({id:n,type:t}))}function i(e,i,a){let o;do n+=1,o=`${xe(e)}/external-annotation-pages/${G(i)}/${G(a)}-${n}`;while(r(o));return t.add(o),o}function a(e,n,a,o){return e&&!r(e)?(t.add(e),e):i(a,n,o)}return{create:i,preserveOrCreate:a}}function ye(e){let t=e.indexOf(`#`);return{sourceId:t>=0?e.slice(0,t):e,fragment:t>=0?e.slice(t):``}}function z(e,t){return`${t}${ye(e).fragment}`}function B(e){if(typeof e==`string`)return e;if(!(!e||typeof e!=`object`))return typeof e.id==`string`?e.id:typeof e[`@id`]==`string`?e[`@id`]:void 0}function V(e){return e?typeof e==`string`?[e]:Array.isArray(e)?e.filter(e=>typeof e==`string`):typeof e==`object`?Object.values(e).flatMap(V):[]:[]}function be(e){return V(e)[0]||``}function H(e){return Array.from(new Set(e.filter(Boolean)))}function U(e){return Array.isArray(e)?e:e==null?[]:[e]}function W(e){return JSON.parse(JSON.stringify(e))}function G(e){return e.toLowerCase().replace(/[^a-z0-9]+/g,`-`).replace(/^-+|-+$/g,``).slice(0,80)||`item`}function xe(e){return e.endsWith(`/`)?e.slice(0,-1):e}function Se(e){return Object.fromEntries(Object.entries(e).filter(([,e])=>Object.keys(e).length))}const K=`@manifest-editor/annotations:bulk-import-results`;function Ce(e,t){window.dispatchEvent(new CustomEvent(K,{detail:{actionId:e,result:t}}))}function we(e){return(0,i.jsx)(Te,{actionId:e})}function Te({actionId:e}){let[t,r]=(0,a.useState)(null);return(0,a.useEffect)(()=>{let t=t=>{let n=t.detail;n?.actionId===e&&n.result&&r(n.result)};return window.addEventListener(K,t),()=>window.removeEventListener(K,t)},[e]),t?(0,i.jsx)(n.Modal,{title:`External annotation page import results`,onClose:()=>r(null),className:`max-w-3xl`,children:(0,i.jsxs)(`div`,{className:`flex min-h-0 flex-col gap-4 p-4 text-sm text-zinc-700`,children:[(0,i.jsxs)(`div`,{className:`grid grid-cols-4 gap-2`,children:[(0,i.jsx)(q,{label:`External pages`,value:t.totalExternalPages}),(0,i.jsx)(q,{label:`Inlined pages`,value:t.pagesInlined}),(0,i.jsx)(q,{label:`Canvases`,value:t.canvasesUpdated}),(0,i.jsx)(q,{label:`Annotations`,value:t.annotationsWritten})]}),t.warnings.length?(0,i.jsx)(`div`,{className:`rounded border border-amber-200 bg-amber-50 p-3 text-amber-900`,children:t.warnings.map(e=>(0,i.jsx)(`div`,{children:e},e))}):null,t.skippedPages.length?(0,i.jsxs)(`div`,{className:`rounded border border-zinc-200`,children:[(0,i.jsx)(`div`,{className:`border-b border-zinc-200 bg-zinc-50 px-3 py-2 font-medium`,children:`Skipped external pages`}),(0,i.jsx)(`div`,{className:`max-h-64 overflow-auto`,children:t.skippedPages.map(e=>(0,i.jsxs)(`div`,{className:`grid gap-1 border-b border-zinc-100 px-3 py-2 last:border-0`,children:[(0,i.jsx)(`div`,{className:`truncate font-medium text-zinc-900`,children:e.pageId}),(0,i.jsx)(`div`,{className:`truncate text-zinc-500`,children:e.canvasLabel}),(0,i.jsx)(`div`,{className:`text-zinc-500`,children:e.reason})]},e.key))})]}):null]})}):null}function q({label:e,value:t}){return(0,i.jsxs)(`div`,{className:`rounded border border-zinc-200 bg-zinc-50 p-3`,children:[(0,i.jsx)(`div`,{className:`text-xl font-semibold text-zinc-900`,children:t}),(0,i.jsx)(`div`,{className:`text-xs uppercase tracking-wide text-zinc-500`,children:e})]})}const J=new Map;function Y(e={}){let t=e.fetchPage||Ee,n=e.requestConfig||De;return{id:f,label:`Bulk Annotation Page Importer`,summary:`Load external Canvas annotation pages and make them editable inline`,section:`Annotations`,order:10,resourceTypes:[`Manifest`],resumable:!1,render:e=>(0,i.jsxs)(i.Fragment,{children:[se(e.definition.id),we(e.definition.id)]}),onResults:e=>Ce(e.definition.id,e.instance?.result),supports:e=>D(e.vault,X(e)).length>0,prepare:async e=>{let t=D(e.vault,X(e));if(!t.length)return!1;let r=await n(e,t,x());if(r===!1)return!1;let i=Z(e,t,r);return i.length?(J.set(e.instanceKey,{references:i,options:r}),!0):!1},run:async e=>{let n=J.get(e.instanceKey),r=n?.options||x(),i=n?.references||Z(e,D(e.vault,X(e)),r);try{if(e.setActionLabel(`Importing external annotation pages`),e.setActionProgress({current:0,total:Math.max(i.length,1),label:`Loading external annotation pages`}),!i.length)return e.setActionStatus(`running`,`No external annotation pages found`),Ae();let n=[];for(let[r,a]of i.entries()){$(e.signal),e.setActionStatus(`running`,`Loading ${r+1}/${i.length}`),e.appendActionLog(`Loading external annotation page`,`info`,{canvasId:a.canvasId,pageId:a.pageId});try{let r=await t(a.pageId,a,e);n.push({reference:a,json:r})}catch(t){let r=je(t);n.push({reference:a,error:r}),e.appendActionLog(`Failed to load external annotation page`,`warn`,{canvasId:a.canvasId,pageId:a.pageId,reason:r})}e.setActionProgress({current:r+1,total:i.length,label:`Loading external annotation pages`})}let a=O({loadedPages:n,motivationFilter:r.motivationMode===`selected`?r.motivations:void 0});if(a.errors.length)throw Error(a.errors[0]||`External annotation page import failed.`);e.setActionStatus(`running`,`Writing inline annotation pages`),e.setActionProgress({current:0,total:Math.max(a.totalAnnotations,a.pages.length,1),label:`Writing inline annotations`});let o=k(e.vault,a);return e.appendActionLog(`External annotation page import complete`,`info`,{pages:o.pagesInlined,annotations:o.annotationsWritten,skipped:o.skippedPages.length}),e.setActionStatus(`running`,`Imported ${o.pagesInlined}/${o.totalExternalPages} external pages`),e.setActionProgress({current:Math.max(o.annotationsWritten,o.pagesInlined),total:Math.max(o.annotationsWritten,o.pagesInlined,1),label:`Import complete`}),o}finally{J.delete(e.instanceKey)}}}}async function Ee(e,t,n){let r=await fetch(e,{signal:n.signal,headers:{Accept:`application/ld+json, application/json;q=0.9, */*;q=0.1`}});if(!r.ok)throw Error(`Unable to fetch ${e} (${r.status}).`);return r.json()}async function De(e,t,n){return oe({actionId:e.definition.id,instanceKey:e.instanceKey,totalExternalPages:t.length,tags:Oe(e,t),defaults:n,signal:e.signal})}function X(e){let t=e.vault.get(e.target);return t?.items?(e.vault.get(t.items)||[]).filter(Boolean):[]}function Z(e,t,n){if(n.scope!==`tag`||!n.tagKey)return t;let r=ke(n.tagKey);return r?t.filter(t=>e.tags.hasTag({id:t.canvasId,type:`Canvas`},r.type,r.id)):[]}function Oe(e,t){let n=new Map,i=new Map;n.set(Q(r.FLAG_TAG),{...r.FLAG_TAG,key:Q(r.FLAG_TAG),canvasCount:0,externalPageCount:0});for(let e of t)i.set(e.canvasId,(i.get(e.canvasId)||0)+1);for(let[t,r]of i)for(let i of e.tags.getTags({id:t,type:`Canvas`})){let e=Q(i),t=n.get(e);t?(t.canvasCount+=1,t.externalPageCount+=r):n.set(e,{...i,key:e,canvasCount:1,externalPageCount:r})}return Array.from(n.values()).sort((e,t)=>e.type===r.FLAG_TAG.type&&e.id===r.FLAG_TAG.id?-1:t.type===r.FLAG_TAG.type&&t.id===r.FLAG_TAG.id?1:e.label.localeCompare(t.label)||e.type.localeCompare(t.type)||e.id.localeCompare(t.id))}function Q(e){return`${e.type}:${e.id}`}function ke(e){let t=e.indexOf(`:`);return t===-1?null:{type:e.slice(0,t),id:e.slice(t+1)}}function Ae(){return{totalExternalPages:0,pagesInlined:0,canvasesUpdated:0,annotationsWritten:0,skippedPages:[],warnings:[]}}function $(e){if(e.aborted)throw new DOMException(`Aborted`,`AbortError`)}function je(e){return e instanceof Error?e.message:String(e||`Unknown error`)}const Me=`@manifest-editor/ranges-listing`,Ne={id:`@manifest-editor/annotations-routing`,label:`Annotation routing`,render:()=>(0,i.jsx)(Pe,{})};function Pe(){let n=(0,t.useManifest)(),i=(0,e.useInStack)(`Canvas`),o=(0,r.useLayoutMode)(),{leftPanel:s,rightPanel:c}=(0,r.useLayoutState)(),{edit:l,open:d,rightPanel:f}=(0,r.useLayoutActions)(),p=(0,a.useRef)(null),[m,h]=(0,a.useState)(!1);return(0,a.useEffect)(()=>{let e=i?.resource?.source?.id;e&&(p.current=e)},[i?.resource?.source?.id]),(0,a.useEffect)(()=>{if(s.current===u){let e=p.current||n?.items?.[0]?.id;if(e&&(d({id:`current-canvas`}),l({id:e,type:`Canvas`})),o===`focused`)return;c.open&&(f.close(),h(!0));return}m&&!c.open&&s.current!==`@manifest-editor/ranges-listing`&&(f.open(),h(!1))},[s.current,o]),null}var Fe={id:l,label:`Annotations`,description:`Create, view, and inline external supplemental canvas annotation pages.`,author:`Digirati`,official:!0,defaultEnabled:!0,tags:[`annotations`,`iiif`,`external-pages`],supports:{apps:[`manifest-editor`],projectTypes:[`Manifest`]}};const Ie=[te],Le=[re],Re=[Ne],ze=[Y()];exports.ANNOTATIONS_LEFT_PANEL_ID=u,exports.ANNOTATIONS_PLUGIN_ID=l,exports.BULK_ANNOTATION_IMPORT_ACTION_ID=f,exports.CANVAS_ANNOTATIONS_PANEL_ID=d,exports.annotations=Le,exports.background=Re,exports.backgroundActions=ze,exports.createBulkAnnotationImportBackgroundAction=Y,exports.createExternalAnnotationPageInlinePlan=O,exports.default=Fe,exports.findExternalAnnotationPageReferences=D,exports.leftPanels=Ie,exports.rewriteAnnotationTarget=A,exports.writeExternalAnnotationPageInlinePlan=k;
|
|
1
|
+
Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:`Module`}});let e=require("@manifest-editor/editors"),t=require("react-iiif-vault"),n=require("@manifest-editor/components"),r=require("@manifest-editor/shell"),i=require("react/jsx-runtime"),a=require("react"),o=require("zustand"),s=require("@iiif/helpers/vault/actions"),c=require("@iiif/parser/presentation-2");const l=`@manifest-editor/annotations`,u=`@manifest-editor/canvas-annotation-listing`,d=`@manifest-editor/canvas-annotations`,f=`@manifest-editor/annotations/bulk-import-pages`;function p(e){return(0,i.jsx)(`svg`,{xmlns:`http://www.w3.org/2000/svg`,width:`1em`,height:`1em`,viewBox:`0 0 24 24`,...e,children:(0,i.jsx)(`path`,{fill:`currentColor`,d:`M20 2H4c-1.1 0-1.99.9-1.99 2L2 22l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2m0 14H5.17l-.59.59l-.58.58V4h16zm-9.5-2H18v-2h-5.5zm3.86-5.87c.2-.2.2-.51 0-.71l-1.77-1.77c-.2-.2-.51-.2-.71 0L6 11.53V14h2.47z`})})}function m(e){return(0,i.jsx)(`svg`,{xmlns:`http://www.w3.org/2000/svg`,width:`1em`,height:`1em`,viewBox:`0 0 24 24`,...e,children:(0,i.jsx)(`path`,{fill:`currentColor`,d:`M9 22a1 1 0 0 1-1-1v-3H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2h-6.1l-3.7 3.71c-.2.19-.45.29-.7.29zm1-6v3.08L13.08 16H20V4H4v12zm1-10h2v3h3v2h-3v3h-2v-3H8V9h3z`})})}const h=[{id:`@manifest-editor/ocr-docling/run-ocr`,label:`Run Local OCR`,preparingLabel:`Preparing OCR`,queuedLabel:`OCR queued`,pendingLabel:`OCR in progress`},{id:`@manifest-editor/remote-inference/action`,label:`Run remote OCR`,preparingLabel:`Preparing local OCR`,queuedLabel:`OCR queued`,pendingLabel:`OCR in progress`},{id:`@manifest-editor/remote-inference/structured-output`,label:`Run structured output`,preparingLabel:`Preparing structured output`,queuedLabel:`Structured output queued`,pendingLabel:`Structured output in progress`}];function g(){let e=(0,r.useBackgroundActionsStoreApi)(),a=(0,r.useAvailableBackgroundActions)(),o=(0,t.useCanvas)(),s=(0,r.useCanvasProgressStatus)(o),c=a.flatMap(e=>e.actions),l=h.map(e=>{let t=c.find(t=>t.definition.id===e.id);return t?{...e,action:t}:null}).filter(e=>!!e);if(!l.length)return null;let u=l.find(({action:e})=>{let t=e.instance?.status;return t!==`preparing`&&t!==`running`?!1:s===`queued`||s===`pending`||e.context.currentCanvas?.id===o?.id});return(0,i.jsxs)(`div`,{className:`mt-5 flex w-full flex-col items-stretch gap-2 border-t border-gray-200 pt-4`,children:[(0,i.jsx)(`div`,{className:`text-center text-xs font-semibold uppercase tracking-wide text-gray-500`,children:`OCR and structured output`}),u?(0,i.jsxs)(`div`,{className:`rounded border border-amber-200 bg-amber-50 px-3 py-2 text-center text-sm text-amber-800`,children:[(0,i.jsx)(`div`,{className:`font-medium`,children:s===`queued`?u.queuedLabel:s===`pending`?u.pendingLabel:u.preparingLabel}),(0,i.jsx)(`div`,{className:`mt-1 text-xs text-amber-700`,children:u.action.instance?.statusText||u.label})]}):null,u?null:l.map(({id:t,label:a,action:o})=>{let s=o.instance?.status===`preparing`||o.instance?.status===`running`;return(0,i.jsx)(n.ActionButton,{large:!0,isDisabled:s,onPress:()=>{s||(0,r.runBackgroundAction)({store:e,context:o.context,prepareData:{scope:`selected`}})},children:a},t)})]})}function _(){let a=(0,e.useInStack)(`Canvas`)?.resource.source?.id,o=(0,t.useCanvas)({id:a}),s=(0,r.useInlineCreator)(),c=()=>{o&&s.create(`@manifest-editor/empty-annotation-page`,{label:{en:[`Inline annotations`]}},{target:{id:o.id,type:`Canvas`},targetType:`AnnotationPage`,parent:{property:`annotations`,resource:{id:o.id,type:`Canvas`}}})};return(0,i.jsxs)(n.Sidebar,{children:[(0,i.jsx)(n.SidebarHeader,{title:`Annotations`,actions:[{icon:(0,i.jsx)(m,{className:`text-2xl`}),title:`Add annotation`,disabled:!0,onClick:()=>void 0}]}),(0,i.jsx)(n.SidebarContent,{children:(0,i.jsxs)(`div`,{className:`flex flex-col items-center justify-center p-4`,children:[(0,i.jsx)(`div`,{className:`p-4 opacity-50 text-center`,children:`This canvas does not yet have any inline annotations. To add inline annotations, an AnnotationPage is created which will be linked to this canvas, and can then used to add your annotations. Simply use the link below to start adding your annotations`}),(0,i.jsxs)(n.ActionButton,{large:!0,primary:!0,onPress:()=>c(),children:[(0,i.jsx)(n.AddIcon,{className:`text-xl`}),` Create empty page`]}),(0,i.jsx)(g,{})]})})]})}function ee(){let n=(0,t.useAnnotation)(),a=(0,t.useCanvas)(),s=(0,t.useAtlasStore)(),{edit:c}=(0,r.useLayoutActions)(),l=(0,o.useStore)(s,e=>a?.id?e.canvasViewports[a.id]:null);return!n||!a||!l?null:(0,i.jsxs)(`div`,{className:`p-2`,children:[(0,i.jsx)(t.LocaleString,{as:`div`,defaultText:(0,i.jsx)(`span`,{className:`opacity-50`,children:`Untitled`}),className:`whitespace-nowrap overflow-ellipsis w-full overflow-x-hidden`,children:n?.label}),(0,i.jsx)(t.LocaleString,{className:`text-gray-500 text-sm bg-white line-clamp-2 mb-4`,as:`div`,children:n?.summary}),(0,i.jsx)(e.CanvasTargetContext,{children:(0,i.jsx)(e.AnnotationPreview,{viewport:l,onClick:()=>c(n,void 0,{forceOpen:!0})})})]})}function v(){let{isPending:o,cancelRequest:s,busy:c,requestAnnotationFromTarget:l,deleteAnnotation:u}=(0,e.useAnnotationEditor)(),[d,{highlightProps:f,annotationTarget:p}]=(0,e.useAnnotationInfo)(),{edit:m}=(0,r.useLayoutActions)(),h=d?.body||[],g=!d||h.length===0,[_,v]=(0,a.useState)(!1);return(0,i.jsxs)(`div`,{...f,className:`border border-gray-300 hover:border-me-500 shadow-sm rounded bg-white relative`,children:[(0,i.jsx)(`div`,{className:`relative`,children:p?(0,i.jsx)(t.AnnotationContext,{annotation:p,children:(0,i.jsx)(ee,{})}):g?(0,i.jsx)(`div`,{className:`flex items-center justify-center px-4 py-6 text-gray-400 text-sm`,children:`This annotation has no body.`}):_?(0,i.jsx)(e.HTMLAnnotationEditor,{className:`border-none`}):(0,i.jsx)(n.HTMLAnnotationBodyRender,{className:`px-3 pt-3 line-clamp-3 prose-p:text-slate-600`,locale:`en`})}),(0,i.jsxs)(`div`,{className:`flex gap-2 p-2`,children:[p?(0,i.jsx)(n.ActionButton,{onPress:()=>m({id:p,type:`Annotation`},void 0,{forceOpen:!0}),children:`Edit painting annotation`}):_&&o?(0,i.jsxs)(n.ActionButton,{primary:!0,onPress:()=>{v(!1),s()},children:[(0,i.jsx)(n.CheckIcon,{}),` Finish editing`]}):(0,i.jsxs)(n.ActionButton,{isDisabled:c,onPress:()=>{v(!0),l().then(()=>{v(!1)})},children:[(0,i.jsx)(n.EditTextIcon,{}),` `,g?`Edit target`:`Edit`]}),(0,i.jsxs)(n.ActionButton,{className:`gap-2 flex`,onPress:()=>u(),children:[(0,i.jsx)(n.DeleteIcon,{}),` Delete`]})]})]})}function y(){let r=(0,t.useCanvas)(),a=(0,t.useAnnotationPage)(),{requestAnnotation:o,isActive:s,busy:c,cancelRequest:l}=(0,t.useRequestAnnotation)(),[u]=(0,t.useRenderingStrategy)();if(u.type!==`images`)return(0,i.jsx)(`div`,{children:`Not supported`});if(!a)return null;let d=()=>o({type:`box`,annotationPopup:(0,i.jsx)(e.AnnotationCreationPopup,{annotationPageId:a.id,canvasId:r.id})});return(0,i.jsxs)(n.Sidebar,{children:[(0,i.jsx)(n.SidebarHeader,{title:`Annotations`,actions:[{icon:(0,i.jsx)(m,{className:`text-2xl`}),title:`Add annotation`,disabled:s||c,onClick:d}]}),s?(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(`button`,{"aria-label":`cancel add annotation`,className:`m-2 rounded border border-gray-300 bg-white px-3 py-2 text-sm text-gray-700`,type:`button`,onClick:()=>l(),children:`Exit edit mode`}),(0,i.jsxs)(`div`,{className:`flex flex-col gap-5 text-center p-4 items-center justify-center`,children:[(0,i.jsx)(n.TargetIcon,{className:`w-32 h-32 text-gray-300`}),(0,i.jsx)(`p`,{className:`text-gray-500`,children:`Draw a box on the canvas`})]})]}):null,(0,i.jsxs)(n.SidebarContent,{className:`w-full p-2 flex flex-col gap-2`,children:[a.items.map(e=>(0,i.jsx)(t.AnnotationContext,{annotation:e.id,children:(0,i.jsx)(v,{})},e.id)),!s&&a.items.length===0?(0,i.jsxs)(`div`,{className:`flex flex-col items-center justify-center p-4`,children:[(0,i.jsx)(`div`,{className:`p-4 opacity-50 text-center`,children:`This canvas does not yet have any inline annotations.`}),(0,i.jsxs)(n.ActionButton,{large:!0,primary:!0,isDisabled:s,onPress:()=>d(),children:[(0,i.jsx)(m,{className:`text-xl`}),` Add annotation`]}),(0,i.jsx)(g,{})]}):null]})]})}const te={id:u,label:`Annotations`,icon:(0,i.jsx)(p,{}),focusedMode:{closeOnMainPanelClick:!1},render:()=>(0,i.jsx)(ne,{})};function ne(){let n=(0,e.useInStack)(`Canvas`)?.resource.source?.id,r=(0,t.useCanvas)({id:n}),a=r?.annotations[0];return r?a?(0,i.jsx)(t.AnnotationPageContext,{annotationPage:a.id,children:(0,i.jsx)(t.CanvasContext,{canvas:r.id,children:(0,i.jsx)(y,{})})}):(0,i.jsx)(t.CanvasContext,{canvas:r.id,children:(0,i.jsx)(_,{})}):(0,i.jsxs)(`div`,{className:`flex flex-col gap-5 text-center p-4 items-center justify-center`,children:[(0,i.jsx)(p,{className:`w-32 h-32 text-gray-300`}),(0,i.jsx)(`p`,{className:`text-gray-500`,children:`Annotations are associated with Canvases in a IIIF Manifest. To view or add annotations, first create a Canvas and then select the Annotations link`})]})}const re={id:d,label:`Canvas annotations`,render:()=>(0,i.jsx)(ie,{})};function ie(){let n=(0,t.useCanvas)(),a=(0,r.useAtlasStore)(),s=(0,o.useStore)(a,e=>e.tool.enabled),{leftPanel:c}=(0,r.useLayoutState)(),l=c.current===u,d=n?.annotations[0];return!n||s||!d||!l?null:(0,i.jsx)(t.AnnotationPageContext,{annotationPage:d.id,children:(0,i.jsx)(e.ViewerAnnotationPage,{})})}const b=`@manifest-editor/annotations:bulk-import-config`,ae=[`commenting`,`supplementing`,`tagging`,`describing`,`linking`,`painting`,`highlighting`,`classifying`,`identifying`,`replying`];function oe(e){return new Promise(t=>{if(e.signal?.aborted){t(!1);return}let n=!1,r=r=>{n||(n=!0,e.signal?.removeEventListener(`abort`,i),t(r))},i=()=>r(!1);e.signal?.addEventListener(`abort`,i,{once:!0}),window.dispatchEvent(new CustomEvent(b,{detail:{...e,resolve:r}}))})}function se(e){return(0,i.jsx)(S,{actionId:e})}function x(){return{scope:`all`,motivationMode:`all`,motivations:[]}}function S({actionId:e}){let[t,r]=(0,a.useState)(null),[o,s]=(0,a.useState)(x()),[c,l]=(0,a.useState)(``);(0,a.useEffect)(()=>{let t=t=>{let n=t.detail;n?.actionId===e&&(r(n),s(C(n.defaults,n.tags)),l(``))};return window.addEventListener(b,t),()=>window.removeEventListener(b,t)},[e]),(0,a.useEffect)(()=>{if(!t?.signal)return;if(t.signal.aborted){r(null);return}let e=()=>r(null);return t.signal.addEventListener(`abort`,e,{once:!0}),()=>t.signal?.removeEventListener(`abort`,e)},[t]);let u=(0,a.useMemo)(()=>t?.tags.find(e=>e.key===o.tagKey),[t?.tags,o.tagKey]),d=o.scope===`tag`?u?.externalPageCount||0:t?.totalExternalPages||0,f=(0,a.useMemo)(()=>ce(o,c),[c,o]),p=o.motivationMode===`selected`&&f.length===0;if(!t)return null;let m=e=>{t.resolve(e),r(null)},h=!t.tags.length;return(0,i.jsx)(n.Modal,{title:`Import External Annotation Pages`,onClose:()=>m(!1),className:`max-w-2xl`,actions:(0,i.jsxs)(`div`,{className:`flex gap-2`,children:[(0,i.jsx)(`button`,{type:`button`,className:`rounded border border-zinc-300 bg-white px-3 py-2 text-sm text-zinc-700`,onClick:()=>m(!1),children:`Cancel`}),(0,i.jsx)(`button`,{type:`button`,className:`rounded border border-me-primary-500 bg-me-primary-500 px-3 py-2 text-sm text-white disabled:cursor-not-allowed disabled:opacity-50`,disabled:d===0||p,onClick:()=>m({...o,motivations:o.motivationMode===`selected`?f:[]}),children:`Import pages`})]}),children:(0,i.jsxs)(`div`,{className:`flex min-h-0 flex-col gap-4 p-4 text-sm text-zinc-700`,children:[(0,i.jsxs)(`fieldset`,{className:`grid gap-2`,children:[(0,i.jsx)(`legend`,{className:`font-medium text-zinc-900`,children:`Canvases`}),(0,i.jsxs)(`label`,{className:`flex items-center gap-2`,children:[(0,i.jsx)(`input`,{type:`radio`,checked:o.scope===`all`,onChange:()=>s(e=>({...e,scope:`all`}))}),(0,i.jsxs)(`span`,{children:[`All canvases with external annotation pages (`,t.totalExternalPages,`)`]})]}),(0,i.jsxs)(`label`,{className:`flex items-center gap-2`,children:[(0,i.jsx)(`input`,{type:`radio`,checked:o.scope===`tag`,disabled:h,onChange:()=>s(e=>({...e,scope:`tag`,tagKey:e.tagKey||t.tags[0]?.key}))}),(0,i.jsx)(`span`,{children:`Only canvases with tag`})]}),(0,i.jsx)(`select`,{className:`rounded border border-zinc-300 bg-white p-2 disabled:bg-zinc-100`,disabled:o.scope!==`tag`||h,value:o.tagKey||``,onChange:e=>s(t=>({...t,tagKey:e.target.value})),children:t.tags.map(e=>(0,i.jsxs)(`option`,{value:e.key,children:[e.label,` (`,e.externalPageCount,`)`]},e.key))})]}),(0,i.jsxs)(`fieldset`,{className:`grid gap-2`,children:[(0,i.jsx)(`legend`,{className:`font-medium text-zinc-900`,children:`Motivations`}),(0,i.jsxs)(`label`,{className:`flex items-center gap-2`,children:[(0,i.jsx)(`input`,{type:`radio`,checked:o.motivationMode===`all`,onChange:()=>s(e=>({...e,motivationMode:`all`}))}),(0,i.jsx)(`span`,{children:`All motivations`})]}),(0,i.jsxs)(`label`,{className:`flex items-center gap-2`,children:[(0,i.jsx)(`input`,{type:`radio`,checked:o.motivationMode===`selected`,onChange:()=>s(e=>({...e,motivationMode:`selected`,motivations:e.motivations.length?e.motivations:[`commenting`]}))}),(0,i.jsx)(`span`,{children:`Only selected motivations`})]}),(0,i.jsx)(`div`,{className:`grid grid-cols-2 gap-2 rounded border border-zinc-200 p-3`,children:ae.map(e=>(0,i.jsxs)(`label`,{className:`flex items-center gap-2`,children:[(0,i.jsx)(`input`,{type:`checkbox`,disabled:o.motivationMode!==`selected`,checked:o.motivations.includes(e),onChange:t=>s(n=>({...n,motivationMode:`selected`,motivations:t.target.checked?w([...n.motivations,e]):n.motivations.filter(t=>t!==e)}))}),(0,i.jsx)(`span`,{children:e})]},e))}),(0,i.jsxs)(`label`,{className:`grid gap-1`,children:[(0,i.jsx)(`span`,{className:`font-medium text-zinc-900`,children:`Additional motivations`}),(0,i.jsx)(`input`,{type:`text`,className:`rounded border border-zinc-300 p-2`,disabled:o.motivationMode!==`selected`,value:c,placeholder:`transcribing, reviewing`,onChange:e=>l(e.target.value)})]})]}),(0,i.jsxs)(`div`,{className:`rounded border border-zinc-200 bg-white p-3 text-zinc-600`,children:[d,` external annotation page`,d===1?``:`s`,` selected.`,o.motivationMode===`selected`?(0,i.jsxs)(i.Fragment,{children:[` `,f.length,` motivation`,f.length===1?``:`s`,` selected.`]}):null]})]})})}function C(e,t){let n=e.tagKey?t.some(t=>t.key===e.tagKey):!1;return{scope:e.scope===`tag`&&t.length?`tag`:`all`,tagKey:n?e.tagKey:t[0]?.key,motivationMode:e.motivationMode===`selected`?`selected`:`all`,motivations:w(e.motivations||[])}}function ce(e,t){return e.motivationMode===`selected`?w([...e.motivations,...le(t)]):[]}function le(e){return e.split(/[,\n]/).map(e=>e.trim()).filter(Boolean)}function w(e){return Array.from(new Set(e.map(e=>e.trim()).filter(Boolean)))}const T=`iiif-parser:isExternal`,E=`iiif-parser:hasPart`,ue=[`Annotation`,`AnnotationPage`,`ContentResource`,`Canvas`,`Manifest`,`Range`];function D(e,t){let n=[];for(let r of t)!r?.id||!Array.isArray(r.annotations)||r.annotations.forEach((t,i)=>{let a=B(t);if(!a)return;let o=e.get({id:a,type:`AnnotationPage`})||e.get(t)||t;de(o)&&n.push({key:`${r.id}:annotations:${i}:${a}`,canvasId:r.id,canvasLabel:be(r.label)||r.id,pageId:a,annotationPageIndex:i,existingPage:o})});return n}function O(e){let t=[],n=[],r=[],i=new Set,a=me(e.motivationFilter),o=0;for(let s of e.loadedPages){let{reference:e}=s;if(i.has(e.pageId)){n.push(j(e,`External annotation page is referenced more than once.`));continue}if(i.add(e.pageId),s.error){n.push(j(e,s.error));continue}let c=fe(s.json,e);if(c.warning&&r.push(c.warning),!c.page){n.push(j(e,c.error));continue}let l=c.page;if(!Array.isArray(l.items)){n.push(j(e,`Fetched annotation page does not contain an items array.`));continue}let u=l.items.filter(e=>e?.type===`Annotation`),d=u.filter(e=>he(e,a)),f=l.items.length-u.length,p=u.length-d.length;if(f&&r.push(`${e.pageId}: skipped ${f} non-Annotation item${f===1?``:`s`}.`),p&&r.push(`${e.pageId}: skipped ${p} annotation${p===1?``:`s`} outside the selected motivation filter.`),!d.length){n.push(j(e,pe(l.items.length,u.length,a)));continue}o+=d.length,t.push({reference:e,page:l,annotations:d,skippedAnnotations:f,skippedByMotivation:p})}return{totalExternalPages:e.loadedPages.length,totalAnnotations:o,pages:t,skippedPages:n,warnings:r,errors:[]}}function k(e,t){let n={AnnotationPage:{},Annotation:{},ContentResource:{}},r=[],i=ve(e),a=new Set,o=0;for(let e of t.pages){let{reference:t}=e,c=t.pageId,l=W(e.page);l.id=c,l.type=`AnnotationPage`,l.items=[],l[T]=!1,t.existingPage?.[E]&&(l[E]=W(t.existingPage[E])),n.AnnotationPage[c]=l,a.add(t.canvasId),r.push((0,s.modifyEntityField)({id:c,type:`AnnotationPage`,key:T,value:!1}));for(let a of e.annotations){let e=W(a),l=i.preserveOrCreate(B(e),`Annotation`,t.canvasId,`external-annotation`),u=F(e.body,i,t.canvasId,l);e.id=l,e.type=`Annotation`,e.body=u.body,e.target=A(e.target,t.canvasId),Object.assign(n.ContentResource,u.entities),n.Annotation[l]=e,r.push((0,s.addReference)({id:c,type:`AnnotationPage`,key:`items`,reference:{id:l,type:`Annotation`}})),o+=1}}let c=[(0,s.importEntities)({entities:Se(n)}),...r];return(r.length||Object.values(n).some(e=>Object.keys(e).length))&&e.dispatch((0,s.batchActions)({actions:c})),{totalExternalPages:t.totalExternalPages,pagesInlined:t.pages.length,canvasesUpdated:a.size,annotationsWritten:o,skippedPages:t.skippedPages,warnings:t.warnings}}function A(e,t){if(Array.isArray(e))return e.map(e=>A(e,t));if(typeof e==`string`)return z(e,t);if(!e||typeof e!=`object`)return e;let n=W(e);return typeof n.source==`string`?(n.source=z(n.source,t),n):n.source&&typeof n.source==`object`?(n.source={...n.source,id:t,type:n.source.type||`Canvas`},n):(typeof n.id==`string`&&(n.id=z(n.id,t)),n)}function de(e){return!!e?.[T]}function j(e,t){return{key:e.key,canvasId:e.canvasId,canvasLabel:e.canvasLabel,pageId:e.pageId,reason:t}}function fe(e,t){if(!e||typeof e!=`object`)return{error:`Fetched resource is not a JSON object.`};let n=e;if(n.type===`AnnotationPage`)return{page:n,error:``};if(P(n))try{let e=(0,c.convertPresentation2)(n);return e?.type===`AnnotationPage`?{page:e,error:``,warning:`${t.pageId}: upgraded Presentation 2 sc:AnnotationList to AnnotationPage.`}:{error:`IIIF upgrade produced ${e?.type||`missing a type`}, not AnnotationPage.`}}catch(e){return{error:`Unable to upgrade Presentation 2 sc:AnnotationList: ${e instanceof Error?e.message:String(e)}`}}return{error:`Fetched resource is ${n.type||n[`@type`]||`missing a type`}, not AnnotationPage.`}}function pe(e,t,n){return e?t?n?.size?`No annotations matched the selected motivation filter (${Array.from(n).join(`, `)}).`:`Fetched annotation page does not contain importable annotations.`:`Fetched annotation page does not contain Annotation items.`:`Fetched annotation page is empty.`}function me(e){let t=H((e||[]).map(N).filter(Boolean));return t.length?new Set(t):null}function he(e,t){return!t?.size||M(e).some(e=>t.has(e))}function M(e){return H(U(e?.motivation).map(N).filter(Boolean))}function N(e){if(typeof e!=`string`)return``;let t=e.trim().toLowerCase(),n=t.includes(`:`)?t.slice(t.lastIndexOf(`:`)+1):t,r=n.lastIndexOf(`/`),i=n.lastIndexOf(`#`),a=Math.max(r,i);return a>=0?n.slice(a+1):n}function P(e){let t=e?.[`@type`]||e?.type;return t===`sc:AnnotationList`||t===`AnnotationList`}function F(e,t,n,r){let i=e==null?[]:U(e),a={};return{body:i.length>1&&i.every(_e)?[L({type:`Choice`,items:i},t,n,r,`body-choice`,a)]:i.map((e,i)=>I(e,t,n,r,`body-${i+1}`,a)),entities:a}}function I(e,t,n,r,i,a){if(ge(e))return L(e,t,n,r,i,a);let o=t.preserveOrCreate(e&&typeof e==`object`?B(e):void 0,`ContentResource`,n,`${r}-${i}`);if(typeof e==`string`)return a[o]={id:o,type:`TextualBody`,format:`text/plain`,value:e},{id:o,type:`ContentResource`};if(e&&typeof e==`object`){let t=R(e);return a[o]={...t,id:o,type:t.type||`ContentResource`},{id:o,type:`ContentResource`}}return a[o]={id:o,type:`TextualBody`,format:`text/plain`,value:String(e)},{id:o,type:`ContentResource`}}function L(e,t,n,r,i,a){let o=t.preserveOrCreate(B(e),`ContentResource`,n,`${r}-${i}`),s=U(e.items).map((e,o)=>I(e,t,n,r,`${i}-item-${o+1}`,a));return a[o]={...W(e),id:o,type:`Choice`,items:s},{id:o,type:`ContentResource`}}function R(e){let t=W(e);return typeof t.chars==`string`&&t.value===void 0&&(t.value=t.chars,delete t.chars,t.type===`Text`&&(t.type=`TextualBody`)),t}function ge(e){return!!e&&typeof e==`object`&&e.type===`Choice`}function _e(e){if(typeof e==`string`)return!0;if(!e||typeof e!=`object`)return!1;let t=e.type;return t===`TextualBody`||t===`Text`}function ve(e){let t=new Set,n=0;function r(n){return t.has(n)?!0:ue.some(t=>!!e.get({id:n,type:t}))}function i(e,i,a){let o;do n+=1,o=`${xe(e)}/external-annotation-pages/${G(i)}/${G(a)}-${n}`;while(r(o));return t.add(o),o}function a(e,n,a,o){return e&&!r(e)?(t.add(e),e):i(a,n,o)}return{create:i,preserveOrCreate:a}}function ye(e){let t=e.indexOf(`#`);return{sourceId:t>=0?e.slice(0,t):e,fragment:t>=0?e.slice(t):``}}function z(e,t){return`${t}${ye(e).fragment}`}function B(e){if(typeof e==`string`)return e;if(!(!e||typeof e!=`object`))return typeof e.id==`string`?e.id:typeof e[`@id`]==`string`?e[`@id`]:void 0}function V(e){return e?typeof e==`string`?[e]:Array.isArray(e)?e.filter(e=>typeof e==`string`):typeof e==`object`?Object.values(e).flatMap(V):[]:[]}function be(e){return V(e)[0]||``}function H(e){return Array.from(new Set(e.filter(Boolean)))}function U(e){return Array.isArray(e)?e:e==null?[]:[e]}function W(e){return JSON.parse(JSON.stringify(e))}function G(e){return e.toLowerCase().replace(/[^a-z0-9]+/g,`-`).replace(/^-+|-+$/g,``).slice(0,80)||`item`}function xe(e){return e.endsWith(`/`)?e.slice(0,-1):e}function Se(e){return Object.fromEntries(Object.entries(e).filter(([,e])=>Object.keys(e).length))}const K=`@manifest-editor/annotations:bulk-import-results`;function Ce(e,t){window.dispatchEvent(new CustomEvent(K,{detail:{actionId:e,result:t}}))}function we(e){return(0,i.jsx)(Te,{actionId:e})}function Te({actionId:e}){let[t,r]=(0,a.useState)(null);return(0,a.useEffect)(()=>{let t=t=>{let n=t.detail;n?.actionId===e&&n.result&&r(n.result)};return window.addEventListener(K,t),()=>window.removeEventListener(K,t)},[e]),t?(0,i.jsx)(n.Modal,{title:`External annotation page import results`,onClose:()=>r(null),className:`max-w-3xl`,children:(0,i.jsxs)(`div`,{className:`flex min-h-0 flex-col gap-4 p-4 text-sm text-zinc-700`,children:[(0,i.jsxs)(`div`,{className:`grid grid-cols-4 gap-2`,children:[(0,i.jsx)(q,{label:`External pages`,value:t.totalExternalPages}),(0,i.jsx)(q,{label:`Inlined pages`,value:t.pagesInlined}),(0,i.jsx)(q,{label:`Canvases`,value:t.canvasesUpdated}),(0,i.jsx)(q,{label:`Annotations`,value:t.annotationsWritten})]}),t.warnings.length?(0,i.jsx)(`div`,{className:`rounded border border-amber-200 bg-amber-50 p-3 text-amber-900`,children:t.warnings.map(e=>(0,i.jsx)(`div`,{children:e},e))}):null,t.skippedPages.length?(0,i.jsxs)(`div`,{className:`rounded border border-zinc-200`,children:[(0,i.jsx)(`div`,{className:`border-b border-zinc-200 bg-zinc-50 px-3 py-2 font-medium`,children:`Skipped external pages`}),(0,i.jsx)(`div`,{className:`max-h-64 overflow-auto`,children:t.skippedPages.map(e=>(0,i.jsxs)(`div`,{className:`grid gap-1 border-b border-zinc-100 px-3 py-2 last:border-0`,children:[(0,i.jsx)(`div`,{className:`truncate font-medium text-zinc-900`,children:e.pageId}),(0,i.jsx)(`div`,{className:`truncate text-zinc-500`,children:e.canvasLabel}),(0,i.jsx)(`div`,{className:`text-zinc-500`,children:e.reason})]},e.key))})]}):null]})}):null}function q({label:e,value:t}){return(0,i.jsxs)(`div`,{className:`rounded border border-zinc-200 bg-zinc-50 p-3`,children:[(0,i.jsx)(`div`,{className:`text-xl font-semibold text-zinc-900`,children:t}),(0,i.jsx)(`div`,{className:`text-xs uppercase tracking-wide text-zinc-500`,children:e})]})}const J=new Map;function Y(e={}){let t=e.fetchPage||Ee,n=e.requestConfig||De;return{id:f,label:`Bulk Annotation Page Importer`,summary:`Load external Canvas annotation pages and make them editable inline`,section:`Annotations`,order:10,resourceTypes:[`Manifest`],resumable:!1,render:e=>(0,i.jsxs)(i.Fragment,{children:[se(e.definition.id),we(e.definition.id)]}),onResults:e=>Ce(e.definition.id,e.instance?.result),supports:e=>D(e.vault,X(e)).length>0,prepare:async e=>{let t=D(e.vault,X(e));if(!t.length)return!1;let r=await n(e,t,x());if(r===!1)return!1;let i=Z(e,t,r);return i.length?(J.set(e.instanceKey,{references:i,options:r}),!0):!1},run:async e=>{let n=J.get(e.instanceKey),r=n?.options||x(),i=n?.references||Z(e,D(e.vault,X(e)),r);try{if(e.setActionLabel(`Importing external annotation pages`),e.setActionProgress({current:0,total:Math.max(i.length,1),label:`Loading external annotation pages`}),!i.length)return e.setActionStatus(`running`,`No external annotation pages found`),Ae();let n=[];for(let[r,a]of i.entries()){$(e.signal),e.setActionStatus(`running`,`Loading ${r+1}/${i.length}`),e.appendActionLog(`Loading external annotation page`,`info`,{canvasId:a.canvasId,pageId:a.pageId});try{let r=await t(a.pageId,a,e);n.push({reference:a,json:r})}catch(t){let r=je(t);n.push({reference:a,error:r}),e.appendActionLog(`Failed to load external annotation page`,`warn`,{canvasId:a.canvasId,pageId:a.pageId,reason:r})}e.setActionProgress({current:r+1,total:i.length,label:`Loading external annotation pages`})}let a=O({loadedPages:n,motivationFilter:r.motivationMode===`selected`?r.motivations:void 0});if(a.errors.length)throw Error(a.errors[0]||`External annotation page import failed.`);e.setActionStatus(`running`,`Writing inline annotation pages`),e.setActionProgress({current:0,total:Math.max(a.totalAnnotations,a.pages.length,1),label:`Writing inline annotations`});let o=k(e.vault,a);return e.appendActionLog(`External annotation page import complete`,`info`,{pages:o.pagesInlined,annotations:o.annotationsWritten,skipped:o.skippedPages.length}),e.setActionStatus(`running`,`Imported ${o.pagesInlined}/${o.totalExternalPages} external pages`),e.setActionProgress({current:Math.max(o.annotationsWritten,o.pagesInlined),total:Math.max(o.annotationsWritten,o.pagesInlined,1),label:`Import complete`}),o}finally{J.delete(e.instanceKey)}}}}async function Ee(e,t,n){let r=await fetch(e,{signal:n.signal,headers:{Accept:`application/ld+json, application/json;q=0.9, */*;q=0.1`}});if(!r.ok)throw Error(`Unable to fetch ${e} (${r.status}).`);return r.json()}async function De(e,t,n){return oe({actionId:e.definition.id,instanceKey:e.instanceKey,totalExternalPages:t.length,tags:Oe(e,t),defaults:n,signal:e.signal})}function X(e){let t=e.vault.get(e.target);return t?.items?(e.vault.get(t.items)||[]).filter(Boolean):[]}function Z(e,t,n){if(n.scope!==`tag`||!n.tagKey)return t;let r=ke(n.tagKey);return r?t.filter(t=>e.tags.hasTag({id:t.canvasId,type:`Canvas`},r.type,r.id)):[]}function Oe(e,t){let n=new Map,i=new Map;n.set(Q(r.FLAG_TAG),{...r.FLAG_TAG,key:Q(r.FLAG_TAG),canvasCount:0,externalPageCount:0});for(let e of t)i.set(e.canvasId,(i.get(e.canvasId)||0)+1);for(let[t,r]of i)for(let i of e.tags.getTags({id:t,type:`Canvas`})){let e=Q(i),t=n.get(e);t?(t.canvasCount+=1,t.externalPageCount+=r):n.set(e,{...i,key:e,canvasCount:1,externalPageCount:r})}return Array.from(n.values()).sort((e,t)=>e.type===r.FLAG_TAG.type&&e.id===r.FLAG_TAG.id?-1:t.type===r.FLAG_TAG.type&&t.id===r.FLAG_TAG.id?1:e.label.localeCompare(t.label)||e.type.localeCompare(t.type)||e.id.localeCompare(t.id))}function Q(e){return`${e.type}:${e.id}`}function ke(e){let t=e.indexOf(`:`);return t===-1?null:{type:e.slice(0,t),id:e.slice(t+1)}}function Ae(){return{totalExternalPages:0,pagesInlined:0,canvasesUpdated:0,annotationsWritten:0,skippedPages:[],warnings:[]}}function $(e){if(e.aborted)throw new DOMException(`Aborted`,`AbortError`)}function je(e){return e instanceof Error?e.message:String(e||`Unknown error`)}const Me={id:`@manifest-editor/annotations-routing`,label:`Annotation routing`,render:()=>(0,i.jsx)(Ne,{})};function Ne(){let n=(0,t.useManifest)(),i=(0,e.useInStack)(`Canvas`),o=(0,r.useLayoutMode)(),{leftPanel:s,rightPanel:c}=(0,r.useLayoutState)(),{edit:l,open:u,rightPanel:d}=(0,r.useLayoutActions)(),f=(0,a.useRef)(null),[p,m]=(0,a.useState)(!1);return(0,a.useEffect)(()=>{let e=i?.resource?.source?.id;e&&(f.current=e)},[i?.resource?.source?.id]),(0,a.useEffect)(()=>{if(s.current===`@manifest-editor/canvas-annotation-listing`){let e=f.current||n?.items?.[0]?.id;if(e&&(u({id:`current-canvas`}),l({id:e,type:`Canvas`})),o===`focused`)return;c.open&&(d.close(),m(!0));return}p&&!c.open&&s.current!==`@manifest-editor/ranges-listing`&&(d.open(),m(!1))},[s.current,o]),null}var Pe={id:l,label:`Annotations`,description:`Create, view, and inline external supplemental canvas annotation pages.`,author:`Digirati`,official:!0,defaultEnabled:!0,tags:[`annotations`,`iiif`,`external-pages`],supports:{apps:[`manifest-editor`],projectTypes:[`Manifest`]}};const Fe=[te],Ie=[re],Le=[Me],Re=[Y()];exports.ANNOTATIONS_LEFT_PANEL_ID=u,exports.ANNOTATIONS_PLUGIN_ID=l,exports.BULK_ANNOTATION_IMPORT_ACTION_ID=f,exports.CANVAS_ANNOTATIONS_PANEL_ID=d,exports.annotations=Ie,exports.background=Le,exports.backgroundActions=Re,exports.createBulkAnnotationImportBackgroundAction=Y,exports.createExternalAnnotationPageInlinePlan=O,exports.default=Pe,exports.findExternalAnnotationPageReferences=D,exports.leftPanels=Fe,exports.rewriteAnnotationTarget=A,exports.writeExternalAnnotationPageInlinePlan=k;
|
|
2
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["useBackgroundActionsStoreApi","useAvailableBackgroundActions","useCanvas","useCanvasProgressStatus","ActionButton","runBackgroundAction","useInStack","useCanvas","useInlineCreator","Sidebar","SidebarHeader","SidebarContent","ActionButton","AddIcon","useAnnotation","useCanvas","useAtlasStore","useLayoutActions","useStore","LocaleString","CanvasTargetContext","AnnotationPreview","useAnnotationEditor","useAnnotationInfo","useLayoutActions","useState","AnnotationContext","HTMLAnnotationEditor","HTMLAnnotationBodyRender","ActionButton","CheckIcon","EditTextIcon","DeleteIcon","useCanvas","useAnnotationPage","useRequestAnnotation","useRenderingStrategy","AnnotationCreationPopup","Sidebar","SidebarHeader","TargetIcon","SidebarContent","AnnotationContext","ActionButton","useInStack","useCanvas","AnnotationPageContext","CanvasContext","useCanvas","useAtlasStore","useStore","useLayoutState","AnnotationPageContext","ViewerAnnotationPage","useState","useMemo","Modal","modifyEntityField","addReference","importEntities","batchActions","convertPresentation2","useState","Modal","FLAG_TAG","useManifest","useInStack","useLayoutMode","useLayoutState","useLayoutActions","useRef","useState"],"sources":["../src/constants.ts","../src/icons.tsx","../src/components/AnnotationsOcrActions.tsx","../src/components/AnnotationsCreateEmptyPage.tsx","../src/components/RenderPaintingAnnotationPreview.tsx","../src/components/AnnotationsSidebarListItem.tsx","../src/components/AnnotationsListingAnnotations.tsx","../src/annotation-panel.tsx","../src/canvas-annotations.tsx","../src/importer/config-modal.tsx","../src/importer/importer.ts","../src/importer/results.tsx","../src/importer/background-action.tsx","../src/routing-background.tsx","../src/index.ts"],"sourcesContent":["export const ANNOTATIONS_PLUGIN_ID = \"@manifest-editor/annotations\";\nexport const ANNOTATIONS_LEFT_PANEL_ID = \"@manifest-editor/canvas-annotation-listing\";\nexport const CANVAS_ANNOTATIONS_PANEL_ID = \"@manifest-editor/canvas-annotations\";\nexport const BULK_ANNOTATION_IMPORT_ACTION_ID = \"@manifest-editor/annotations/bulk-import-pages\";\n","import type { SVGProps } from \"react\";\n\nexport function AnnotationsIcon(props: SVGProps<SVGSVGElement>) {\n return (\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"1em\" height=\"1em\" viewBox=\"0 0 24 24\" {...props}>\n <path\n fill=\"currentColor\"\n d=\"M20 2H4c-1.1 0-1.99.9-1.99 2L2 22l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2m0 14H5.17l-.59.59l-.58.58V4h16zm-9.5-2H18v-2h-5.5zm3.86-5.87c.2-.2.2-.51 0-.71l-1.77-1.77c-.2-.2-.51-.2-.71 0L6 11.53V14h2.47z\"\n />\n </svg>\n );\n}\n\nexport function AddAnnotationIcon(props: SVGProps<SVGSVGElement>) {\n return (\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"1em\" height=\"1em\" viewBox=\"0 0 24 24\" {...props}>\n <path\n fill=\"currentColor\"\n d=\"M9 22a1 1 0 0 1-1-1v-3H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2h-6.1l-3.7 3.71c-.2.19-.45.29-.7.29zm1-6v3.08L13.08 16H20V4H4v12zm1-10h2v3h3v2h-3v3h-2v-3H8V9h3z\"\n />\n </svg>\n );\n}\n","import { ActionButton } from \"@manifest-editor/components\";\nimport {\n type AvailableBackgroundAction,\n runBackgroundAction,\n useAvailableBackgroundActions,\n useBackgroundActionsStoreApi,\n useCanvasProgressStatus,\n} from \"@manifest-editor/shell\";\nimport { useCanvas } from \"react-iiif-vault\";\n\nconst OCR_ACTIONS = [\n {\n id: \"@manifest-editor/ocr-docling/run-ocr\",\n label: \"Run Local OCR\",\n preparingLabel: \"Preparing OCR\",\n queuedLabel: \"OCR queued\",\n pendingLabel: \"OCR in progress\",\n },\n {\n id: \"@manifest-editor/remote-inference/action\",\n label: \"Run remote OCR\",\n preparingLabel: \"Preparing local OCR\",\n queuedLabel: \"OCR queued\",\n pendingLabel: \"OCR in progress\",\n },\n {\n id: \"@manifest-editor/remote-inference/structured-output\",\n label: \"Run structured output\",\n preparingLabel: \"Preparing structured output\",\n queuedLabel: \"Structured output queued\",\n pendingLabel: \"Structured output in progress\",\n },\n];\n\nexport function AnnotationsOcrActions() {\n const store = useBackgroundActionsStoreApi();\n const groups = useAvailableBackgroundActions();\n const canvas = useCanvas();\n const canvasProgressStatus = useCanvasProgressStatus(canvas);\n const actions = groups.flatMap((group) => group.actions);\n const availableActions = OCR_ACTIONS.map((ocrAction) => {\n const action = actions.find((item) => item.definition.id === ocrAction.id);\n return action ? { ...ocrAction, action } : null;\n }).filter(\n (\n item,\n ): item is {\n id: string;\n label: string;\n preparingLabel: string;\n queuedLabel: string;\n pendingLabel: string;\n action: AvailableBackgroundAction;\n } => !!item,\n );\n\n if (!availableActions.length) {\n return null;\n }\n\n const activeAction = availableActions.find(({ action }) => {\n const status = action.instance?.status;\n const isBusy = status === \"preparing\" || status === \"running\";\n if (!isBusy) return false;\n\n if (canvasProgressStatus === \"queued\" || canvasProgressStatus === \"pending\") {\n return true;\n }\n\n return action.context.currentCanvas?.id === canvas?.id;\n });\n\n return (\n <div className=\"mt-5 flex w-full flex-col items-stretch gap-2 border-t border-gray-200 pt-4\">\n <div className=\"text-center text-xs font-semibold uppercase tracking-wide text-gray-500\">\n OCR and structured output\n </div>\n {activeAction ? (\n <div className=\"rounded border border-amber-200 bg-amber-50 px-3 py-2 text-center text-sm text-amber-800\">\n <div className=\"font-medium\">\n {canvasProgressStatus === \"queued\"\n ? activeAction.queuedLabel\n : canvasProgressStatus === \"pending\"\n ? activeAction.pendingLabel\n : activeAction.preparingLabel}\n </div>\n <div className=\"mt-1 text-xs text-amber-700\">\n {activeAction.action.instance?.statusText || activeAction.label}\n </div>\n </div>\n ) : null}\n {activeAction\n ? null\n : availableActions.map(({ id, label, action }) => {\n const busy = action.instance?.status === \"preparing\" || action.instance?.status === \"running\";\n return (\n <ActionButton\n key={id}\n large\n isDisabled={busy}\n onPress={() => {\n if (busy) return;\n void runBackgroundAction({\n store,\n context: action.context,\n prepareData: { scope: \"selected\" },\n });\n }}\n >\n {label}\n </ActionButton>\n );\n })}\n </div>\n );\n}\n","import {\n ActionButton,\n AddIcon,\n Sidebar,\n SidebarContent,\n SidebarHeader,\n} from \"@manifest-editor/components\";\nimport { useInStack } from \"@manifest-editor/editors\";\nimport { useInlineCreator } from \"@manifest-editor/shell\";\nimport { useCanvas } from \"react-iiif-vault\";\nimport { AddAnnotationIcon } from \"../icons\";\nimport { AnnotationsOcrActions } from \"./AnnotationsOcrActions\";\n\nexport function AnnotationsCreateEmptyPage() {\n const canvasRef = useInStack(\"Canvas\");\n const canvasId = canvasRef?.resource.source?.id;\n const canvas = useCanvas({ id: canvasId });\n const creator = useInlineCreator();\n\n const createEmptyAnnotationPage = () => {\n if (!canvas) return;\n creator.create(\n \"@manifest-editor/empty-annotation-page\",\n {\n label: { en: [\"Inline annotations\"] },\n },\n {\n target: {\n id: canvas.id,\n type: \"Canvas\",\n },\n targetType: \"AnnotationPage\",\n parent: {\n property: \"annotations\",\n resource: {\n id: canvas.id,\n type: \"Canvas\",\n },\n },\n },\n );\n };\n\n return (\n <Sidebar>\n <SidebarHeader\n title=\"Annotations\"\n actions={[\n {\n icon: <AddAnnotationIcon className=\"text-2xl\" />,\n title: \"Add annotation\",\n disabled: true,\n onClick: () => void 0,\n },\n ]}\n />\n <SidebarContent>\n <div className=\"flex flex-col items-center justify-center p-4\">\n <div className=\"p-4 opacity-50 text-center\">\n This canvas does not yet have any inline annotations. To add inline\n annotations, an AnnotationPage is created which will be linked to\n this canvas, and can then used to add your annotations. Simply use\n the link below to start adding your annotations\n </div>\n\n <ActionButton\n large\n primary\n onPress={() => createEmptyAnnotationPage()}\n >\n <AddIcon className=\"text-xl\" /> Create empty page\n </ActionButton>\n\n <AnnotationsOcrActions />\n </div>\n </SidebarContent>\n </Sidebar>\n );\n}\n","import { AnnotationPreview, CanvasTargetContext } from \"@manifest-editor/editors\";\nimport { useLayoutActions } from \"@manifest-editor/shell\";\nimport { LocaleString, useAnnotation, useAtlasStore, useCanvas } from \"react-iiif-vault\";\nimport { useStore } from \"zustand\";\n\nexport function RenderPaintingAnnotationPreview() {\n const annotation = useAnnotation();\n const canvas = useCanvas();\n const store = useAtlasStore();\n const { edit } = useLayoutActions();\n const viewport = useStore(store, (state) => (canvas?.id ? state.canvasViewports[canvas.id] : null));\n\n if (!annotation || !canvas || !viewport) return null;\n\n return (\n <div className=\"p-2\">\n <LocaleString\n as=\"div\"\n defaultText={(<span className=\"opacity-50\">Untitled</span>) as any}\n className=\"whitespace-nowrap overflow-ellipsis w-full overflow-x-hidden\"\n >\n {annotation?.label}\n </LocaleString>\n <LocaleString className=\"text-gray-500 text-sm bg-white line-clamp-2 mb-4\" as=\"div\">\n {annotation?.summary}\n </LocaleString>\n <CanvasTargetContext>\n <AnnotationPreview viewport={viewport} onClick={() => edit(annotation, undefined, { forceOpen: true })} />\n </CanvasTargetContext>\n </div>\n );\n}\n","import { ActionButton, CheckIcon, DeleteIcon, EditTextIcon, HTMLAnnotationBodyRender } from \"@manifest-editor/components\";\nimport { HTMLAnnotationEditor, useAnnotationEditor, useAnnotationInfo } from \"@manifest-editor/editors\";\nimport { useLayoutActions } from \"@manifest-editor/shell\";\nimport { useState } from \"react\";\nimport { AnnotationContext } from \"react-iiif-vault\";\nimport { RenderPaintingAnnotationPreview } from \"./RenderPaintingAnnotationPreview\";\n\nexport function AnnotationsSidebarListItem() {\n const { isPending, cancelRequest, busy, requestAnnotationFromTarget, deleteAnnotation } = useAnnotationEditor();\n const [annotation, { highlightProps, annotationTarget }] = useAnnotationInfo();\n const { edit } = useLayoutActions();\n const bodies = annotation?.body || [];\n const isBodyEmpty = !annotation || bodies.length === 0;\n const [isOpen, setIsOpen] = useState(false);\n\n return (\n <div {...highlightProps} className=\"border border-gray-300 hover:border-me-500 shadow-sm rounded bg-white relative\">\n <div className=\"relative\">\n {annotationTarget ? (\n <AnnotationContext annotation={annotationTarget}>\n <RenderPaintingAnnotationPreview />\n </AnnotationContext>\n ) : isBodyEmpty ? (\n <div className=\"flex items-center justify-center px-4 py-6 text-gray-400 text-sm\">This annotation has no body.</div>\n ) : isOpen ? (\n <HTMLAnnotationEditor className=\"border-none\" />\n ) : (\n <HTMLAnnotationBodyRender className=\"px-3 pt-3 line-clamp-3 prose-p:text-slate-600\" locale=\"en\" />\n )}\n </div>\n <div className=\"flex gap-2 p-2\">\n {annotationTarget ? (\n <ActionButton onPress={() => edit({ id: annotationTarget, type: \"Annotation\" }, undefined, { forceOpen: true })}>\n Edit painting annotation\n </ActionButton>\n ) : isOpen && isPending ? (\n <ActionButton\n primary\n onPress={() => {\n setIsOpen(false);\n cancelRequest();\n }}\n >\n <CheckIcon /> Finish editing\n </ActionButton>\n ) : (\n <ActionButton\n isDisabled={busy}\n onPress={() => {\n setIsOpen(true);\n requestAnnotationFromTarget().then(() => {\n setIsOpen(false);\n });\n }}\n >\n <EditTextIcon /> {isBodyEmpty ? \"Edit target\" : \"Edit\"}\n </ActionButton>\n )}\n <ActionButton className=\"gap-2 flex\" onPress={() => deleteAnnotation()}>\n <DeleteIcon /> Delete\n </ActionButton>\n </div>\n </div>\n );\n}\n","import {\n ActionButton,\n Sidebar,\n SidebarContent,\n SidebarHeader,\n TargetIcon,\n} from \"@manifest-editor/components\";\nimport { AnnotationCreationPopup } from \"@manifest-editor/editors\";\nimport {\n AnnotationContext,\n useAnnotationPage,\n useCanvas,\n useRenderingStrategy,\n useRequestAnnotation,\n} from \"react-iiif-vault\";\nimport { AddAnnotationIcon } from \"../icons\";\nimport { AnnotationsSidebarListItem } from \"./AnnotationsSidebarListItem\";\nimport { AnnotationsOcrActions } from \"./AnnotationsOcrActions\";\n\nexport function AnnotationsListingAnnotations() {\n const canvas = useCanvas();\n const page = useAnnotationPage();\n const { requestAnnotation, isActive, busy, cancelRequest } =\n useRequestAnnotation();\n const [strategy] = useRenderingStrategy();\n\n if (strategy.type !== \"images\") {\n return <div>Not supported</div>;\n }\n\n if (!page) {\n return null;\n }\n\n const createAnnotation = () =>\n requestAnnotation({\n type: \"box\",\n annotationPopup: (\n <AnnotationCreationPopup\n annotationPageId={page.id}\n canvasId={canvas!.id}\n />\n ),\n });\n\n return (\n <Sidebar>\n <SidebarHeader\n title=\"Annotations\"\n actions={[\n {\n icon: <AddAnnotationIcon className=\"text-2xl\" />,\n title: \"Add annotation\",\n disabled: isActive || busy,\n onClick: createAnnotation,\n },\n ]}\n />\n {isActive ? (\n <>\n <button\n aria-label=\"cancel add annotation\"\n className=\"m-2 rounded border border-gray-300 bg-white px-3 py-2 text-sm text-gray-700\"\n type=\"button\"\n onClick={() => cancelRequest()}\n >\n Exit edit mode\n </button>\n <div className=\"flex flex-col gap-5 text-center p-4 items-center justify-center\">\n <TargetIcon className=\"w-32 h-32 text-gray-300\" />\n <p className=\"text-gray-500\">Draw a box on the canvas</p>\n </div>\n </>\n ) : null}\n <SidebarContent className=\"w-full p-2 flex flex-col gap-2\">\n {page.items.map((annotation) => (\n <AnnotationContext key={annotation.id} annotation={annotation.id}>\n <AnnotationsSidebarListItem />\n </AnnotationContext>\n ))}\n\n {!isActive && page.items.length === 0 ? (\n <div className=\"flex flex-col items-center justify-center p-4\">\n <div className=\"p-4 opacity-50 text-center\">\n This canvas does not yet have any inline annotations.\n </div>\n\n <ActionButton\n large\n primary\n isDisabled={isActive}\n onPress={() => createAnnotation()}\n >\n <AddAnnotationIcon className=\"text-xl\" /> Add annotation\n </ActionButton>\n\n <AnnotationsOcrActions />\n </div>\n ) : null}\n </SidebarContent>\n </Sidebar>\n );\n}\n","import { useInStack } from \"@manifest-editor/editors\";\nimport type { LayoutPanel } from \"@manifest-editor/shell\";\nimport {\n AnnotationPageContext,\n CanvasContext,\n useCanvas,\n} from \"react-iiif-vault\";\nimport { ANNOTATIONS_LEFT_PANEL_ID } from \"./constants\";\nimport { AnnotationsCreateEmptyPage } from \"./components/AnnotationsCreateEmptyPage\";\nimport { AnnotationsListingAnnotations } from \"./components/AnnotationsListingAnnotations\";\nimport { AnnotationsIcon } from \"./icons\";\n\nexport const annotationsPanel: LayoutPanel = {\n id: ANNOTATIONS_LEFT_PANEL_ID,\n label: \"Annotations\",\n icon: <AnnotationsIcon />,\n focusedMode: {\n closeOnMainPanelClick: false,\n },\n render: () => <AnnotationsPanel />,\n};\n\nfunction AnnotationsPanel() {\n const canvasRef = useInStack(\"Canvas\");\n const canvasId = canvasRef?.resource.source?.id;\n const canvas = useCanvas({ id: canvasId });\n const firstPage = canvas?.annotations[0];\n\n if (!canvas) {\n return (\n <div className=\"flex flex-col gap-5 text-center p-4 items-center justify-center\">\n <AnnotationsIcon className=\"w-32 h-32 text-gray-300\" />\n <p className=\"text-gray-500\">\n Annotations are associated with Canvases in a IIIF Manifest. To view\n or add annotations, first create a Canvas and then select the\n Annotations link\n </p>\n </div>\n );\n }\n\n if (firstPage) {\n return (\n <AnnotationPageContext annotationPage={firstPage.id}>\n <CanvasContext canvas={canvas.id}>\n <AnnotationsListingAnnotations />\n </CanvasContext>\n </AnnotationPageContext>\n );\n }\n\n return (\n <CanvasContext canvas={canvas.id}>\n <AnnotationsCreateEmptyPage />\n </CanvasContext>\n );\n}\n","import { ViewerAnnotationPage } from \"@manifest-editor/editors\";\nimport { type AnnotationPanel, useAtlasStore, useLayoutState } from \"@manifest-editor/shell\";\nimport { AnnotationPageContext, useCanvas } from \"react-iiif-vault\";\nimport { useStore } from \"zustand\";\nimport { ANNOTATIONS_LEFT_PANEL_ID, CANVAS_ANNOTATIONS_PANEL_ID } from \"./constants\";\n\nexport const canvasAnnotations: AnnotationPanel = {\n id: CANVAS_ANNOTATIONS_PANEL_ID,\n label: \"Canvas annotations\",\n render: () => <CanvasAnnotations />,\n};\n\nfunction CanvasAnnotations() {\n const canvas = useCanvas();\n const store = useAtlasStore();\n const toolEnabled = useStore(store, (state) => state.tool.enabled);\n const { leftPanel } = useLayoutState();\n const isLeftPanel = leftPanel.current === ANNOTATIONS_LEFT_PANEL_ID;\n const firstAnnotationPage = canvas?.annotations[0];\n\n if (!canvas || toolEnabled || !firstAnnotationPage || !isLeftPanel) {\n return null;\n }\n\n return (\n <AnnotationPageContext annotationPage={firstAnnotationPage.id}>\n <ViewerAnnotationPage />\n </AnnotationPageContext>\n );\n}\n","import { Modal } from \"@manifest-editor/components\";\nimport { useEffect, useMemo, useState } from \"react\";\n\nexport const BULK_ANNOTATION_IMPORT_CONFIG_EVENT =\n \"@manifest-editor/annotations:bulk-import-config\";\n\nexport const BULK_ANNOTATION_IMPORT_MOTIVATIONS = [\n \"commenting\",\n \"supplementing\",\n \"tagging\",\n \"describing\",\n \"linking\",\n \"painting\",\n \"highlighting\",\n \"classifying\",\n \"identifying\",\n \"replying\",\n] as const;\n\nexport type BulkAnnotationImportScope = \"all\" | \"tag\";\nexport type BulkAnnotationImportMotivationMode = \"all\" | \"selected\";\n\nexport type BulkAnnotationImportRunOptions = {\n scope: BulkAnnotationImportScope;\n tagKey?: string;\n motivationMode: BulkAnnotationImportMotivationMode;\n motivations: string[];\n};\n\nexport type BulkAnnotationImportTagOption = {\n key: string;\n label: string;\n canvasCount: number;\n externalPageCount: number;\n};\n\nexport type BulkAnnotationImportConfigRequest = {\n actionId: string;\n instanceKey: string;\n totalExternalPages: number;\n tags: BulkAnnotationImportTagOption[];\n defaults: BulkAnnotationImportRunOptions;\n signal?: AbortSignal;\n resolve: (options: BulkAnnotationImportRunOptions | false) => void;\n};\n\nexport function requestBulkAnnotationImportConfig(\n request: Omit<BulkAnnotationImportConfigRequest, \"resolve\">,\n): Promise<BulkAnnotationImportRunOptions | false> {\n return new Promise((resolve) => {\n if (request.signal?.aborted) {\n resolve(false);\n return;\n }\n\n let settled = false;\n const settle = (options: BulkAnnotationImportRunOptions | false) => {\n if (settled) {\n return;\n }\n\n settled = true;\n request.signal?.removeEventListener(\"abort\", handleAbort);\n resolve(options);\n };\n const handleAbort = () => settle(false);\n\n request.signal?.addEventListener(\"abort\", handleAbort, { once: true });\n window.dispatchEvent(\n new CustomEvent<BulkAnnotationImportConfigRequest>(\n BULK_ANNOTATION_IMPORT_CONFIG_EVENT,\n {\n detail: { ...request, resolve: settle },\n },\n ),\n );\n });\n}\n\nexport function renderBulkAnnotationImportConfigModal(actionId: string) {\n return <BulkAnnotationImportConfigModal actionId={actionId} />;\n}\n\nexport function getDefaultRunOptions(): BulkAnnotationImportRunOptions {\n return {\n scope: \"all\",\n motivationMode: \"all\",\n motivations: [],\n };\n}\n\nfunction BulkAnnotationImportConfigModal({ actionId }: { actionId: string }) {\n const [request, setRequest] =\n useState<BulkAnnotationImportConfigRequest | null>(null);\n const [options, setOptions] = useState<BulkAnnotationImportRunOptions>(\n getDefaultRunOptions(),\n );\n const [customMotivations, setCustomMotivations] = useState(\"\");\n\n useEffect(() => {\n const listener = (event: Event) => {\n const detail = (event as CustomEvent<BulkAnnotationImportConfigRequest>)\n .detail;\n if (detail?.actionId === actionId) {\n setRequest(detail);\n setOptions(normaliseDefaults(detail.defaults, detail.tags));\n setCustomMotivations(\"\");\n }\n };\n\n window.addEventListener(BULK_ANNOTATION_IMPORT_CONFIG_EVENT, listener);\n return () =>\n window.removeEventListener(BULK_ANNOTATION_IMPORT_CONFIG_EVENT, listener);\n }, [actionId]);\n\n useEffect(() => {\n if (!request?.signal) {\n return;\n }\n\n if (request.signal.aborted) {\n setRequest(null);\n return;\n }\n\n const handleAbort = () => setRequest(null);\n request.signal.addEventListener(\"abort\", handleAbort, { once: true });\n return () => request.signal?.removeEventListener(\"abort\", handleAbort);\n }, [request]);\n\n const selectedTag = useMemo(\n () => request?.tags.find((tag) => tag.key === options.tagKey),\n [request?.tags, options.tagKey],\n );\n const selectedExternalPages =\n options.scope === \"tag\"\n ? selectedTag?.externalPageCount || 0\n : request?.totalExternalPages || 0;\n const selectedMotivations = useMemo(\n () => getSelectedMotivations(options, customMotivations),\n [customMotivations, options],\n );\n const motivationSelectionInvalid =\n options.motivationMode === \"selected\" && selectedMotivations.length === 0;\n\n if (!request) {\n return null;\n }\n\n const close = (value: BulkAnnotationImportRunOptions | false) => {\n request.resolve(value);\n setRequest(null);\n };\n\n const tagSelectionDisabled = !request.tags.length;\n\n return (\n <Modal\n title=\"Import External Annotation Pages\"\n onClose={() => close(false)}\n className=\"max-w-2xl\"\n actions={\n <div className=\"flex gap-2\">\n <button\n type=\"button\"\n className=\"rounded border border-zinc-300 bg-white px-3 py-2 text-sm text-zinc-700\"\n onClick={() => close(false)}\n >\n Cancel\n </button>\n <button\n type=\"button\"\n className=\"rounded border border-me-primary-500 bg-me-primary-500 px-3 py-2 text-sm text-white disabled:cursor-not-allowed disabled:opacity-50\"\n disabled={selectedExternalPages === 0 || motivationSelectionInvalid}\n onClick={() =>\n close({\n ...options,\n motivations:\n options.motivationMode === \"selected\"\n ? selectedMotivations\n : [],\n })\n }\n >\n Import pages\n </button>\n </div>\n }\n >\n <div className=\"flex min-h-0 flex-col gap-4 p-4 text-sm text-zinc-700\">\n <fieldset className=\"grid gap-2\">\n <legend className=\"font-medium text-zinc-900\">Canvases</legend>\n <label className=\"flex items-center gap-2\">\n <input\n type=\"radio\"\n checked={options.scope === \"all\"}\n onChange={() =>\n setOptions((current) => ({ ...current, scope: \"all\" }))\n }\n />\n <span>\n All canvases with external annotation pages (\n {request.totalExternalPages})\n </span>\n </label>\n <label className=\"flex items-center gap-2\">\n <input\n type=\"radio\"\n checked={options.scope === \"tag\"}\n disabled={tagSelectionDisabled}\n onChange={() =>\n setOptions((current) => ({\n ...current,\n scope: \"tag\",\n tagKey: current.tagKey || request.tags[0]?.key,\n }))\n }\n />\n <span>Only canvases with tag</span>\n </label>\n <select\n className=\"rounded border border-zinc-300 bg-white p-2 disabled:bg-zinc-100\"\n disabled={options.scope !== \"tag\" || tagSelectionDisabled}\n value={options.tagKey || \"\"}\n onChange={(event) =>\n setOptions((current) => ({\n ...current,\n tagKey: event.target.value,\n }))\n }\n >\n {request.tags.map((tag) => (\n <option key={tag.key} value={tag.key}>\n {tag.label} ({tag.externalPageCount})\n </option>\n ))}\n </select>\n </fieldset>\n\n <fieldset className=\"grid gap-2\">\n <legend className=\"font-medium text-zinc-900\">Motivations</legend>\n <label className=\"flex items-center gap-2\">\n <input\n type=\"radio\"\n checked={options.motivationMode === \"all\"}\n onChange={() =>\n setOptions((current) => ({ ...current, motivationMode: \"all\" }))\n }\n />\n <span>All motivations</span>\n </label>\n <label className=\"flex items-center gap-2\">\n <input\n type=\"radio\"\n checked={options.motivationMode === \"selected\"}\n onChange={() =>\n setOptions((current) => ({\n ...current,\n motivationMode: \"selected\",\n motivations: current.motivations.length\n ? current.motivations\n : [\"commenting\"],\n }))\n }\n />\n <span>Only selected motivations</span>\n </label>\n <div className=\"grid grid-cols-2 gap-2 rounded border border-zinc-200 p-3\">\n {BULK_ANNOTATION_IMPORT_MOTIVATIONS.map((motivation) => (\n <label key={motivation} className=\"flex items-center gap-2\">\n <input\n type=\"checkbox\"\n disabled={options.motivationMode !== \"selected\"}\n checked={options.motivations.includes(motivation)}\n onChange={(event) =>\n setOptions((current) => ({\n ...current,\n motivationMode: \"selected\",\n motivations: event.target.checked\n ? uniqueStrings([...current.motivations, motivation])\n : current.motivations.filter(\n (item) => item !== motivation,\n ),\n }))\n }\n />\n <span>{motivation}</span>\n </label>\n ))}\n </div>\n <label className=\"grid gap-1\">\n <span className=\"font-medium text-zinc-900\">\n Additional motivations\n </span>\n <input\n type=\"text\"\n className=\"rounded border border-zinc-300 p-2\"\n disabled={options.motivationMode !== \"selected\"}\n value={customMotivations}\n placeholder=\"transcribing, reviewing\"\n onChange={(event) => setCustomMotivations(event.target.value)}\n />\n </label>\n </fieldset>\n\n <div className=\"rounded border border-zinc-200 bg-white p-3 text-zinc-600\">\n {selectedExternalPages} external annotation page\n {selectedExternalPages === 1 ? \"\" : \"s\"} selected.\n {options.motivationMode === \"selected\" ? (\n <>\n {\" \"}\n {selectedMotivations.length} motivation\n {selectedMotivations.length === 1 ? \"\" : \"s\"} selected.\n </>\n ) : null}\n </div>\n </div>\n </Modal>\n );\n}\n\nfunction normaliseDefaults(\n defaults: BulkAnnotationImportRunOptions,\n tags: BulkAnnotationImportTagOption[],\n): BulkAnnotationImportRunOptions {\n const hasSelectedTag = defaults.tagKey\n ? tags.some((tag) => tag.key === defaults.tagKey)\n : false;\n\n return {\n scope: defaults.scope === \"tag\" && tags.length ? \"tag\" : \"all\",\n tagKey: hasSelectedTag ? defaults.tagKey : tags[0]?.key,\n motivationMode: defaults.motivationMode === \"selected\" ? \"selected\" : \"all\",\n motivations: uniqueStrings(defaults.motivations || []),\n };\n}\n\nfunction getSelectedMotivations(\n options: BulkAnnotationImportRunOptions,\n customMotivations: string,\n) {\n if (options.motivationMode !== \"selected\") {\n return [];\n }\n\n return uniqueStrings([\n ...options.motivations,\n ...parseMotivationText(customMotivations),\n ]);\n}\n\nfunction parseMotivationText(value: string) {\n return value\n .split(/[,\\n]/)\n .map((item) => item.trim())\n .filter(Boolean);\n}\n\nfunction uniqueStrings(values: string[]) {\n return Array.from(new Set(values.map((item) => item.trim()).filter(Boolean)));\n}\n","import {\n addReference,\n batchActions,\n importEntities,\n modifyEntityField,\n} from \"@iiif/helpers/vault/actions\";\nimport { convertPresentation2 } from \"@iiif/parser/presentation-2\";\n\nconst IS_EXTERNAL = \"iiif-parser:isExternal\";\nconst HAS_PART = \"iiif-parser:hasPart\";\nconst RESOURCE_TYPES = [\n \"Annotation\",\n \"AnnotationPage\",\n \"ContentResource\",\n \"Canvas\",\n \"Manifest\",\n \"Range\",\n];\n\nexport type ExternalAnnotationPageReference = {\n key: string;\n canvasId: string;\n canvasLabel: string;\n pageId: string;\n annotationPageIndex: number;\n existingPage?: any;\n};\n\nexport type LoadedExternalAnnotationPage = {\n reference: ExternalAnnotationPageReference;\n json?: unknown;\n error?: string;\n};\n\nexport type SkippedExternalAnnotationPage = {\n key: string;\n canvasId: string;\n canvasLabel: string;\n pageId: string;\n reason: string;\n};\n\nexport type InlineAnnotationPageImport = {\n reference: ExternalAnnotationPageReference;\n page: any;\n annotations: any[];\n skippedAnnotations: number;\n skippedByMotivation: number;\n};\n\nexport type ExternalAnnotationPageInlinePlan = {\n totalExternalPages: number;\n totalAnnotations: number;\n pages: InlineAnnotationPageImport[];\n skippedPages: SkippedExternalAnnotationPage[];\n warnings: string[];\n errors: string[];\n};\n\nexport type ExternalAnnotationPageInlineResult = {\n totalExternalPages: number;\n pagesInlined: number;\n canvasesUpdated: number;\n annotationsWritten: number;\n skippedPages: SkippedExternalAnnotationPage[];\n warnings: string[];\n};\n\ntype EntityBuckets = {\n AnnotationPage: Record<string, any>;\n Annotation: Record<string, any>;\n ContentResource: Record<string, any>;\n};\n\nexport function findExternalAnnotationPageReferences(\n vault: any,\n canvases: any[],\n): ExternalAnnotationPageReference[] {\n const references: ExternalAnnotationPageReference[] = [];\n\n for (const canvas of canvases) {\n if (!canvas?.id || !Array.isArray(canvas.annotations)) {\n continue;\n }\n\n canvas.annotations.forEach((annotationPageRef: any, index: number) => {\n const pageId = getResourceId(annotationPageRef);\n if (!pageId) {\n return;\n }\n\n const existingPage =\n vault.get({ id: pageId, type: \"AnnotationPage\" }) ||\n vault.get(annotationPageRef) ||\n annotationPageRef;\n\n if (!isExternalAnnotationPage(existingPage)) {\n return;\n }\n\n references.push({\n key: `${canvas.id}:annotations:${index}:${pageId}`,\n canvasId: canvas.id,\n canvasLabel: getLabelText(canvas.label) || canvas.id,\n pageId,\n annotationPageIndex: index,\n existingPage,\n });\n });\n }\n\n return references;\n}\n\nexport function createExternalAnnotationPageInlinePlan(options: {\n loadedPages: LoadedExternalAnnotationPage[];\n motivationFilter?: string[];\n}): ExternalAnnotationPageInlinePlan {\n const pages: InlineAnnotationPageImport[] = [];\n const skippedPages: SkippedExternalAnnotationPage[] = [];\n const warnings: string[] = [];\n const seenPageIds = new Set<string>();\n const motivationFilter = createMotivationFilter(options.motivationFilter);\n let totalAnnotations = 0;\n\n for (const loaded of options.loadedPages) {\n const { reference } = loaded;\n\n if (seenPageIds.has(reference.pageId)) {\n skippedPages.push(\n toSkippedPage(\n reference,\n \"External annotation page is referenced more than once.\",\n ),\n );\n continue;\n }\n seenPageIds.add(reference.pageId);\n\n if (loaded.error) {\n skippedPages.push(toSkippedPage(reference, loaded.error));\n continue;\n }\n\n const pageResult = normaliseFetchedAnnotationPage(loaded.json, reference);\n if (pageResult.warning) {\n warnings.push(pageResult.warning);\n }\n if (!pageResult.page) {\n skippedPages.push(toSkippedPage(reference, pageResult.error));\n continue;\n }\n\n const page = pageResult.page;\n if (!Array.isArray(page.items)) {\n skippedPages.push(\n toSkippedPage(\n reference,\n \"Fetched annotation page does not contain an items array.\",\n ),\n );\n continue;\n }\n\n const annotationItems = page.items.filter(\n (item: any) => item?.type === \"Annotation\",\n );\n const annotations = annotationItems.filter((annotation: any) =>\n annotationMatchesMotivationFilter(annotation, motivationFilter),\n );\n const skippedAnnotations = page.items.length - annotationItems.length;\n const skippedByMotivation = annotationItems.length - annotations.length;\n\n if (skippedAnnotations) {\n warnings.push(\n `${reference.pageId}: skipped ${skippedAnnotations} non-Annotation item${skippedAnnotations === 1 ? \"\" : \"s\"}.`,\n );\n }\n if (skippedByMotivation) {\n warnings.push(\n `${reference.pageId}: skipped ${skippedByMotivation} annotation${skippedByMotivation === 1 ? \"\" : \"s\"} outside the selected motivation filter.`,\n );\n }\n\n if (!annotations.length) {\n skippedPages.push(\n toSkippedPage(\n reference,\n getEmptyPageReason(\n page.items.length,\n annotationItems.length,\n motivationFilter,\n ),\n ),\n );\n continue;\n }\n\n totalAnnotations += annotations.length;\n pages.push({\n reference,\n page,\n annotations,\n skippedAnnotations,\n skippedByMotivation,\n });\n }\n\n return {\n totalExternalPages: options.loadedPages.length,\n totalAnnotations,\n pages,\n skippedPages,\n warnings,\n errors: [],\n };\n}\n\nexport function writeExternalAnnotationPageInlinePlan(\n vault: any,\n plan: ExternalAnnotationPageInlinePlan,\n) {\n const entities: EntityBuckets = {\n AnnotationPage: {},\n Annotation: {},\n ContentResource: {},\n };\n const relationshipActions: any[] = [];\n const idFactory = createIdFactory(vault);\n const updatedCanvasIds = new Set<string>();\n let annotationsWritten = 0;\n\n for (const pageImport of plan.pages) {\n const { reference } = pageImport;\n const pageId = reference.pageId;\n const inlinePage = cloneJson(pageImport.page);\n\n inlinePage.id = pageId;\n inlinePage.type = \"AnnotationPage\";\n inlinePage.items = [];\n inlinePage[IS_EXTERNAL] = false;\n\n if (reference.existingPage?.[HAS_PART]) {\n inlinePage[HAS_PART] = cloneJson(reference.existingPage[HAS_PART]);\n }\n\n entities.AnnotationPage[pageId] = inlinePage;\n updatedCanvasIds.add(reference.canvasId);\n relationshipActions.push(\n modifyEntityField({\n id: pageId,\n type: \"AnnotationPage\",\n key: IS_EXTERNAL,\n value: false,\n }),\n );\n\n for (const sourceAnnotation of pageImport.annotations) {\n const annotation = cloneJson(sourceAnnotation);\n const annotationId = idFactory.preserveOrCreate(\n getResourceId(annotation),\n \"Annotation\",\n reference.canvasId,\n \"external-annotation\",\n );\n const bodyResult = normaliseAnnotationBodies(\n annotation.body,\n idFactory,\n reference.canvasId,\n annotationId,\n );\n\n annotation.id = annotationId;\n annotation.type = \"Annotation\";\n annotation.body = bodyResult.body;\n annotation.target = rewriteAnnotationTarget(\n annotation.target,\n reference.canvasId,\n );\n\n Object.assign(entities.ContentResource, bodyResult.entities);\n entities.Annotation[annotationId] = annotation;\n relationshipActions.push(\n addReference({\n id: pageId,\n type: \"AnnotationPage\",\n key: \"items\",\n reference: {\n id: annotationId,\n type: \"Annotation\",\n },\n }),\n );\n annotationsWritten += 1;\n }\n }\n\n const actions = [\n importEntities({\n entities: removeEmptyEntityBuckets(entities),\n }),\n ...relationshipActions,\n ];\n\n if (\n relationshipActions.length ||\n Object.values(entities).some((bucket) => Object.keys(bucket).length)\n ) {\n vault.dispatch(batchActions({ actions }));\n }\n\n return {\n totalExternalPages: plan.totalExternalPages,\n pagesInlined: plan.pages.length,\n canvasesUpdated: updatedCanvasIds.size,\n annotationsWritten,\n skippedPages: plan.skippedPages,\n warnings: plan.warnings,\n } satisfies ExternalAnnotationPageInlineResult;\n}\n\nexport function rewriteAnnotationTarget(\n target: unknown,\n canvasId: string,\n): unknown {\n if (Array.isArray(target)) {\n return target.map((item) => rewriteAnnotationTarget(item, canvasId));\n }\n\n if (typeof target === \"string\") {\n return withCanvasId(target, canvasId);\n }\n\n if (!target || typeof target !== \"object\") {\n return target;\n }\n\n const clone = cloneJson(target as any);\n\n if (typeof clone.source === \"string\") {\n clone.source = withCanvasId(clone.source, canvasId);\n return clone;\n }\n\n if (clone.source && typeof clone.source === \"object\") {\n clone.source = {\n ...clone.source,\n id: canvasId,\n type: clone.source.type || \"Canvas\",\n };\n return clone;\n }\n\n if (typeof clone.id === \"string\") {\n clone.id = withCanvasId(clone.id, canvasId);\n }\n\n return clone;\n}\n\nfunction isExternalAnnotationPage(page: any) {\n return !!page?.[IS_EXTERNAL];\n}\n\nfunction toSkippedPage(\n reference: ExternalAnnotationPageReference,\n reason: string,\n): SkippedExternalAnnotationPage {\n return {\n key: reference.key,\n canvasId: reference.canvasId,\n canvasLabel: reference.canvasLabel,\n pageId: reference.pageId,\n reason,\n };\n}\n\nfunction normaliseFetchedAnnotationPage(\n json: unknown,\n reference: ExternalAnnotationPageReference,\n): { page?: any; error: string; warning?: string } {\n if (!json || typeof json !== \"object\") {\n return { error: \"Fetched resource is not a JSON object.\" };\n }\n\n const resource = json as any;\n if (resource.type === \"AnnotationPage\") {\n return { page: resource, error: \"\" };\n }\n\n if (isPresentation2AnnotationList(resource)) {\n try {\n const upgraded = convertPresentation2(resource) as any;\n if (upgraded?.type === \"AnnotationPage\") {\n return {\n page: upgraded,\n error: \"\",\n warning: `${reference.pageId}: upgraded Presentation 2 sc:AnnotationList to AnnotationPage.`,\n };\n }\n\n return {\n error: `IIIF upgrade produced ${upgraded?.type || \"missing a type\"}, not AnnotationPage.`,\n };\n } catch (error) {\n return {\n error: `Unable to upgrade Presentation 2 sc:AnnotationList: ${error instanceof Error ? error.message : String(error)}`,\n };\n }\n }\n\n return {\n error: `Fetched resource is ${resource.type || resource[\"@type\"] || \"missing a type\"}, not AnnotationPage.`,\n };\n}\n\nfunction getEmptyPageReason(\n itemCount: number,\n annotationCount: number,\n motivationFilter: Set<string> | null,\n) {\n if (!itemCount) {\n return \"Fetched annotation page is empty.\";\n }\n\n if (!annotationCount) {\n return \"Fetched annotation page does not contain Annotation items.\";\n }\n\n if (motivationFilter?.size) {\n return `No annotations matched the selected motivation filter (${Array.from(motivationFilter).join(\", \")}).`;\n }\n\n return \"Fetched annotation page does not contain importable annotations.\";\n}\n\nfunction createMotivationFilter(values: string[] | undefined) {\n const normalised = dedupeStrings(\n (values || []).map(normaliseMotivation).filter(Boolean),\n );\n return normalised.length ? new Set(normalised) : null;\n}\n\nfunction annotationMatchesMotivationFilter(\n annotation: any,\n motivationFilter: Set<string> | null,\n) {\n if (!motivationFilter?.size) {\n return true;\n }\n\n return getAnnotationMotivations(annotation).some((motivation) =>\n motivationFilter.has(motivation),\n );\n}\n\nfunction getAnnotationMotivations(annotation: any) {\n return dedupeStrings(\n toArray(annotation?.motivation).map(normaliseMotivation).filter(Boolean),\n );\n}\n\nfunction normaliseMotivation(value: unknown) {\n if (typeof value !== \"string\") {\n return \"\";\n }\n\n const trimmed = value.trim().toLowerCase();\n const compact = trimmed.includes(\":\")\n ? trimmed.slice(trimmed.lastIndexOf(\":\") + 1)\n : trimmed;\n const slashIndex = compact.lastIndexOf(\"/\");\n const hashIndex = compact.lastIndexOf(\"#\");\n const separator = Math.max(slashIndex, hashIndex);\n return separator >= 0 ? compact.slice(separator + 1) : compact;\n}\n\nfunction isPresentation2AnnotationList(resource: any) {\n const type = resource?.[\"@type\"] || resource?.type;\n return type === \"sc:AnnotationList\" || type === \"AnnotationList\";\n}\n\nfunction normaliseAnnotationBodies(\n body: unknown,\n idFactory: ReturnType<typeof createIdFactory>,\n canvasId: string,\n annotationId: string,\n) {\n const bodyItems =\n typeof body === \"undefined\" || body === null ? [] : toArray(body);\n const entities: Record<string, any> = {};\n const normalised =\n bodyItems.length > 1 && bodyItems.every(isTextualBodyLike)\n ? [\n normaliseChoiceBody(\n {\n type: \"Choice\",\n items: bodyItems,\n },\n idFactory,\n canvasId,\n annotationId,\n \"body-choice\",\n entities,\n ),\n ]\n : bodyItems.map((item, index) =>\n normaliseBodyItem(\n item,\n idFactory,\n canvasId,\n annotationId,\n `body-${index + 1}`,\n entities,\n ),\n );\n\n return {\n body: normalised,\n entities,\n };\n}\n\nfunction normaliseBodyItem(\n item: unknown,\n idFactory: ReturnType<typeof createIdFactory>,\n canvasId: string,\n annotationId: string,\n seed: string,\n entities: Record<string, any>,\n) {\n if (isChoiceBody(item)) {\n return normaliseChoiceBody(\n item,\n idFactory,\n canvasId,\n annotationId,\n seed,\n entities,\n );\n }\n\n const bodyId = idFactory.preserveOrCreate(\n item && typeof item === \"object\" ? getResourceId(item) : undefined,\n \"ContentResource\",\n canvasId,\n `${annotationId}-${seed}`,\n );\n\n if (typeof item === \"string\") {\n entities[bodyId] = {\n id: bodyId,\n type: \"TextualBody\",\n format: \"text/plain\",\n value: item,\n };\n return { id: bodyId, type: \"ContentResource\" };\n }\n\n if (item && typeof item === \"object\") {\n const resource = normaliseImportedBodyResource(item);\n entities[bodyId] = {\n ...resource,\n id: bodyId,\n type: resource.type || \"ContentResource\",\n };\n return { id: bodyId, type: \"ContentResource\" };\n }\n\n entities[bodyId] = {\n id: bodyId,\n type: \"TextualBody\",\n format: \"text/plain\",\n value: String(item),\n };\n return { id: bodyId, type: \"ContentResource\" };\n}\n\nfunction normaliseChoiceBody(\n choice: any,\n idFactory: ReturnType<typeof createIdFactory>,\n canvasId: string,\n annotationId: string,\n seed: string,\n entities: Record<string, any>,\n) {\n const choiceId = idFactory.preserveOrCreate(\n getResourceId(choice),\n \"ContentResource\",\n canvasId,\n `${annotationId}-${seed}`,\n );\n const items = toArray(choice.items).map((item, index) =>\n normaliseBodyItem(\n item,\n idFactory,\n canvasId,\n annotationId,\n `${seed}-item-${index + 1}`,\n entities,\n ),\n );\n\n entities[choiceId] = {\n ...cloneJson(choice),\n id: choiceId,\n type: \"Choice\",\n items,\n };\n\n return { id: choiceId, type: \"ContentResource\" };\n}\n\nfunction normaliseImportedBodyResource(item: unknown) {\n const resource = cloneJson(item as any);\n\n if (\n typeof resource.chars === \"string\" &&\n typeof resource.value === \"undefined\"\n ) {\n resource.value = resource.chars;\n delete resource.chars;\n\n if (resource.type === \"Text\") {\n resource.type = \"TextualBody\";\n }\n }\n\n return resource;\n}\n\nfunction isChoiceBody(item: unknown) {\n return !!item && typeof item === \"object\" && (item as any).type === \"Choice\";\n}\n\nfunction isTextualBodyLike(item: unknown) {\n if (typeof item === \"string\") {\n return true;\n }\n\n if (!item || typeof item !== \"object\") {\n return false;\n }\n\n const type = (item as any).type;\n return type === \"TextualBody\" || type === \"Text\";\n}\n\nfunction createIdFactory(vault: any) {\n const used = new Set<string>();\n let counter = 0;\n\n function isInUse(id: string) {\n if (used.has(id)) {\n return true;\n }\n\n return RESOURCE_TYPES.some((type) => !!vault.get({ id, type }));\n }\n\n function create(canvasId: string, type: string, seed: string) {\n let id: string;\n do {\n counter += 1;\n id = `${trimTrailingSlash(canvasId)}/external-annotation-pages/${slugify(type)}/${slugify(seed)}-${counter}`;\n } while (isInUse(id));\n\n used.add(id);\n return id;\n }\n\n function preserveOrCreate(\n id: string | undefined,\n type: string,\n canvasId: string,\n seed: string,\n ) {\n if (id && !isInUse(id)) {\n used.add(id);\n return id;\n }\n\n return create(canvasId, type, seed);\n }\n\n return { create, preserveOrCreate };\n}\n\nfunction splitTargetId(value: string) {\n const hashIndex = value.indexOf(\"#\");\n return {\n sourceId: hashIndex >= 0 ? value.slice(0, hashIndex) : value,\n fragment: hashIndex >= 0 ? value.slice(hashIndex) : \"\",\n };\n}\n\nfunction withCanvasId(value: string, canvasId: string) {\n return `${canvasId}${splitTargetId(value).fragment}`;\n}\n\nfunction getResourceId(resource: unknown) {\n if (typeof resource === \"string\") return resource;\n if (!resource || typeof resource !== \"object\") return undefined;\n return typeof (resource as any).id === \"string\"\n ? (resource as any).id\n : typeof (resource as any)[\"@id\"] === \"string\"\n ? (resource as any)[\"@id\"]\n : undefined;\n}\n\nfunction getLabelTexts(label: unknown): string[] {\n if (!label) return [];\n if (typeof label === \"string\") return [label];\n if (Array.isArray(label))\n return label.filter((item): item is string => typeof item === \"string\");\n if (typeof label === \"object\") {\n return Object.values(label as Record<string, unknown>).flatMap(\n getLabelTexts,\n );\n }\n return [];\n}\n\nfunction getLabelText(label: unknown) {\n return getLabelTexts(label)[0] || \"\";\n}\n\nfunction dedupeStrings(values: string[]) {\n return Array.from(new Set(values.filter(Boolean)));\n}\n\nfunction toArray<T>(value: T | T[] | null | undefined): T[] {\n if (Array.isArray(value)) return value;\n if (typeof value === \"undefined\" || value === null) return [];\n return [value];\n}\n\nfunction cloneJson<T>(value: T): T {\n return JSON.parse(JSON.stringify(value));\n}\n\nfunction slugify(value: string) {\n return (\n value\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\")\n .slice(0, 80) || \"item\"\n );\n}\n\nfunction trimTrailingSlash(value: string) {\n return value.endsWith(\"/\") ? value.slice(0, -1) : value;\n}\n\nfunction removeEmptyEntityBuckets(entities: EntityBuckets) {\n return Object.fromEntries(\n Object.entries(entities).filter(([, value]) => Object.keys(value).length),\n );\n}\n","import { Modal } from \"@manifest-editor/components\";\nimport { useEffect, useState } from \"react\";\nimport type { ExternalAnnotationPageInlineResult } from \"./importer\";\n\nconst resultsEventName = \"@manifest-editor/annotations:bulk-import-results\";\n\ntype BulkAnnotationImportResultsEvent = {\n actionId: string;\n result?: ExternalAnnotationPageInlineResult;\n};\n\nexport function openBulkAnnotationImportResults(actionId: string, result: unknown) {\n window.dispatchEvent(\n new CustomEvent<BulkAnnotationImportResultsEvent>(resultsEventName, {\n detail: {\n actionId,\n result: result as ExternalAnnotationPageInlineResult | undefined,\n },\n }),\n );\n}\n\nexport function renderBulkAnnotationImportResults(actionId: string) {\n return <BulkAnnotationImportResultsModal actionId={actionId} />;\n}\n\nfunction BulkAnnotationImportResultsModal({ actionId }: { actionId: string }) {\n const [activeResult, setActiveResult] = useState<ExternalAnnotationPageInlineResult | null>(null);\n\n useEffect(() => {\n const listener = (event: Event) => {\n const detail = (event as CustomEvent<BulkAnnotationImportResultsEvent>).detail;\n if (detail?.actionId === actionId && detail.result) {\n setActiveResult(detail.result);\n }\n };\n\n window.addEventListener(resultsEventName, listener);\n return () => window.removeEventListener(resultsEventName, listener);\n }, [actionId]);\n\n if (!activeResult) {\n return null;\n }\n\n return (\n <Modal title=\"External annotation page import results\" onClose={() => setActiveResult(null)} className=\"max-w-3xl\">\n <div className=\"flex min-h-0 flex-col gap-4 p-4 text-sm text-zinc-700\">\n <div className=\"grid grid-cols-4 gap-2\">\n <ResultStat label=\"External pages\" value={activeResult.totalExternalPages} />\n <ResultStat label=\"Inlined pages\" value={activeResult.pagesInlined} />\n <ResultStat label=\"Canvases\" value={activeResult.canvasesUpdated} />\n <ResultStat label=\"Annotations\" value={activeResult.annotationsWritten} />\n </div>\n\n {activeResult.warnings.length ? (\n <div className=\"rounded border border-amber-200 bg-amber-50 p-3 text-amber-900\">\n {activeResult.warnings.map((warning) => (\n <div key={warning}>{warning}</div>\n ))}\n </div>\n ) : null}\n\n {activeResult.skippedPages.length ? (\n <div className=\"rounded border border-zinc-200\">\n <div className=\"border-b border-zinc-200 bg-zinc-50 px-3 py-2 font-medium\">Skipped external pages</div>\n <div className=\"max-h-64 overflow-auto\">\n {activeResult.skippedPages.map((item) => (\n <div key={item.key} className=\"grid gap-1 border-b border-zinc-100 px-3 py-2 last:border-0\">\n <div className=\"truncate font-medium text-zinc-900\">{item.pageId}</div>\n <div className=\"truncate text-zinc-500\">{item.canvasLabel}</div>\n <div className=\"text-zinc-500\">{item.reason}</div>\n </div>\n ))}\n </div>\n </div>\n ) : null}\n </div>\n </Modal>\n );\n}\n\nfunction ResultStat({ label, value }: { label: string; value: number }) {\n return (\n <div className=\"rounded border border-zinc-200 bg-zinc-50 p-3\">\n <div className=\"text-xl font-semibold text-zinc-900\">{value}</div>\n <div className=\"text-xs uppercase tracking-wide text-zinc-500\">{label}</div>\n </div>\n );\n}\n","import {\n FLAG_TAG,\n type BackgroundActionDefinition,\n type BackgroundActionRunContext,\n type ManifestEditorTag,\n} from \"@manifest-editor/shell\";\nimport { BULK_ANNOTATION_IMPORT_ACTION_ID } from \"../constants\";\nimport {\n getDefaultRunOptions,\n renderBulkAnnotationImportConfigModal,\n requestBulkAnnotationImportConfig,\n type BulkAnnotationImportRunOptions,\n type BulkAnnotationImportTagOption,\n} from \"./config-modal\";\nimport {\n createExternalAnnotationPageInlinePlan,\n findExternalAnnotationPageReferences,\n writeExternalAnnotationPageInlinePlan,\n type ExternalAnnotationPageInlineResult,\n type ExternalAnnotationPageReference,\n type LoadedExternalAnnotationPage,\n} from \"./importer\";\nimport {\n openBulkAnnotationImportResults,\n renderBulkAnnotationImportResults,\n} from \"./results\";\n\nconst runOptions = new Map<\n string,\n {\n references: ExternalAnnotationPageReference[];\n options: BulkAnnotationImportRunOptions;\n }\n>();\n\nexport type BulkAnnotationImportActionDependencies = {\n fetchPage?: (\n pageId: string,\n reference: ExternalAnnotationPageReference,\n ctx: BackgroundActionRunContext,\n ) => Promise<unknown>;\n requestConfig?: (\n ctx: BackgroundActionRunContext,\n references: ExternalAnnotationPageReference[],\n defaults: BulkAnnotationImportRunOptions,\n ) => Promise<BulkAnnotationImportRunOptions | false>;\n};\n\nexport function createBulkAnnotationImportBackgroundAction(\n dependencies: BulkAnnotationImportActionDependencies = {},\n): BackgroundActionDefinition {\n const fetchPage = dependencies.fetchPage || defaultFetchPage;\n const requestConfig = dependencies.requestConfig || defaultRequestConfig;\n\n return {\n id: BULK_ANNOTATION_IMPORT_ACTION_ID,\n label: \"Bulk Annotation Page Importer\",\n summary:\n \"Load external Canvas annotation pages and make them editable inline\",\n section: \"Annotations\",\n order: 10,\n resourceTypes: [\"Manifest\"],\n resumable: false,\n render: (ctx) => (\n <>\n {renderBulkAnnotationImportConfigModal(ctx.definition.id)}\n {renderBulkAnnotationImportResults(ctx.definition.id)}\n </>\n ),\n onResults: (ctx) =>\n openBulkAnnotationImportResults(ctx.definition.id, ctx.instance?.result),\n supports: (ctx) =>\n findExternalAnnotationPageReferences(ctx.vault, getManifestCanvases(ctx))\n .length > 0,\n prepare: async (ctx) => {\n const references = findExternalAnnotationPageReferences(\n ctx.vault,\n getManifestCanvases(ctx),\n );\n if (!references.length) {\n return false;\n }\n\n const options = await requestConfig(\n ctx,\n references,\n getDefaultRunOptions(),\n );\n if (options === false) {\n return false;\n }\n\n const selectedReferences = selectReferences(ctx, references, options);\n if (!selectedReferences.length) {\n return false;\n }\n\n runOptions.set(ctx.instanceKey, {\n references: selectedReferences,\n options,\n });\n return true;\n },\n run: async (ctx) => {\n const prepared = runOptions.get(ctx.instanceKey);\n const options = prepared?.options || getDefaultRunOptions();\n const references =\n prepared?.references ||\n selectReferences(\n ctx,\n findExternalAnnotationPageReferences(\n ctx.vault,\n getManifestCanvases(ctx),\n ),\n options,\n );\n\n try {\n ctx.setActionLabel(\"Importing external annotation pages\");\n ctx.setActionProgress({\n current: 0,\n total: Math.max(references.length, 1),\n label: \"Loading external annotation pages\",\n });\n\n if (!references.length) {\n ctx.setActionStatus(\"running\", \"No external annotation pages found\");\n return createEmptyResult();\n }\n\n const loadedPages: LoadedExternalAnnotationPage[] = [];\n for (const [index, reference] of references.entries()) {\n throwIfAborted(ctx.signal);\n ctx.setActionStatus(\n \"running\",\n `Loading ${index + 1}/${references.length}`,\n );\n ctx.appendActionLog(\"Loading external annotation page\", \"info\", {\n canvasId: reference.canvasId,\n pageId: reference.pageId,\n });\n\n try {\n const json = await fetchPage(reference.pageId, reference, ctx);\n loadedPages.push({ reference, json });\n } catch (error) {\n const message = getErrorMessage(error);\n loadedPages.push({ reference, error: message });\n ctx.appendActionLog(\n \"Failed to load external annotation page\",\n \"warn\",\n {\n canvasId: reference.canvasId,\n pageId: reference.pageId,\n reason: message,\n },\n );\n }\n\n ctx.setActionProgress({\n current: index + 1,\n total: references.length,\n label: \"Loading external annotation pages\",\n });\n }\n\n const plan = createExternalAnnotationPageInlinePlan({\n loadedPages,\n motivationFilter:\n options.motivationMode === \"selected\"\n ? options.motivations\n : undefined,\n });\n if (plan.errors.length) {\n throw new Error(\n plan.errors[0] || \"External annotation page import failed.\",\n );\n }\n\n ctx.setActionStatus(\"running\", \"Writing inline annotation pages\");\n ctx.setActionProgress({\n current: 0,\n total: Math.max(plan.totalAnnotations, plan.pages.length, 1),\n label: \"Writing inline annotations\",\n });\n\n const result = writeExternalAnnotationPageInlinePlan(ctx.vault, plan);\n ctx.appendActionLog(\n \"External annotation page import complete\",\n \"info\",\n {\n pages: result.pagesInlined,\n annotations: result.annotationsWritten,\n skipped: result.skippedPages.length,\n },\n );\n ctx.setActionStatus(\n \"running\",\n `Imported ${result.pagesInlined}/${result.totalExternalPages} external pages`,\n );\n ctx.setActionProgress({\n current: Math.max(result.annotationsWritten, result.pagesInlined),\n total: Math.max(result.annotationsWritten, result.pagesInlined, 1),\n label: \"Import complete\",\n });\n return result;\n } finally {\n runOptions.delete(ctx.instanceKey);\n }\n },\n };\n}\n\nasync function defaultFetchPage(\n pageId: string,\n _reference: ExternalAnnotationPageReference,\n ctx: BackgroundActionRunContext,\n) {\n const response = await fetch(pageId, {\n signal: ctx.signal,\n headers: {\n Accept: \"application/ld+json, application/json;q=0.9, */*;q=0.1\",\n },\n });\n\n if (!response.ok) {\n throw new Error(`Unable to fetch ${pageId} (${response.status}).`);\n }\n\n return response.json();\n}\n\nasync function defaultRequestConfig(\n ctx: BackgroundActionRunContext,\n references: ExternalAnnotationPageReference[],\n defaults: BulkAnnotationImportRunOptions,\n) {\n return requestBulkAnnotationImportConfig({\n actionId: ctx.definition.id,\n instanceKey: ctx.instanceKey,\n totalExternalPages: references.length,\n tags: getCanvasTagOptions(ctx, references),\n defaults,\n signal: ctx.signal,\n });\n}\n\nfunction getManifestCanvases(\n ctx: BackgroundActionRunContext | { vault: any; target: unknown },\n) {\n const manifest = ctx.vault.get(ctx.target as any) as any;\n return manifest?.items\n ? (ctx.vault.get(manifest.items) || []).filter(Boolean)\n : [];\n}\n\nfunction selectReferences(\n ctx: BackgroundActionRunContext,\n references: ExternalAnnotationPageReference[],\n options: BulkAnnotationImportRunOptions,\n) {\n if (options.scope !== \"tag\" || !options.tagKey) {\n return references;\n }\n\n const selectedTag = parseTagKey(options.tagKey);\n if (!selectedTag) {\n return [];\n }\n\n return references.filter((reference) =>\n ctx.tags.hasTag(\n { id: reference.canvasId, type: \"Canvas\" },\n selectedTag.type,\n selectedTag.id,\n ),\n );\n}\n\nfunction getCanvasTagOptions(\n ctx: BackgroundActionRunContext,\n references: ExternalAnnotationPageReference[],\n): BulkAnnotationImportTagOption[] {\n const tags = new Map<\n string,\n BulkAnnotationImportTagOption & ManifestEditorTag\n >();\n const pageCountByCanvas = new Map<string, number>();\n\n tags.set(getTagKey(FLAG_TAG), {\n ...FLAG_TAG,\n key: getTagKey(FLAG_TAG),\n canvasCount: 0,\n externalPageCount: 0,\n });\n\n for (const reference of references) {\n pageCountByCanvas.set(\n reference.canvasId,\n (pageCountByCanvas.get(reference.canvasId) || 0) + 1,\n );\n }\n\n for (const [canvasId, externalPageCount] of pageCountByCanvas) {\n for (const tag of ctx.tags.getTags({ id: canvasId, type: \"Canvas\" })) {\n const key = getTagKey(tag);\n const existing = tags.get(key);\n\n if (existing) {\n existing.canvasCount += 1;\n existing.externalPageCount += externalPageCount;\n } else {\n tags.set(key, {\n ...tag,\n key,\n canvasCount: 1,\n externalPageCount,\n });\n }\n }\n }\n\n return Array.from(tags.values()).sort((a, b) => {\n if (a.type === FLAG_TAG.type && a.id === FLAG_TAG.id) return -1;\n if (b.type === FLAG_TAG.type && b.id === FLAG_TAG.id) return 1;\n return (\n a.label.localeCompare(b.label) ||\n a.type.localeCompare(b.type) ||\n a.id.localeCompare(b.id)\n );\n });\n}\n\nfunction getTagKey(tag: Pick<ManifestEditorTag, \"type\" | \"id\">) {\n return `${tag.type}:${tag.id}`;\n}\n\nfunction parseTagKey(key: string): { type: string; id: string } | null {\n const separator = key.indexOf(\":\");\n if (separator === -1) {\n return null;\n }\n\n return {\n type: key.slice(0, separator),\n id: key.slice(separator + 1),\n };\n}\n\nfunction createEmptyResult(): ExternalAnnotationPageInlineResult {\n return {\n totalExternalPages: 0,\n pagesInlined: 0,\n canvasesUpdated: 0,\n annotationsWritten: 0,\n skippedPages: [],\n warnings: [],\n };\n}\n\nfunction throwIfAborted(signal: AbortSignal) {\n if (signal.aborted) {\n throw new DOMException(\"Aborted\", \"AbortError\");\n }\n}\n\nfunction getErrorMessage(error: unknown) {\n return error instanceof Error\n ? error.message\n : String(error || \"Unknown error\");\n}\n","import { useInStack } from \"@manifest-editor/editors\";\nimport {\n type BackgroundPanel,\n useLayoutActions,\n useLayoutMode,\n useLayoutState,\n} from \"@manifest-editor/shell\";\nimport { useEffect, useRef, useState } from \"react\";\nimport { useManifest } from \"react-iiif-vault\";\nimport { ANNOTATIONS_LEFT_PANEL_ID } from \"./constants\";\n\nconst RANGES_PANEL_ID = \"@manifest-editor/ranges-listing\";\n\nexport const annotationRoutingBackground: BackgroundPanel = {\n id: \"@manifest-editor/annotations-routing\",\n label: \"Annotation routing\",\n render: () => <AnnotationRoutingBackground />,\n};\n\nfunction AnnotationRoutingBackground() {\n const manifest = useManifest();\n const canvas = useInStack(\"Canvas\");\n const layoutMode = useLayoutMode();\n const { leftPanel, rightPanel } = useLayoutState();\n const { edit, open, rightPanel: rightPanelActions } = useLayoutActions();\n const lastCanvas = useRef<string | null>(null);\n const [closedRightPanel, setClosedRightPanel] = useState(false);\n\n useEffect(() => {\n const canvasId = canvas?.resource?.source?.id;\n if (canvasId) {\n lastCanvas.current = canvasId;\n }\n }, [canvas?.resource?.source?.id]);\n\n useEffect(() => {\n if (leftPanel.current === ANNOTATIONS_LEFT_PANEL_ID) {\n const firstCanvas = lastCanvas.current || manifest?.items?.[0]?.id;\n if (firstCanvas) {\n open({ id: \"current-canvas\" });\n edit({ id: firstCanvas, type: \"Canvas\" });\n }\n\n if (layoutMode === \"focused\") {\n return;\n }\n\n if (rightPanel.open) {\n rightPanelActions.close();\n setClosedRightPanel(true);\n }\n return;\n }\n\n if (\n closedRightPanel &&\n !rightPanel.open &&\n leftPanel.current !== RANGES_PANEL_ID\n ) {\n rightPanelActions.open();\n setClosedRightPanel(false);\n }\n }, [leftPanel.current, layoutMode]);\n\n return null;\n}\n","import type { AnnotationPanel, BackgroundActionDefinition, BackgroundPanel, LayoutPanel, PluginMetadata } from \"@manifest-editor/shell\";\nimport { annotationsPanel } from \"./annotation-panel\";\nimport { canvasAnnotations } from \"./canvas-annotations\";\nimport { ANNOTATIONS_PLUGIN_ID } from \"./constants\";\nimport { createBulkAnnotationImportBackgroundAction } from \"./importer/background-action\";\nimport { annotationRoutingBackground } from \"./routing-background\";\n\nexport default {\n id: ANNOTATIONS_PLUGIN_ID,\n label: \"Annotations\",\n description: \"Create, view, and inline external supplemental canvas annotation pages.\",\n author: \"Digirati\",\n official: true,\n defaultEnabled: true,\n tags: [\"annotations\", \"iiif\", \"external-pages\"],\n supports: {\n apps: [\"manifest-editor\"],\n projectTypes: [\"Manifest\"],\n },\n} satisfies PluginMetadata;\n\nexport const leftPanels: LayoutPanel[] = [annotationsPanel];\nexport const annotations: AnnotationPanel[] = [canvasAnnotations];\nexport const background: BackgroundPanel[] = [annotationRoutingBackground];\nexport const backgroundActions: BackgroundActionDefinition[] = [createBulkAnnotationImportBackgroundAction()];\n\nexport * from \"./constants\";\nexport * from \"./importer/background-action\";\nexport * from \"./importer/importer\";\n"],"mappings":"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"}
|
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { AnnotationPanel, BackgroundActionDefinition, BackgroundActionRunContext, BackgroundPanel, LayoutPanel } from "@manifest-editor/shell";
|
|
2
|
-
|
|
3
2
|
//#region src/constants.d.ts
|
|
4
3
|
declare const ANNOTATIONS_PLUGIN_ID = "@manifest-editor/annotations";
|
|
5
4
|
declare const ANNOTATIONS_LEFT_PANEL_ID = "@manifest-editor/canvas-annotation-listing";
|
package/dist/index.d.cts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.cts","names":[],"sources":["../src/constants.ts","../src/importer/config-modal.tsx","../src/importer/importer.ts","../src/importer/background-action.tsx","../src/index.ts"],"
|
|
1
|
+
{"version":3,"file":"index.d.cts","names":[],"sources":["../src/constants.ts","../src/importer/config-modal.tsx","../src/importer/importer.ts","../src/importer/background-action.tsx","../src/index.ts"],"mappings":";;cAAa;cACA;cACA;cACA;;;KCgBD;KACA;KAEA;EACV,OAAO;EACP;EACA,gBAAgB;EAChB;;;;KCPU;EACV;EACA;EACA;EACA;EACA;EACA;;KAGU;EACV,WAAW;EACX;EACA;;KAGU;EACV;EACA;EACA;EACA;EACA;;KAGU;EACV,WAAW;EACX;EACA;EACA;EACA;;KAGU;EACV;EACA;EACA,OAAO;EACP,cAAc;EACd;EACA;;KAGU;EACV;EACA;EACA;EACA;EACA,cAAc;EACd;;iBASc,qCACd,YACA,kBACC;iBAqCa,uCAAuC;EACrD,aAAa;EACb;IACE;iBAqGY,sCACd,YACA,MAAM;;;;;gBAAA;;;iBAqGQ,wBACd,iBACA;;;KChSU;EACV,aACE,gBACA,WAAW,iCACX,KAAK,+BACF;EACL,iBACE,KAAK,4BACL,YAAY,mCACZ,UAAU,mCACP,QAAQ;;iBAGC,2CACd,eAAc,yCACb;;;;;;;;;;;;IClCC;IACA;;;cAIS,YAAY;cACZ,aAAa;cACb,YAAY;cACZ,mBAAmB"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
import { AnnotationPanel, BackgroundActionDefinition, BackgroundActionRunContext, BackgroundPanel, LayoutPanel } from "@manifest-editor/shell";
|
|
2
|
-
import "react/jsx-runtime";
|
|
3
|
-
|
|
4
2
|
//#region src/constants.d.ts
|
|
5
3
|
declare const ANNOTATIONS_PLUGIN_ID = "@manifest-editor/annotations";
|
|
6
4
|
declare const ANNOTATIONS_LEFT_PANEL_ID = "@manifest-editor/canvas-annotation-listing";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/constants.ts","../src/importer/config-modal.tsx","../src/importer/importer.ts","../src/importer/background-action.tsx","../src/index.ts"],"
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/constants.ts","../src/importer/config-modal.tsx","../src/importer/importer.ts","../src/importer/background-action.tsx","../src/index.ts"],"mappings":";;cAAa;cACA;cACA;cACA;;;KCgBD;KACA;KAEA;EACV,OAAO;EACP;EACA,gBAAgB;EAChB;;;;KCPU;EACV;EACA;EACA;EACA;EACA;EACA;;KAGU;EACV,WAAW;EACX;EACA;;KAGU;EACV;EACA;EACA;EACA;EACA;;KAGU;EACV,WAAW;EACX;EACA;EACA;EACA;;KAGU;EACV;EACA;EACA,OAAO;EACP,cAAc;EACd;EACA;;KAGU;EACV;EACA;EACA;EACA;EACA,cAAc;EACd;;iBASc,qCACd,YACA,kBACC;iBAqCa,uCAAuC;EACrD,aAAa;EACb;IACE;iBAqGY,sCACd,YACA,MAAM;;;;;gBAAA;;;iBAqGQ,wBACd,iBACA;;;KChSU;EACV,aACE,gBACA,WAAW,iCACX,KAAK,+BACF;EACL,iBACE,KAAK,4BACL,YAAY,mCACZ,UAAU,mCACP,QAAQ;;iBAGC,2CACd,eAAc,yCACb;;;;;;;;;;;;IClCC;IACA;;;cAIS,YAAY;cACZ,aAAa;cACb,YAAY;cACZ,mBAAmB"}
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{AnnotationCreationPopup as e,AnnotationPreview as t,CanvasTargetContext as n,HTMLAnnotationEditor as r,ViewerAnnotationPage as i,useAnnotationEditor as a,useAnnotationInfo as o,useInStack as s}from"@manifest-editor/editors";import{AnnotationContext as c,AnnotationPageContext as l,CanvasContext as u,LocaleString as d,useAnnotation as f,useAnnotationPage as p,useAtlasStore as m,useCanvas as h,useManifest as g,useRenderingStrategy as ee,useRequestAnnotation as te}from"react-iiif-vault";import{ActionButton as _,AddIcon as ne,CheckIcon as re,DeleteIcon as ie,EditTextIcon as ae,HTMLAnnotationBodyRender as oe,Modal as se,Sidebar as ce,SidebarContent as le,SidebarHeader as ue,TargetIcon as de}from"@manifest-editor/components";import{FLAG_TAG as v,runBackgroundAction as fe,useAtlasStore as pe,useAvailableBackgroundActions as me,useBackgroundActionsStoreApi as he,useCanvasProgressStatus as ge,useInlineCreator as _e,useLayoutActions as y,useLayoutMode as ve,useLayoutState as b}from"@manifest-editor/shell";import{Fragment as x,jsx as S,jsxs as C}from"react/jsx-runtime";import{useEffect as w,useMemo as ye,useRef as be,useState as T}from"react";import{useStore as E}from"zustand";import{addReference as xe,batchActions as Se,importEntities as Ce,modifyEntityField as we}from"@iiif/helpers/vault/actions";import{convertPresentation2 as Te}from"@iiif/parser/presentation-2";const D=`@manifest-editor/annotations`,O=`@manifest-editor/canvas-annotation-listing`,Ee=`@manifest-editor/canvas-annotations`,k=`@manifest-editor/annotations/bulk-import-pages`;function A(e){return S(`svg`,{xmlns:`http://www.w3.org/2000/svg`,width:`1em`,height:`1em`,viewBox:`0 0 24 24`,...e,children:S(`path`,{fill:`currentColor`,d:`M20 2H4c-1.1 0-1.99.9-1.99 2L2 22l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2m0 14H5.17l-.59.59l-.58.58V4h16zm-9.5-2H18v-2h-5.5zm3.86-5.87c.2-.2.2-.51 0-.71l-1.77-1.77c-.2-.2-.51-.2-.71 0L6 11.53V14h2.47z`})})}function j(e){return S(`svg`,{xmlns:`http://www.w3.org/2000/svg`,width:`1em`,height:`1em`,viewBox:`0 0 24 24`,...e,children:S(`path`,{fill:`currentColor`,d:`M9 22a1 1 0 0 1-1-1v-3H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2h-6.1l-3.7 3.71c-.2.19-.45.29-.7.29zm1-6v3.08L13.08 16H20V4H4v12zm1-10h2v3h3v2h-3v3h-2v-3H8V9h3z`})})}const De=[{id:`@manifest-editor/ocr-docling/run-ocr`,label:`Run Local OCR`,preparingLabel:`Preparing OCR`,queuedLabel:`OCR queued`,pendingLabel:`OCR in progress`},{id:`@manifest-editor/remote-inference/action`,label:`Run remote OCR`,preparingLabel:`Preparing local OCR`,queuedLabel:`OCR queued`,pendingLabel:`OCR in progress`},{id:`@manifest-editor/remote-inference/structured-output`,label:`Run structured output`,preparingLabel:`Preparing structured output`,queuedLabel:`Structured output queued`,pendingLabel:`Structured output in progress`}];function Oe(){let e=he(),t=me(),n=h(),r=ge(n),i=t.flatMap(e=>e.actions),a=De.map(e=>{let t=i.find(t=>t.definition.id===e.id);return t?{...e,action:t}:null}).filter(e=>!!e);if(!a.length)return null;let o=a.find(({action:e})=>{let t=e.instance?.status;return t===`preparing`||t===`running`?r===`queued`||r===`pending`?!0:e.context.currentCanvas?.id===n?.id:!1});return C(`div`,{className:`mt-5 flex w-full flex-col items-stretch gap-2 border-t border-gray-200 pt-4`,children:[S(`div`,{className:`text-center text-xs font-semibold uppercase tracking-wide text-gray-500`,children:`OCR and structured output`}),o?C(`div`,{className:`rounded border border-amber-200 bg-amber-50 px-3 py-2 text-center text-sm text-amber-800`,children:[S(`div`,{className:`font-medium`,children:r===`queued`?o.queuedLabel:r===`pending`?o.pendingLabel:o.preparingLabel}),S(`div`,{className:`mt-1 text-xs text-amber-700`,children:o.action.instance?.statusText||o.label})]}):null,o?null:a.map(({id:t,label:n,action:r})=>{let i=r.instance?.status===`preparing`||r.instance?.status===`running`;return S(_,{large:!0,isDisabled:i,onPress:()=>{i||fe({store:e,context:r.context,prepareData:{scope:`selected`}})},children:n},t)})]})}function ke(){let e=s(`Canvas`)?.resource.source?.id,t=h({id:e}),n=_e(),r=()=>{t&&n.create(`@manifest-editor/empty-annotation-page`,{label:{en:[`Inline annotations`]}},{target:{id:t.id,type:`Canvas`},targetType:`AnnotationPage`,parent:{property:`annotations`,resource:{id:t.id,type:`Canvas`}}})};return C(ce,{children:[S(ue,{title:`Annotations`,actions:[{icon:S(j,{className:`text-2xl`}),title:`Add annotation`,disabled:!0,onClick:()=>void 0}]}),S(le,{children:C(`div`,{className:`flex flex-col items-center justify-center p-4`,children:[S(`div`,{className:`p-4 opacity-50 text-center`,children:`This canvas does not yet have any inline annotations. To add inline annotations, an AnnotationPage is created which will be linked to this canvas, and can then used to add your annotations. Simply use the link below to start adding your annotations`}),C(_,{large:!0,primary:!0,onPress:()=>r(),children:[S(ne,{className:`text-xl`}),` Create empty page`]}),S(Oe,{})]})})]})}function Ae(){let e=f(),r=h(),i=m(),{edit:a}=y(),o=E(i,e=>r?.id?e.canvasViewports[r.id]:null);return!e||!r||!o?null:C(`div`,{className:`p-2`,children:[S(d,{as:`div`,defaultText:S(`span`,{className:`opacity-50`,children:`Untitled`}),className:`whitespace-nowrap overflow-ellipsis w-full overflow-x-hidden`,children:e?.label}),S(d,{className:`text-gray-500 text-sm bg-white line-clamp-2 mb-4`,as:`div`,children:e?.summary}),S(n,{children:S(t,{viewport:o,onClick:()=>a(e,void 0,{forceOpen:!0})})})]})}function je(){let{isPending:e,cancelRequest:t,busy:n,requestAnnotationFromTarget:i,deleteAnnotation:s}=a(),[l,{highlightProps:u,annotationTarget:d}]=o(),{edit:f}=y(),p=l?.body||[],m=!l||p.length===0,[h,g]=T(!1);return C(`div`,{...u,className:`border border-gray-300 hover:border-me-500 shadow-sm rounded bg-white relative`,children:[S(`div`,{className:`relative`,children:d?S(c,{annotation:d,children:S(Ae,{})}):m?S(`div`,{className:`flex items-center justify-center px-4 py-6 text-gray-400 text-sm`,children:`This annotation has no body.`}):h?S(r,{className:`border-none`}):S(oe,{className:`px-3 pt-3 line-clamp-3 prose-p:text-slate-600`,locale:`en`})}),C(`div`,{className:`flex gap-2 p-2`,children:[d?S(_,{onPress:()=>f({id:d,type:`Annotation`},void 0,{forceOpen:!0}),children:`Edit painting annotation`}):h&&e?C(_,{primary:!0,onPress:()=>{g(!1),t()},children:[S(re,{}),` Finish editing`]}):C(_,{isDisabled:n,onPress:()=>{g(!0),i().then(()=>{g(!1)})},children:[S(ae,{}),` `,m?`Edit target`:`Edit`]}),C(_,{className:`gap-2 flex`,onPress:()=>s(),children:[S(ie,{}),` Delete`]})]})]})}function Me(){let t=h(),n=p(),{requestAnnotation:r,isActive:i,busy:a,cancelRequest:o}=te(),[s]=ee();if(s.type!==`images`)return S(`div`,{children:`Not supported`});if(!n)return null;let l=()=>r({type:`box`,annotationPopup:S(e,{annotationPageId:n.id,canvasId:t.id})});return C(ce,{children:[S(ue,{title:`Annotations`,actions:[{icon:S(j,{className:`text-2xl`}),title:`Add annotation`,disabled:i||a,onClick:l}]}),i?C(x,{children:[S(`button`,{"aria-label":`cancel add annotation`,className:`m-2 rounded border border-gray-300 bg-white px-3 py-2 text-sm text-gray-700`,type:`button`,onClick:()=>o(),children:`Exit edit mode`}),C(`div`,{className:`flex flex-col gap-5 text-center p-4 items-center justify-center`,children:[S(de,{className:`w-32 h-32 text-gray-300`}),S(`p`,{className:`text-gray-500`,children:`Draw a box on the canvas`})]})]}):null,C(le,{className:`w-full p-2 flex flex-col gap-2`,children:[n.items.map(e=>S(c,{annotation:e.id,children:S(je,{})},e.id)),!i&&n.items.length===0?C(`div`,{className:`flex flex-col items-center justify-center p-4`,children:[S(`div`,{className:`p-4 opacity-50 text-center`,children:`This canvas does not yet have any inline annotations.`}),C(_,{large:!0,primary:!0,isDisabled:i,onPress:()=>l(),children:[S(j,{className:`text-xl`}),` Add annotation`]}),S(Oe,{})]}):null]})]})}const Ne={id:O,label:`Annotations`,icon:S(A,{}),focusedMode:{closeOnMainPanelClick:!1},render:()=>S(Pe,{})};function Pe(){let e=s(`Canvas`)?.resource.source?.id,t=h({id:e}),n=t?.annotations[0];return t?n?S(l,{annotationPage:n.id,children:S(u,{canvas:t.id,children:S(Me,{})})}):S(u,{canvas:t.id,children:S(ke,{})}):C(`div`,{className:`flex flex-col gap-5 text-center p-4 items-center justify-center`,children:[S(A,{className:`w-32 h-32 text-gray-300`}),S(`p`,{className:`text-gray-500`,children:`Annotations are associated with Canvases in a IIIF Manifest. To view or add annotations, first create a Canvas and then select the Annotations link`})]})}const Fe={id:Ee,label:`Canvas annotations`,render:()=>S(Ie,{})};function Ie(){let e=h(),t=E(pe(),e=>e.tool.enabled),{leftPanel:n}=b(),r=n.current===O,a=e?.annotations[0];return!e||t||!a||!r?null:S(l,{annotationPage:a.id,children:S(i,{})})}const M=`@manifest-editor/annotations:bulk-import-config`,Le=[`commenting`,`supplementing`,`tagging`,`describing`,`linking`,`painting`,`highlighting`,`classifying`,`identifying`,`replying`];function Re(e){return new Promise(t=>{if(e.signal?.aborted){t(!1);return}let n=!1,r=r=>{n||(n=!0,e.signal?.removeEventListener(`abort`,i),t(r))},i=()=>r(!1);e.signal?.addEventListener(`abort`,i,{once:!0}),window.dispatchEvent(new CustomEvent(M,{detail:{...e,resolve:r}}))})}function ze(e){return S(Be,{actionId:e})}function N(){return{scope:`all`,motivationMode:`all`,motivations:[]}}function Be({actionId:e}){let[t,n]=T(null),[r,i]=T(N()),[a,o]=T(``);w(()=>{let t=t=>{let r=t.detail;r?.actionId===e&&(n(r),i(Ve(r.defaults,r.tags)),o(``))};return window.addEventListener(M,t),()=>window.removeEventListener(M,t)},[e]),w(()=>{if(!t?.signal)return;if(t.signal.aborted){n(null);return}let e=()=>n(null);return t.signal.addEventListener(`abort`,e,{once:!0}),()=>t.signal?.removeEventListener(`abort`,e)},[t]);let s=ye(()=>t?.tags.find(e=>e.key===r.tagKey),[t?.tags,r.tagKey]),c=r.scope===`tag`?s?.externalPageCount||0:t?.totalExternalPages||0,l=ye(()=>He(r,a),[a,r]),u=r.motivationMode===`selected`&&l.length===0;if(!t)return null;let d=e=>{t.resolve(e),n(null)},f=!t.tags.length;return S(se,{title:`Import External Annotation Pages`,onClose:()=>d(!1),className:`max-w-2xl`,actions:C(`div`,{className:`flex gap-2`,children:[S(`button`,{type:`button`,className:`rounded border border-zinc-300 bg-white px-3 py-2 text-sm text-zinc-700`,onClick:()=>d(!1),children:`Cancel`}),S(`button`,{type:`button`,className:`rounded border border-me-primary-500 bg-me-primary-500 px-3 py-2 text-sm text-white disabled:cursor-not-allowed disabled:opacity-50`,disabled:c===0||u,onClick:()=>d({...r,motivations:r.motivationMode===`selected`?l:[]}),children:`Import pages`})]}),children:C(`div`,{className:`flex min-h-0 flex-col gap-4 p-4 text-sm text-zinc-700`,children:[C(`fieldset`,{className:`grid gap-2`,children:[S(`legend`,{className:`font-medium text-zinc-900`,children:`Canvases`}),C(`label`,{className:`flex items-center gap-2`,children:[S(`input`,{type:`radio`,checked:r.scope===`all`,onChange:()=>i(e=>({...e,scope:`all`}))}),C(`span`,{children:[`All canvases with external annotation pages (`,t.totalExternalPages,`)`]})]}),C(`label`,{className:`flex items-center gap-2`,children:[S(`input`,{type:`radio`,checked:r.scope===`tag`,disabled:f,onChange:()=>i(e=>({...e,scope:`tag`,tagKey:e.tagKey||t.tags[0]?.key}))}),S(`span`,{children:`Only canvases with tag`})]}),S(`select`,{className:`rounded border border-zinc-300 bg-white p-2 disabled:bg-zinc-100`,disabled:r.scope!==`tag`||f,value:r.tagKey||``,onChange:e=>i(t=>({...t,tagKey:e.target.value})),children:t.tags.map(e=>C(`option`,{value:e.key,children:[e.label,` (`,e.externalPageCount,`)`]},e.key))})]}),C(`fieldset`,{className:`grid gap-2`,children:[S(`legend`,{className:`font-medium text-zinc-900`,children:`Motivations`}),C(`label`,{className:`flex items-center gap-2`,children:[S(`input`,{type:`radio`,checked:r.motivationMode===`all`,onChange:()=>i(e=>({...e,motivationMode:`all`}))}),S(`span`,{children:`All motivations`})]}),C(`label`,{className:`flex items-center gap-2`,children:[S(`input`,{type:`radio`,checked:r.motivationMode===`selected`,onChange:()=>i(e=>({...e,motivationMode:`selected`,motivations:e.motivations.length?e.motivations:[`commenting`]}))}),S(`span`,{children:`Only selected motivations`})]}),S(`div`,{className:`grid grid-cols-2 gap-2 rounded border border-zinc-200 p-3`,children:Le.map(e=>C(`label`,{className:`flex items-center gap-2`,children:[S(`input`,{type:`checkbox`,disabled:r.motivationMode!==`selected`,checked:r.motivations.includes(e),onChange:t=>i(n=>({...n,motivationMode:`selected`,motivations:t.target.checked?P([...n.motivations,e]):n.motivations.filter(t=>t!==e)}))}),S(`span`,{children:e})]},e))}),C(`label`,{className:`grid gap-1`,children:[S(`span`,{className:`font-medium text-zinc-900`,children:`Additional motivations`}),S(`input`,{type:`text`,className:`rounded border border-zinc-300 p-2`,disabled:r.motivationMode!==`selected`,value:a,placeholder:`transcribing, reviewing`,onChange:e=>o(e.target.value)})]})]}),C(`div`,{className:`rounded border border-zinc-200 bg-white p-3 text-zinc-600`,children:[c,` external annotation page`,c===1?``:`s`,` selected.`,r.motivationMode===`selected`?C(x,{children:[` `,l.length,` motivation`,l.length===1?``:`s`,` selected.`]}):null]})]})})}function Ve(e,t){let n=e.tagKey?t.some(t=>t.key===e.tagKey):!1;return{scope:e.scope===`tag`&&t.length?`tag`:`all`,tagKey:n?e.tagKey:t[0]?.key,motivationMode:e.motivationMode===`selected`?`selected`:`all`,motivations:P(e.motivations||[])}}function He(e,t){return e.motivationMode===`selected`?P([...e.motivations,...Ue(t)]):[]}function Ue(e){return e.split(/[,\n]/).map(e=>e.trim()).filter(Boolean)}function P(e){return Array.from(new Set(e.map(e=>e.trim()).filter(Boolean)))}const F=`iiif-parser:isExternal`,I=`iiif-parser:hasPart`,We=[`Annotation`,`AnnotationPage`,`ContentResource`,`Canvas`,`Manifest`,`Range`];function L(e,t){let n=[];for(let r of t)!r?.id||!Array.isArray(r.annotations)||r.annotations.forEach((t,i)=>{let a=G(t);if(!a)return;let o=e.get({id:a,type:`AnnotationPage`})||e.get(t)||t;Ke(o)&&n.push({key:`${r.id}:annotations:${i}:${a}`,canvasId:r.id,canvasLabel:at(r.label)||r.id,pageId:a,annotationPageIndex:i,existingPage:o})});return n}function Ge(e){let t=[],n=[],r=[],i=new Set,a=Ye(e.motivationFilter),o=0;for(let s of e.loadedPages){let{reference:e}=s;if(i.has(e.pageId)){n.push(B(e,`External annotation page is referenced more than once.`));continue}if(i.add(e.pageId),s.error){n.push(B(e,s.error));continue}let c=qe(s.json,e);if(c.warning&&r.push(c.warning),!c.page){n.push(B(e,c.error));continue}let l=c.page;if(!Array.isArray(l.items)){n.push(B(e,`Fetched annotation page does not contain an items array.`));continue}let u=l.items.filter(e=>e?.type===`Annotation`),d=u.filter(e=>Xe(e,a)),f=l.items.length-u.length,p=u.length-d.length;if(f&&r.push(`${e.pageId}: skipped ${f} non-Annotation item${f===1?``:`s`}.`),p&&r.push(`${e.pageId}: skipped ${p} annotation${p===1?``:`s`} outside the selected motivation filter.`),!d.length){n.push(B(e,Je(l.items.length,u.length,a)));continue}o+=d.length,t.push({reference:e,page:l,annotations:d,skippedAnnotations:f,skippedByMotivation:p})}return{totalExternalPages:e.loadedPages.length,totalAnnotations:o,pages:t,skippedPages:n,warnings:r,errors:[]}}function R(e,t){let n={AnnotationPage:{},Annotation:{},ContentResource:{}},r=[],i=rt(e),a=new Set,o=0;for(let e of t.pages){let{reference:t}=e,s=t.pageId,c=J(e.page);c.id=s,c.type=`AnnotationPage`,c.items=[],c[F]=!1,t.existingPage?.[I]&&(c[I]=J(t.existingPage[I])),n.AnnotationPage[s]=c,a.add(t.canvasId),r.push(we({id:s,type:`AnnotationPage`,key:F,value:!1}));for(let a of e.annotations){let e=J(a),c=i.preserveOrCreate(G(e),`Annotation`,t.canvasId,`external-annotation`),l=$e(e.body,i,t.canvasId,c);e.id=c,e.type=`Annotation`,e.body=l.body,e.target=z(e.target,t.canvasId),Object.assign(n.ContentResource,l.entities),n.Annotation[c]=e,r.push(xe({id:s,type:`AnnotationPage`,key:`items`,reference:{id:c,type:`Annotation`}})),o+=1}}let s=[Ce({entities:lt(n)}),...r];return(r.length||Object.values(n).some(e=>Object.keys(e).length))&&e.dispatch(Se({actions:s})),{totalExternalPages:t.totalExternalPages,pagesInlined:t.pages.length,canvasesUpdated:a.size,annotationsWritten:o,skippedPages:t.skippedPages,warnings:t.warnings}}function z(e,t){if(Array.isArray(e))return e.map(e=>z(e,t));if(typeof e==`string`)return W(e,t);if(!e||typeof e!=`object`)return e;let n=J(e);return typeof n.source==`string`?(n.source=W(n.source,t),n):n.source&&typeof n.source==`object`?(n.source={...n.source,id:t,type:n.source.type||`Canvas`},n):(typeof n.id==`string`&&(n.id=W(n.id,t)),n)}function Ke(e){return!!e?.[F]}function B(e,t){return{key:e.key,canvasId:e.canvasId,canvasLabel:e.canvasLabel,pageId:e.pageId,reason:t}}function qe(e,t){if(!e||typeof e!=`object`)return{error:`Fetched resource is not a JSON object.`};let n=e;if(n.type===`AnnotationPage`)return{page:n,error:``};if(Qe(n))try{let e=Te(n);return e?.type===`AnnotationPage`?{page:e,error:``,warning:`${t.pageId}: upgraded Presentation 2 sc:AnnotationList to AnnotationPage.`}:{error:`IIIF upgrade produced ${e?.type||`missing a type`}, not AnnotationPage.`}}catch(e){return{error:`Unable to upgrade Presentation 2 sc:AnnotationList: ${e instanceof Error?e.message:String(e)}`}}return{error:`Fetched resource is ${n.type||n[`@type`]||`missing a type`}, not AnnotationPage.`}}function Je(e,t,n){return e?t?n?.size?`No annotations matched the selected motivation filter (${Array.from(n).join(`, `)}).`:`Fetched annotation page does not contain importable annotations.`:`Fetched annotation page does not contain Annotation items.`:`Fetched annotation page is empty.`}function Ye(e){let t=ot((e||[]).map(V).filter(Boolean));return t.length?new Set(t):null}function Xe(e,t){return t?.size?Ze(e).some(e=>t.has(e)):!0}function Ze(e){return ot(q(e?.motivation).map(V).filter(Boolean))}function V(e){if(typeof e!=`string`)return``;let t=e.trim().toLowerCase(),n=t.includes(`:`)?t.slice(t.lastIndexOf(`:`)+1):t,r=n.lastIndexOf(`/`),i=n.lastIndexOf(`#`),a=Math.max(r,i);return a>=0?n.slice(a+1):n}function Qe(e){let t=e?.[`@type`]||e?.type;return t===`sc:AnnotationList`||t===`AnnotationList`}function $e(e,t,n,r){let i=e==null?[]:q(e),a={};return{body:i.length>1&&i.every(nt)?[U({type:`Choice`,items:i},t,n,r,`body-choice`,a)]:i.map((e,i)=>H(e,t,n,r,`body-${i+1}`,a)),entities:a}}function H(e,t,n,r,i,a){if(tt(e))return U(e,t,n,r,i,a);let o=t.preserveOrCreate(e&&typeof e==`object`?G(e):void 0,`ContentResource`,n,`${r}-${i}`);if(typeof e==`string`)return a[o]={id:o,type:`TextualBody`,format:`text/plain`,value:e},{id:o,type:`ContentResource`};if(e&&typeof e==`object`){let t=et(e);return a[o]={...t,id:o,type:t.type||`ContentResource`},{id:o,type:`ContentResource`}}return a[o]={id:o,type:`TextualBody`,format:`text/plain`,value:String(e)},{id:o,type:`ContentResource`}}function U(e,t,n,r,i,a){let o=t.preserveOrCreate(G(e),`ContentResource`,n,`${r}-${i}`),s=q(e.items).map((e,o)=>H(e,t,n,r,`${i}-item-${o+1}`,a));return a[o]={...J(e),id:o,type:`Choice`,items:s},{id:o,type:`ContentResource`}}function et(e){let t=J(e);return typeof t.chars==`string`&&t.value===void 0&&(t.value=t.chars,delete t.chars,t.type===`Text`&&(t.type=`TextualBody`)),t}function tt(e){return!!e&&typeof e==`object`&&e.type===`Choice`}function nt(e){if(typeof e==`string`)return!0;if(!e||typeof e!=`object`)return!1;let t=e.type;return t===`TextualBody`||t===`Text`}function rt(e){let t=new Set,n=0;function r(n){return t.has(n)?!0:We.some(t=>!!e.get({id:n,type:t}))}function i(e,i,a){let o;do n+=1,o=`${ct(e)}/external-annotation-pages/${st(i)}/${st(a)}-${n}`;while(r(o));return t.add(o),o}function a(e,n,a,o){return e&&!r(e)?(t.add(e),e):i(a,n,o)}return{create:i,preserveOrCreate:a}}function it(e){let t=e.indexOf(`#`);return{sourceId:t>=0?e.slice(0,t):e,fragment:t>=0?e.slice(t):``}}function W(e,t){return`${t}${it(e).fragment}`}function G(e){if(typeof e==`string`)return e;if(!(!e||typeof e!=`object`))return typeof e.id==`string`?e.id:typeof e[`@id`]==`string`?e[`@id`]:void 0}function K(e){return e?typeof e==`string`?[e]:Array.isArray(e)?e.filter(e=>typeof e==`string`):typeof e==`object`?Object.values(e).flatMap(K):[]:[]}function at(e){return K(e)[0]||``}function ot(e){return Array.from(new Set(e.filter(Boolean)))}function q(e){return Array.isArray(e)?e:e==null?[]:[e]}function J(e){return JSON.parse(JSON.stringify(e))}function st(e){return e.toLowerCase().replace(/[^a-z0-9]+/g,`-`).replace(/^-+|-+$/g,``).slice(0,80)||`item`}function ct(e){return e.endsWith(`/`)?e.slice(0,-1):e}function lt(e){return Object.fromEntries(Object.entries(e).filter(([,e])=>Object.keys(e).length))}const Y=`@manifest-editor/annotations:bulk-import-results`;function ut(e,t){window.dispatchEvent(new CustomEvent(Y,{detail:{actionId:e,result:t}}))}function dt(e){return S(ft,{actionId:e})}function ft({actionId:e}){let[t,n]=T(null);return w(()=>{let t=t=>{let r=t.detail;r?.actionId===e&&r.result&&n(r.result)};return window.addEventListener(Y,t),()=>window.removeEventListener(Y,t)},[e]),t?S(se,{title:`External annotation page import results`,onClose:()=>n(null),className:`max-w-3xl`,children:C(`div`,{className:`flex min-h-0 flex-col gap-4 p-4 text-sm text-zinc-700`,children:[C(`div`,{className:`grid grid-cols-4 gap-2`,children:[S(X,{label:`External pages`,value:t.totalExternalPages}),S(X,{label:`Inlined pages`,value:t.pagesInlined}),S(X,{label:`Canvases`,value:t.canvasesUpdated}),S(X,{label:`Annotations`,value:t.annotationsWritten})]}),t.warnings.length?S(`div`,{className:`rounded border border-amber-200 bg-amber-50 p-3 text-amber-900`,children:t.warnings.map(e=>S(`div`,{children:e},e))}):null,t.skippedPages.length?C(`div`,{className:`rounded border border-zinc-200`,children:[S(`div`,{className:`border-b border-zinc-200 bg-zinc-50 px-3 py-2 font-medium`,children:`Skipped external pages`}),S(`div`,{className:`max-h-64 overflow-auto`,children:t.skippedPages.map(e=>C(`div`,{className:`grid gap-1 border-b border-zinc-100 px-3 py-2 last:border-0`,children:[S(`div`,{className:`truncate font-medium text-zinc-900`,children:e.pageId}),S(`div`,{className:`truncate text-zinc-500`,children:e.canvasLabel}),S(`div`,{className:`text-zinc-500`,children:e.reason})]},e.key))})]}):null]})}):null}function X({label:e,value:t}){return C(`div`,{className:`rounded border border-zinc-200 bg-zinc-50 p-3`,children:[S(`div`,{className:`text-xl font-semibold text-zinc-900`,children:t}),S(`div`,{className:`text-xs uppercase tracking-wide text-zinc-500`,children:e})]})}const Z=new Map;function pt(e={}){let t=e.fetchPage||mt,n=e.requestConfig||ht;return{id:k,label:`Bulk Annotation Page Importer`,summary:`Load external Canvas annotation pages and make them editable inline`,section:`Annotations`,order:10,resourceTypes:[`Manifest`],resumable:!1,render:e=>C(x,{children:[ze(e.definition.id),dt(e.definition.id)]}),onResults:e=>ut(e.definition.id,e.instance?.result),supports:e=>L(e.vault,Q(e)).length>0,prepare:async e=>{let t=L(e.vault,Q(e));if(!t.length)return!1;let r=await n(e,t,N());if(r===!1)return!1;let i=gt(e,t,r);return i.length?(Z.set(e.instanceKey,{references:i,options:r}),!0):!1},run:async e=>{let n=Z.get(e.instanceKey),r=n?.options||N(),i=n?.references||gt(e,L(e.vault,Q(e)),r);try{if(e.setActionLabel(`Importing external annotation pages`),e.setActionProgress({current:0,total:Math.max(i.length,1),label:`Loading external annotation pages`}),!i.length)return e.setActionStatus(`running`,`No external annotation pages found`),yt();let n=[];for(let[r,a]of i.entries()){bt(e.signal),e.setActionStatus(`running`,`Loading ${r+1}/${i.length}`),e.appendActionLog(`Loading external annotation page`,`info`,{canvasId:a.canvasId,pageId:a.pageId});try{let r=await t(a.pageId,a,e);n.push({reference:a,json:r})}catch(t){let r=xt(t);n.push({reference:a,error:r}),e.appendActionLog(`Failed to load external annotation page`,`warn`,{canvasId:a.canvasId,pageId:a.pageId,reason:r})}e.setActionProgress({current:r+1,total:i.length,label:`Loading external annotation pages`})}let a=Ge({loadedPages:n,motivationFilter:r.motivationMode===`selected`?r.motivations:void 0});if(a.errors.length)throw Error(a.errors[0]||`External annotation page import failed.`);e.setActionStatus(`running`,`Writing inline annotation pages`),e.setActionProgress({current:0,total:Math.max(a.totalAnnotations,a.pages.length,1),label:`Writing inline annotations`});let o=R(e.vault,a);return e.appendActionLog(`External annotation page import complete`,`info`,{pages:o.pagesInlined,annotations:o.annotationsWritten,skipped:o.skippedPages.length}),e.setActionStatus(`running`,`Imported ${o.pagesInlined}/${o.totalExternalPages} external pages`),e.setActionProgress({current:Math.max(o.annotationsWritten,o.pagesInlined),total:Math.max(o.annotationsWritten,o.pagesInlined,1),label:`Import complete`}),o}finally{Z.delete(e.instanceKey)}}}}async function mt(e,t,n){let r=await fetch(e,{signal:n.signal,headers:{Accept:`application/ld+json, application/json;q=0.9, */*;q=0.1`}});if(!r.ok)throw Error(`Unable to fetch ${e} (${r.status}).`);return r.json()}async function ht(e,t,n){return Re({actionId:e.definition.id,instanceKey:e.instanceKey,totalExternalPages:t.length,tags:_t(e,t),defaults:n,signal:e.signal})}function Q(e){let t=e.vault.get(e.target);return t?.items?(e.vault.get(t.items)||[]).filter(Boolean):[]}function gt(e,t,n){if(n.scope!==`tag`||!n.tagKey)return t;let r=vt(n.tagKey);return r?t.filter(t=>e.tags.hasTag({id:t.canvasId,type:`Canvas`},r.type,r.id)):[]}function _t(e,t){let n=new Map,r=new Map;n.set($(v),{...v,key:$(v),canvasCount:0,externalPageCount:0});for(let e of t)r.set(e.canvasId,(r.get(e.canvasId)||0)+1);for(let[t,i]of r)for(let r of e.tags.getTags({id:t,type:`Canvas`})){let e=$(r),t=n.get(e);t?(t.canvasCount+=1,t.externalPageCount+=i):n.set(e,{...r,key:e,canvasCount:1,externalPageCount:i})}return Array.from(n.values()).sort((e,t)=>e.type===v.type&&e.id===v.id?-1:t.type===v.type&&t.id===v.id?1:e.label.localeCompare(t.label)||e.type.localeCompare(t.type)||e.id.localeCompare(t.id))}function $(e){return`${e.type}:${e.id}`}function vt(e){let t=e.indexOf(`:`);return t===-1?null:{type:e.slice(0,t),id:e.slice(t+1)}}function yt(){return{totalExternalPages:0,pagesInlined:0,canvasesUpdated:0,annotationsWritten:0,skippedPages:[],warnings:[]}}function bt(e){if(e.aborted)throw new DOMException(`Aborted`,`AbortError`)}function xt(e){return e instanceof Error?e.message:String(e||`Unknown error`)}const St={id:`@manifest-editor/annotations-routing`,label:`Annotation routing`,render:()=>S(Ct,{})};function Ct(){let e=g(),t=s(`Canvas`),n=ve(),{leftPanel:r,rightPanel:i}=b(),{edit:a,open:o,rightPanel:c}=y(),l=be(null),[u,d]=T(!1);return w(()=>{let e=t?.resource?.source?.id;e&&(l.current=e)},[t?.resource?.source?.id]),w(()=>{if(r.current===O){let t=l.current||e?.items?.[0]?.id;if(t&&(o({id:`current-canvas`}),a({id:t,type:`Canvas`})),n===`focused`)return;i.open&&(c.close(),d(!0));return}u&&!i.open&&r.current!==`@manifest-editor/ranges-listing`&&(c.open(),d(!1))},[r.current,n]),null}var wt={id:D,label:`Annotations`,description:`Create, view, and inline external supplemental canvas annotation pages.`,author:`Digirati`,official:!0,defaultEnabled:!0,tags:[`annotations`,`iiif`,`external-pages`],supports:{apps:[`manifest-editor`],projectTypes:[`Manifest`]}};const Tt=[Ne],Et=[Fe],Dt=[St],Ot=[pt()];export{O as ANNOTATIONS_LEFT_PANEL_ID,D as ANNOTATIONS_PLUGIN_ID,k as BULK_ANNOTATION_IMPORT_ACTION_ID,Ee as CANVAS_ANNOTATIONS_PANEL_ID,Et as annotations,Dt as background,Ot as backgroundActions,pt as createBulkAnnotationImportBackgroundAction,Ge as createExternalAnnotationPageInlinePlan,wt as default,L as findExternalAnnotationPageReferences,Tt as leftPanels,z as rewriteAnnotationTarget,R as writeExternalAnnotationPageInlinePlan};
|
|
1
|
+
import{AnnotationCreationPopup as e,AnnotationPreview as t,CanvasTargetContext as n,HTMLAnnotationEditor as r,ViewerAnnotationPage as i,useAnnotationEditor as a,useAnnotationInfo as o,useInStack as s}from"@manifest-editor/editors";import{AnnotationContext as c,AnnotationPageContext as l,CanvasContext as u,LocaleString as d,useAnnotation as f,useAnnotationPage as p,useAtlasStore as m,useCanvas as h,useManifest as g,useRenderingStrategy as ee,useRequestAnnotation as te}from"react-iiif-vault";import{ActionButton as _,AddIcon as ne,CheckIcon as re,DeleteIcon as ie,EditTextIcon as ae,HTMLAnnotationBodyRender as oe,Modal as se,Sidebar as ce,SidebarContent as le,SidebarHeader as v,TargetIcon as ue}from"@manifest-editor/components";import{FLAG_TAG as y,runBackgroundAction as de,useAtlasStore as fe,useAvailableBackgroundActions as pe,useBackgroundActionsStoreApi as me,useCanvasProgressStatus as he,useInlineCreator as ge,useLayoutActions as b,useLayoutMode as _e,useLayoutState as x}from"@manifest-editor/shell";import{Fragment as S,jsx as C,jsxs as w}from"react/jsx-runtime";import{useEffect as T,useMemo as ve,useRef as ye,useState as E}from"react";import{useStore as D}from"zustand";import{addReference as be,batchActions as xe,importEntities as Se,modifyEntityField as Ce}from"@iiif/helpers/vault/actions";import{convertPresentation2 as we}from"@iiif/parser/presentation-2";const Te=`@manifest-editor/annotations`,O=`@manifest-editor/canvas-annotation-listing`,k=`@manifest-editor/canvas-annotations`,A=`@manifest-editor/annotations/bulk-import-pages`;function Ee(e){return C(`svg`,{xmlns:`http://www.w3.org/2000/svg`,width:`1em`,height:`1em`,viewBox:`0 0 24 24`,...e,children:C(`path`,{fill:`currentColor`,d:`M20 2H4c-1.1 0-1.99.9-1.99 2L2 22l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2m0 14H5.17l-.59.59l-.58.58V4h16zm-9.5-2H18v-2h-5.5zm3.86-5.87c.2-.2.2-.51 0-.71l-1.77-1.77c-.2-.2-.51-.2-.71 0L6 11.53V14h2.47z`})})}function j(e){return C(`svg`,{xmlns:`http://www.w3.org/2000/svg`,width:`1em`,height:`1em`,viewBox:`0 0 24 24`,...e,children:C(`path`,{fill:`currentColor`,d:`M9 22a1 1 0 0 1-1-1v-3H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2h-6.1l-3.7 3.71c-.2.19-.45.29-.7.29zm1-6v3.08L13.08 16H20V4H4v12zm1-10h2v3h3v2h-3v3h-2v-3H8V9h3z`})})}const De=[{id:`@manifest-editor/ocr-docling/run-ocr`,label:`Run Local OCR`,preparingLabel:`Preparing OCR`,queuedLabel:`OCR queued`,pendingLabel:`OCR in progress`},{id:`@manifest-editor/remote-inference/action`,label:`Run remote OCR`,preparingLabel:`Preparing local OCR`,queuedLabel:`OCR queued`,pendingLabel:`OCR in progress`},{id:`@manifest-editor/remote-inference/structured-output`,label:`Run structured output`,preparingLabel:`Preparing structured output`,queuedLabel:`Structured output queued`,pendingLabel:`Structured output in progress`}];function Oe(){let e=me(),t=pe(),n=h(),r=he(n),i=t.flatMap(e=>e.actions),a=De.map(e=>{let t=i.find(t=>t.definition.id===e.id);return t?{...e,action:t}:null}).filter(e=>!!e);if(!a.length)return null;let o=a.find(({action:e})=>{let t=e.instance?.status;return t!==`preparing`&&t!==`running`?!1:r===`queued`||r===`pending`||e.context.currentCanvas?.id===n?.id});return w(`div`,{className:`mt-5 flex w-full flex-col items-stretch gap-2 border-t border-gray-200 pt-4`,children:[C(`div`,{className:`text-center text-xs font-semibold uppercase tracking-wide text-gray-500`,children:`OCR and structured output`}),o?w(`div`,{className:`rounded border border-amber-200 bg-amber-50 px-3 py-2 text-center text-sm text-amber-800`,children:[C(`div`,{className:`font-medium`,children:r===`queued`?o.queuedLabel:r===`pending`?o.pendingLabel:o.preparingLabel}),C(`div`,{className:`mt-1 text-xs text-amber-700`,children:o.action.instance?.statusText||o.label})]}):null,o?null:a.map(({id:t,label:n,action:r})=>{let i=r.instance?.status===`preparing`||r.instance?.status===`running`;return C(_,{large:!0,isDisabled:i,onPress:()=>{i||de({store:e,context:r.context,prepareData:{scope:`selected`}})},children:n},t)})]})}function ke(){let e=s(`Canvas`)?.resource.source?.id,t=h({id:e}),n=ge(),r=()=>{t&&n.create(`@manifest-editor/empty-annotation-page`,{label:{en:[`Inline annotations`]}},{target:{id:t.id,type:`Canvas`},targetType:`AnnotationPage`,parent:{property:`annotations`,resource:{id:t.id,type:`Canvas`}}})};return w(ce,{children:[C(v,{title:`Annotations`,actions:[{icon:C(j,{className:`text-2xl`}),title:`Add annotation`,disabled:!0,onClick:()=>void 0}]}),C(le,{children:w(`div`,{className:`flex flex-col items-center justify-center p-4`,children:[C(`div`,{className:`p-4 opacity-50 text-center`,children:`This canvas does not yet have any inline annotations. To add inline annotations, an AnnotationPage is created which will be linked to this canvas, and can then used to add your annotations. Simply use the link below to start adding your annotations`}),w(_,{large:!0,primary:!0,onPress:()=>r(),children:[C(ne,{className:`text-xl`}),` Create empty page`]}),C(Oe,{})]})})]})}function Ae(){let e=f(),r=h(),i=m(),{edit:a}=b(),o=D(i,e=>r?.id?e.canvasViewports[r.id]:null);return!e||!r||!o?null:w(`div`,{className:`p-2`,children:[C(d,{as:`div`,defaultText:C(`span`,{className:`opacity-50`,children:`Untitled`}),className:`whitespace-nowrap overflow-ellipsis w-full overflow-x-hidden`,children:e?.label}),C(d,{className:`text-gray-500 text-sm bg-white line-clamp-2 mb-4`,as:`div`,children:e?.summary}),C(n,{children:C(t,{viewport:o,onClick:()=>a(e,void 0,{forceOpen:!0})})})]})}function je(){let{isPending:e,cancelRequest:t,busy:n,requestAnnotationFromTarget:i,deleteAnnotation:s}=a(),[l,{highlightProps:u,annotationTarget:d}]=o(),{edit:f}=b(),p=l?.body||[],m=!l||p.length===0,[h,g]=E(!1);return w(`div`,{...u,className:`border border-gray-300 hover:border-me-500 shadow-sm rounded bg-white relative`,children:[C(`div`,{className:`relative`,children:d?C(c,{annotation:d,children:C(Ae,{})}):m?C(`div`,{className:`flex items-center justify-center px-4 py-6 text-gray-400 text-sm`,children:`This annotation has no body.`}):h?C(r,{className:`border-none`}):C(oe,{className:`px-3 pt-3 line-clamp-3 prose-p:text-slate-600`,locale:`en`})}),w(`div`,{className:`flex gap-2 p-2`,children:[d?C(_,{onPress:()=>f({id:d,type:`Annotation`},void 0,{forceOpen:!0}),children:`Edit painting annotation`}):h&&e?w(_,{primary:!0,onPress:()=>{g(!1),t()},children:[C(re,{}),` Finish editing`]}):w(_,{isDisabled:n,onPress:()=>{g(!0),i().then(()=>{g(!1)})},children:[C(ae,{}),` `,m?`Edit target`:`Edit`]}),w(_,{className:`gap-2 flex`,onPress:()=>s(),children:[C(ie,{}),` Delete`]})]})]})}function Me(){let t=h(),n=p(),{requestAnnotation:r,isActive:i,busy:a,cancelRequest:o}=te(),[s]=ee();if(s.type!==`images`)return C(`div`,{children:`Not supported`});if(!n)return null;let l=()=>r({type:`box`,annotationPopup:C(e,{annotationPageId:n.id,canvasId:t.id})});return w(ce,{children:[C(v,{title:`Annotations`,actions:[{icon:C(j,{className:`text-2xl`}),title:`Add annotation`,disabled:i||a,onClick:l}]}),i?w(S,{children:[C(`button`,{"aria-label":`cancel add annotation`,className:`m-2 rounded border border-gray-300 bg-white px-3 py-2 text-sm text-gray-700`,type:`button`,onClick:()=>o(),children:`Exit edit mode`}),w(`div`,{className:`flex flex-col gap-5 text-center p-4 items-center justify-center`,children:[C(ue,{className:`w-32 h-32 text-gray-300`}),C(`p`,{className:`text-gray-500`,children:`Draw a box on the canvas`})]})]}):null,w(le,{className:`w-full p-2 flex flex-col gap-2`,children:[n.items.map(e=>C(c,{annotation:e.id,children:C(je,{})},e.id)),!i&&n.items.length===0?w(`div`,{className:`flex flex-col items-center justify-center p-4`,children:[C(`div`,{className:`p-4 opacity-50 text-center`,children:`This canvas does not yet have any inline annotations.`}),w(_,{large:!0,primary:!0,isDisabled:i,onPress:()=>l(),children:[C(j,{className:`text-xl`}),` Add annotation`]}),C(Oe,{})]}):null]})]})}const Ne={id:O,label:`Annotations`,icon:C(Ee,{}),focusedMode:{closeOnMainPanelClick:!1},render:()=>C(Pe,{})};function Pe(){let e=s(`Canvas`)?.resource.source?.id,t=h({id:e}),n=t?.annotations[0];return t?n?C(l,{annotationPage:n.id,children:C(u,{canvas:t.id,children:C(Me,{})})}):C(u,{canvas:t.id,children:C(ke,{})}):w(`div`,{className:`flex flex-col gap-5 text-center p-4 items-center justify-center`,children:[C(Ee,{className:`w-32 h-32 text-gray-300`}),C(`p`,{className:`text-gray-500`,children:`Annotations are associated with Canvases in a IIIF Manifest. To view or add annotations, first create a Canvas and then select the Annotations link`})]})}const Fe={id:k,label:`Canvas annotations`,render:()=>C(Ie,{})};function Ie(){let e=h(),t=fe(),n=D(t,e=>e.tool.enabled),{leftPanel:r}=x(),a=r.current===O,o=e?.annotations[0];return!e||n||!o||!a?null:C(l,{annotationPage:o.id,children:C(i,{})})}const M=`@manifest-editor/annotations:bulk-import-config`,Le=[`commenting`,`supplementing`,`tagging`,`describing`,`linking`,`painting`,`highlighting`,`classifying`,`identifying`,`replying`];function Re(e){return new Promise(t=>{if(e.signal?.aborted){t(!1);return}let n=!1,r=r=>{n||(n=!0,e.signal?.removeEventListener(`abort`,i),t(r))},i=()=>r(!1);e.signal?.addEventListener(`abort`,i,{once:!0}),window.dispatchEvent(new CustomEvent(M,{detail:{...e,resolve:r}}))})}function ze(e){return C(Be,{actionId:e})}function N(){return{scope:`all`,motivationMode:`all`,motivations:[]}}function Be({actionId:e}){let[t,n]=E(null),[r,i]=E(N()),[a,o]=E(``);T(()=>{let t=t=>{let r=t.detail;r?.actionId===e&&(n(r),i(Ve(r.defaults,r.tags)),o(``))};return window.addEventListener(M,t),()=>window.removeEventListener(M,t)},[e]),T(()=>{if(!t?.signal)return;if(t.signal.aborted){n(null);return}let e=()=>n(null);return t.signal.addEventListener(`abort`,e,{once:!0}),()=>t.signal?.removeEventListener(`abort`,e)},[t]);let s=ve(()=>t?.tags.find(e=>e.key===r.tagKey),[t?.tags,r.tagKey]),c=r.scope===`tag`?s?.externalPageCount||0:t?.totalExternalPages||0,l=ve(()=>He(r,a),[a,r]),u=r.motivationMode===`selected`&&l.length===0;if(!t)return null;let d=e=>{t.resolve(e),n(null)},f=!t.tags.length;return C(se,{title:`Import External Annotation Pages`,onClose:()=>d(!1),className:`max-w-2xl`,actions:w(`div`,{className:`flex gap-2`,children:[C(`button`,{type:`button`,className:`rounded border border-zinc-300 bg-white px-3 py-2 text-sm text-zinc-700`,onClick:()=>d(!1),children:`Cancel`}),C(`button`,{type:`button`,className:`rounded border border-me-primary-500 bg-me-primary-500 px-3 py-2 text-sm text-white disabled:cursor-not-allowed disabled:opacity-50`,disabled:c===0||u,onClick:()=>d({...r,motivations:r.motivationMode===`selected`?l:[]}),children:`Import pages`})]}),children:w(`div`,{className:`flex min-h-0 flex-col gap-4 p-4 text-sm text-zinc-700`,children:[w(`fieldset`,{className:`grid gap-2`,children:[C(`legend`,{className:`font-medium text-zinc-900`,children:`Canvases`}),w(`label`,{className:`flex items-center gap-2`,children:[C(`input`,{type:`radio`,checked:r.scope===`all`,onChange:()=>i(e=>({...e,scope:`all`}))}),w(`span`,{children:[`All canvases with external annotation pages (`,t.totalExternalPages,`)`]})]}),w(`label`,{className:`flex items-center gap-2`,children:[C(`input`,{type:`radio`,checked:r.scope===`tag`,disabled:f,onChange:()=>i(e=>({...e,scope:`tag`,tagKey:e.tagKey||t.tags[0]?.key}))}),C(`span`,{children:`Only canvases with tag`})]}),C(`select`,{className:`rounded border border-zinc-300 bg-white p-2 disabled:bg-zinc-100`,disabled:r.scope!==`tag`||f,value:r.tagKey||``,onChange:e=>i(t=>({...t,tagKey:e.target.value})),children:t.tags.map(e=>w(`option`,{value:e.key,children:[e.label,` (`,e.externalPageCount,`)`]},e.key))})]}),w(`fieldset`,{className:`grid gap-2`,children:[C(`legend`,{className:`font-medium text-zinc-900`,children:`Motivations`}),w(`label`,{className:`flex items-center gap-2`,children:[C(`input`,{type:`radio`,checked:r.motivationMode===`all`,onChange:()=>i(e=>({...e,motivationMode:`all`}))}),C(`span`,{children:`All motivations`})]}),w(`label`,{className:`flex items-center gap-2`,children:[C(`input`,{type:`radio`,checked:r.motivationMode===`selected`,onChange:()=>i(e=>({...e,motivationMode:`selected`,motivations:e.motivations.length?e.motivations:[`commenting`]}))}),C(`span`,{children:`Only selected motivations`})]}),C(`div`,{className:`grid grid-cols-2 gap-2 rounded border border-zinc-200 p-3`,children:Le.map(e=>w(`label`,{className:`flex items-center gap-2`,children:[C(`input`,{type:`checkbox`,disabled:r.motivationMode!==`selected`,checked:r.motivations.includes(e),onChange:t=>i(n=>({...n,motivationMode:`selected`,motivations:t.target.checked?P([...n.motivations,e]):n.motivations.filter(t=>t!==e)}))}),C(`span`,{children:e})]},e))}),w(`label`,{className:`grid gap-1`,children:[C(`span`,{className:`font-medium text-zinc-900`,children:`Additional motivations`}),C(`input`,{type:`text`,className:`rounded border border-zinc-300 p-2`,disabled:r.motivationMode!==`selected`,value:a,placeholder:`transcribing, reviewing`,onChange:e=>o(e.target.value)})]})]}),w(`div`,{className:`rounded border border-zinc-200 bg-white p-3 text-zinc-600`,children:[c,` external annotation page`,c===1?``:`s`,` selected.`,r.motivationMode===`selected`?w(S,{children:[` `,l.length,` motivation`,l.length===1?``:`s`,` selected.`]}):null]})]})})}function Ve(e,t){let n=e.tagKey?t.some(t=>t.key===e.tagKey):!1;return{scope:e.scope===`tag`&&t.length?`tag`:`all`,tagKey:n?e.tagKey:t[0]?.key,motivationMode:e.motivationMode===`selected`?`selected`:`all`,motivations:P(e.motivations||[])}}function He(e,t){return e.motivationMode===`selected`?P([...e.motivations,...Ue(t)]):[]}function Ue(e){return e.split(/[,\n]/).map(e=>e.trim()).filter(Boolean)}function P(e){return Array.from(new Set(e.map(e=>e.trim()).filter(Boolean)))}const F=`iiif-parser:isExternal`,I=`iiif-parser:hasPart`,We=[`Annotation`,`AnnotationPage`,`ContentResource`,`Canvas`,`Manifest`,`Range`];function L(e,t){let n=[];for(let r of t)!r?.id||!Array.isArray(r.annotations)||r.annotations.forEach((t,i)=>{let a=G(t);if(!a)return;let o=e.get({id:a,type:`AnnotationPage`})||e.get(t)||t;Ke(o)&&n.push({key:`${r.id}:annotations:${i}:${a}`,canvasId:r.id,canvasLabel:at(r.label)||r.id,pageId:a,annotationPageIndex:i,existingPage:o})});return n}function R(e){let t=[],n=[],r=[],i=new Set,a=Ye(e.motivationFilter),o=0;for(let s of e.loadedPages){let{reference:e}=s;if(i.has(e.pageId)){n.push(B(e,`External annotation page is referenced more than once.`));continue}if(i.add(e.pageId),s.error){n.push(B(e,s.error));continue}let c=qe(s.json,e);if(c.warning&&r.push(c.warning),!c.page){n.push(B(e,c.error));continue}let l=c.page;if(!Array.isArray(l.items)){n.push(B(e,`Fetched annotation page does not contain an items array.`));continue}let u=l.items.filter(e=>e?.type===`Annotation`),d=u.filter(e=>Xe(e,a)),f=l.items.length-u.length,p=u.length-d.length;if(f&&r.push(`${e.pageId}: skipped ${f} non-Annotation item${f===1?``:`s`}.`),p&&r.push(`${e.pageId}: skipped ${p} annotation${p===1?``:`s`} outside the selected motivation filter.`),!d.length){n.push(B(e,Je(l.items.length,u.length,a)));continue}o+=d.length,t.push({reference:e,page:l,annotations:d,skippedAnnotations:f,skippedByMotivation:p})}return{totalExternalPages:e.loadedPages.length,totalAnnotations:o,pages:t,skippedPages:n,warnings:r,errors:[]}}function Ge(e,t){let n={AnnotationPage:{},Annotation:{},ContentResource:{}},r=[],i=rt(e),a=new Set,o=0;for(let e of t.pages){let{reference:t}=e,s=t.pageId,c=J(e.page);c.id=s,c.type=`AnnotationPage`,c.items=[],c[F]=!1,t.existingPage?.[I]&&(c[I]=J(t.existingPage[I])),n.AnnotationPage[s]=c,a.add(t.canvasId),r.push(Ce({id:s,type:`AnnotationPage`,key:F,value:!1}));for(let a of e.annotations){let e=J(a),c=i.preserveOrCreate(G(e),`Annotation`,t.canvasId,`external-annotation`),l=$e(e.body,i,t.canvasId,c);e.id=c,e.type=`Annotation`,e.body=l.body,e.target=z(e.target,t.canvasId),Object.assign(n.ContentResource,l.entities),n.Annotation[c]=e,r.push(be({id:s,type:`AnnotationPage`,key:`items`,reference:{id:c,type:`Annotation`}})),o+=1}}let s=[Se({entities:lt(n)}),...r];return(r.length||Object.values(n).some(e=>Object.keys(e).length))&&e.dispatch(xe({actions:s})),{totalExternalPages:t.totalExternalPages,pagesInlined:t.pages.length,canvasesUpdated:a.size,annotationsWritten:o,skippedPages:t.skippedPages,warnings:t.warnings}}function z(e,t){if(Array.isArray(e))return e.map(e=>z(e,t));if(typeof e==`string`)return W(e,t);if(!e||typeof e!=`object`)return e;let n=J(e);return typeof n.source==`string`?(n.source=W(n.source,t),n):n.source&&typeof n.source==`object`?(n.source={...n.source,id:t,type:n.source.type||`Canvas`},n):(typeof n.id==`string`&&(n.id=W(n.id,t)),n)}function Ke(e){return!!e?.[F]}function B(e,t){return{key:e.key,canvasId:e.canvasId,canvasLabel:e.canvasLabel,pageId:e.pageId,reason:t}}function qe(e,t){if(!e||typeof e!=`object`)return{error:`Fetched resource is not a JSON object.`};let n=e;if(n.type===`AnnotationPage`)return{page:n,error:``};if(Qe(n))try{let e=we(n);return e?.type===`AnnotationPage`?{page:e,error:``,warning:`${t.pageId}: upgraded Presentation 2 sc:AnnotationList to AnnotationPage.`}:{error:`IIIF upgrade produced ${e?.type||`missing a type`}, not AnnotationPage.`}}catch(e){return{error:`Unable to upgrade Presentation 2 sc:AnnotationList: ${e instanceof Error?e.message:String(e)}`}}return{error:`Fetched resource is ${n.type||n[`@type`]||`missing a type`}, not AnnotationPage.`}}function Je(e,t,n){return e?t?n?.size?`No annotations matched the selected motivation filter (${Array.from(n).join(`, `)}).`:`Fetched annotation page does not contain importable annotations.`:`Fetched annotation page does not contain Annotation items.`:`Fetched annotation page is empty.`}function Ye(e){let t=ot((e||[]).map(V).filter(Boolean));return t.length?new Set(t):null}function Xe(e,t){return!t?.size||Ze(e).some(e=>t.has(e))}function Ze(e){return ot(q(e?.motivation).map(V).filter(Boolean))}function V(e){if(typeof e!=`string`)return``;let t=e.trim().toLowerCase(),n=t.includes(`:`)?t.slice(t.lastIndexOf(`:`)+1):t,r=n.lastIndexOf(`/`),i=n.lastIndexOf(`#`),a=Math.max(r,i);return a>=0?n.slice(a+1):n}function Qe(e){let t=e?.[`@type`]||e?.type;return t===`sc:AnnotationList`||t===`AnnotationList`}function $e(e,t,n,r){let i=e==null?[]:q(e),a={};return{body:i.length>1&&i.every(nt)?[U({type:`Choice`,items:i},t,n,r,`body-choice`,a)]:i.map((e,i)=>H(e,t,n,r,`body-${i+1}`,a)),entities:a}}function H(e,t,n,r,i,a){if(tt(e))return U(e,t,n,r,i,a);let o=t.preserveOrCreate(e&&typeof e==`object`?G(e):void 0,`ContentResource`,n,`${r}-${i}`);if(typeof e==`string`)return a[o]={id:o,type:`TextualBody`,format:`text/plain`,value:e},{id:o,type:`ContentResource`};if(e&&typeof e==`object`){let t=et(e);return a[o]={...t,id:o,type:t.type||`ContentResource`},{id:o,type:`ContentResource`}}return a[o]={id:o,type:`TextualBody`,format:`text/plain`,value:String(e)},{id:o,type:`ContentResource`}}function U(e,t,n,r,i,a){let o=t.preserveOrCreate(G(e),`ContentResource`,n,`${r}-${i}`),s=q(e.items).map((e,o)=>H(e,t,n,r,`${i}-item-${o+1}`,a));return a[o]={...J(e),id:o,type:`Choice`,items:s},{id:o,type:`ContentResource`}}function et(e){let t=J(e);return typeof t.chars==`string`&&t.value===void 0&&(t.value=t.chars,delete t.chars,t.type===`Text`&&(t.type=`TextualBody`)),t}function tt(e){return!!e&&typeof e==`object`&&e.type===`Choice`}function nt(e){if(typeof e==`string`)return!0;if(!e||typeof e!=`object`)return!1;let t=e.type;return t===`TextualBody`||t===`Text`}function rt(e){let t=new Set,n=0;function r(n){return t.has(n)?!0:We.some(t=>!!e.get({id:n,type:t}))}function i(e,i,a){let o;do n+=1,o=`${ct(e)}/external-annotation-pages/${st(i)}/${st(a)}-${n}`;while(r(o));return t.add(o),o}function a(e,n,a,o){return e&&!r(e)?(t.add(e),e):i(a,n,o)}return{create:i,preserveOrCreate:a}}function it(e){let t=e.indexOf(`#`);return{sourceId:t>=0?e.slice(0,t):e,fragment:t>=0?e.slice(t):``}}function W(e,t){return`${t}${it(e).fragment}`}function G(e){if(typeof e==`string`)return e;if(!(!e||typeof e!=`object`))return typeof e.id==`string`?e.id:typeof e[`@id`]==`string`?e[`@id`]:void 0}function K(e){return e?typeof e==`string`?[e]:Array.isArray(e)?e.filter(e=>typeof e==`string`):typeof e==`object`?Object.values(e).flatMap(K):[]:[]}function at(e){return K(e)[0]||``}function ot(e){return Array.from(new Set(e.filter(Boolean)))}function q(e){return Array.isArray(e)?e:e==null?[]:[e]}function J(e){return JSON.parse(JSON.stringify(e))}function st(e){return e.toLowerCase().replace(/[^a-z0-9]+/g,`-`).replace(/^-+|-+$/g,``).slice(0,80)||`item`}function ct(e){return e.endsWith(`/`)?e.slice(0,-1):e}function lt(e){return Object.fromEntries(Object.entries(e).filter(([,e])=>Object.keys(e).length))}const Y=`@manifest-editor/annotations:bulk-import-results`;function ut(e,t){window.dispatchEvent(new CustomEvent(Y,{detail:{actionId:e,result:t}}))}function dt(e){return C(ft,{actionId:e})}function ft({actionId:e}){let[t,n]=E(null);return T(()=>{let t=t=>{let r=t.detail;r?.actionId===e&&r.result&&n(r.result)};return window.addEventListener(Y,t),()=>window.removeEventListener(Y,t)},[e]),t?C(se,{title:`External annotation page import results`,onClose:()=>n(null),className:`max-w-3xl`,children:w(`div`,{className:`flex min-h-0 flex-col gap-4 p-4 text-sm text-zinc-700`,children:[w(`div`,{className:`grid grid-cols-4 gap-2`,children:[C(X,{label:`External pages`,value:t.totalExternalPages}),C(X,{label:`Inlined pages`,value:t.pagesInlined}),C(X,{label:`Canvases`,value:t.canvasesUpdated}),C(X,{label:`Annotations`,value:t.annotationsWritten})]}),t.warnings.length?C(`div`,{className:`rounded border border-amber-200 bg-amber-50 p-3 text-amber-900`,children:t.warnings.map(e=>C(`div`,{children:e},e))}):null,t.skippedPages.length?w(`div`,{className:`rounded border border-zinc-200`,children:[C(`div`,{className:`border-b border-zinc-200 bg-zinc-50 px-3 py-2 font-medium`,children:`Skipped external pages`}),C(`div`,{className:`max-h-64 overflow-auto`,children:t.skippedPages.map(e=>w(`div`,{className:`grid gap-1 border-b border-zinc-100 px-3 py-2 last:border-0`,children:[C(`div`,{className:`truncate font-medium text-zinc-900`,children:e.pageId}),C(`div`,{className:`truncate text-zinc-500`,children:e.canvasLabel}),C(`div`,{className:`text-zinc-500`,children:e.reason})]},e.key))})]}):null]})}):null}function X({label:e,value:t}){return w(`div`,{className:`rounded border border-zinc-200 bg-zinc-50 p-3`,children:[C(`div`,{className:`text-xl font-semibold text-zinc-900`,children:t}),C(`div`,{className:`text-xs uppercase tracking-wide text-zinc-500`,children:e})]})}const Z=new Map;function pt(e={}){let t=e.fetchPage||mt,n=e.requestConfig||ht;return{id:A,label:`Bulk Annotation Page Importer`,summary:`Load external Canvas annotation pages and make them editable inline`,section:`Annotations`,order:10,resourceTypes:[`Manifest`],resumable:!1,render:e=>w(S,{children:[ze(e.definition.id),dt(e.definition.id)]}),onResults:e=>ut(e.definition.id,e.instance?.result),supports:e=>L(e.vault,Q(e)).length>0,prepare:async e=>{let t=L(e.vault,Q(e));if(!t.length)return!1;let r=await n(e,t,N());if(r===!1)return!1;let i=gt(e,t,r);return i.length?(Z.set(e.instanceKey,{references:i,options:r}),!0):!1},run:async e=>{let n=Z.get(e.instanceKey),r=n?.options||N(),i=n?.references||gt(e,L(e.vault,Q(e)),r);try{if(e.setActionLabel(`Importing external annotation pages`),e.setActionProgress({current:0,total:Math.max(i.length,1),label:`Loading external annotation pages`}),!i.length)return e.setActionStatus(`running`,`No external annotation pages found`),yt();let n=[];for(let[r,a]of i.entries()){bt(e.signal),e.setActionStatus(`running`,`Loading ${r+1}/${i.length}`),e.appendActionLog(`Loading external annotation page`,`info`,{canvasId:a.canvasId,pageId:a.pageId});try{let r=await t(a.pageId,a,e);n.push({reference:a,json:r})}catch(t){let r=xt(t);n.push({reference:a,error:r}),e.appendActionLog(`Failed to load external annotation page`,`warn`,{canvasId:a.canvasId,pageId:a.pageId,reason:r})}e.setActionProgress({current:r+1,total:i.length,label:`Loading external annotation pages`})}let a=R({loadedPages:n,motivationFilter:r.motivationMode===`selected`?r.motivations:void 0});if(a.errors.length)throw Error(a.errors[0]||`External annotation page import failed.`);e.setActionStatus(`running`,`Writing inline annotation pages`),e.setActionProgress({current:0,total:Math.max(a.totalAnnotations,a.pages.length,1),label:`Writing inline annotations`});let o=Ge(e.vault,a);return e.appendActionLog(`External annotation page import complete`,`info`,{pages:o.pagesInlined,annotations:o.annotationsWritten,skipped:o.skippedPages.length}),e.setActionStatus(`running`,`Imported ${o.pagesInlined}/${o.totalExternalPages} external pages`),e.setActionProgress({current:Math.max(o.annotationsWritten,o.pagesInlined),total:Math.max(o.annotationsWritten,o.pagesInlined,1),label:`Import complete`}),o}finally{Z.delete(e.instanceKey)}}}}async function mt(e,t,n){let r=await fetch(e,{signal:n.signal,headers:{Accept:`application/ld+json, application/json;q=0.9, */*;q=0.1`}});if(!r.ok)throw Error(`Unable to fetch ${e} (${r.status}).`);return r.json()}async function ht(e,t,n){return Re({actionId:e.definition.id,instanceKey:e.instanceKey,totalExternalPages:t.length,tags:_t(e,t),defaults:n,signal:e.signal})}function Q(e){let t=e.vault.get(e.target);return t?.items?(e.vault.get(t.items)||[]).filter(Boolean):[]}function gt(e,t,n){if(n.scope!==`tag`||!n.tagKey)return t;let r=vt(n.tagKey);return r?t.filter(t=>e.tags.hasTag({id:t.canvasId,type:`Canvas`},r.type,r.id)):[]}function _t(e,t){let n=new Map,r=new Map;n.set($(y),{...y,key:$(y),canvasCount:0,externalPageCount:0});for(let e of t)r.set(e.canvasId,(r.get(e.canvasId)||0)+1);for(let[t,i]of r)for(let r of e.tags.getTags({id:t,type:`Canvas`})){let e=$(r),t=n.get(e);t?(t.canvasCount+=1,t.externalPageCount+=i):n.set(e,{...r,key:e,canvasCount:1,externalPageCount:i})}return Array.from(n.values()).sort((e,t)=>e.type===y.type&&e.id===y.id?-1:t.type===y.type&&t.id===y.id?1:e.label.localeCompare(t.label)||e.type.localeCompare(t.type)||e.id.localeCompare(t.id))}function $(e){return`${e.type}:${e.id}`}function vt(e){let t=e.indexOf(`:`);return t===-1?null:{type:e.slice(0,t),id:e.slice(t+1)}}function yt(){return{totalExternalPages:0,pagesInlined:0,canvasesUpdated:0,annotationsWritten:0,skippedPages:[],warnings:[]}}function bt(e){if(e.aborted)throw new DOMException(`Aborted`,`AbortError`)}function xt(e){return e instanceof Error?e.message:String(e||`Unknown error`)}const St={id:`@manifest-editor/annotations-routing`,label:`Annotation routing`,render:()=>C(Ct,{})};function Ct(){let e=g(),t=s(`Canvas`),n=_e(),{leftPanel:r,rightPanel:i}=x(),{edit:a,open:o,rightPanel:c}=b(),l=ye(null),[u,d]=E(!1);return T(()=>{let e=t?.resource?.source?.id;e&&(l.current=e)},[t?.resource?.source?.id]),T(()=>{if(r.current===`@manifest-editor/canvas-annotation-listing`){let t=l.current||e?.items?.[0]?.id;if(t&&(o({id:`current-canvas`}),a({id:t,type:`Canvas`})),n===`focused`)return;i.open&&(c.close(),d(!0));return}u&&!i.open&&r.current!==`@manifest-editor/ranges-listing`&&(c.open(),d(!1))},[r.current,n]),null}var wt={id:Te,label:`Annotations`,description:`Create, view, and inline external supplemental canvas annotation pages.`,author:`Digirati`,official:!0,defaultEnabled:!0,tags:[`annotations`,`iiif`,`external-pages`],supports:{apps:[`manifest-editor`],projectTypes:[`Manifest`]}};const Tt=[Ne],Et=[Fe],Dt=[St],Ot=[pt()];export{O as ANNOTATIONS_LEFT_PANEL_ID,Te as ANNOTATIONS_PLUGIN_ID,A as BULK_ANNOTATION_IMPORT_ACTION_ID,k as CANVAS_ANNOTATIONS_PANEL_ID,Et as annotations,Dt as background,Ot as backgroundActions,pt as createBulkAnnotationImportBackgroundAction,R as createExternalAnnotationPageInlinePlan,wt as default,L as findExternalAnnotationPageReferences,Tt as leftPanels,z as rewriteAnnotationTarget,Ge as writeExternalAnnotationPageInlinePlan};
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["annotationsPanel: LayoutPanel","canvasAnnotations: AnnotationPanel","useAtlasStore","references: ExternalAnnotationPageReference[]","pages: InlineAnnotationPageImport[]","skippedPages: SkippedExternalAnnotationPage[]","warnings: string[]","annotations","entities: EntityBuckets","relationshipActions: any[]","entities: Record<string, any>","id: string","loadedPages: LoadedExternalAnnotationPage[]","annotationRoutingBackground: BackgroundPanel","leftPanels: LayoutPanel[]","annotations: AnnotationPanel[]","background: BackgroundPanel[]","backgroundActions: BackgroundActionDefinition[]"],"sources":["../src/constants.ts","../src/icons.tsx","../src/components/AnnotationsOcrActions.tsx","../src/components/AnnotationsCreateEmptyPage.tsx","../src/components/RenderPaintingAnnotationPreview.tsx","../src/components/AnnotationsSidebarListItem.tsx","../src/components/AnnotationsListingAnnotations.tsx","../src/annotation-panel.tsx","../src/canvas-annotations.tsx","../src/importer/config-modal.tsx","../src/importer/importer.ts","../src/importer/results.tsx","../src/importer/background-action.tsx","../src/routing-background.tsx","../src/index.ts"],"sourcesContent":["export const ANNOTATIONS_PLUGIN_ID = \"@manifest-editor/annotations\";\nexport const ANNOTATIONS_LEFT_PANEL_ID = \"@manifest-editor/canvas-annotation-listing\";\nexport const CANVAS_ANNOTATIONS_PANEL_ID = \"@manifest-editor/canvas-annotations\";\nexport const BULK_ANNOTATION_IMPORT_ACTION_ID = \"@manifest-editor/annotations/bulk-import-pages\";\n","import type { SVGProps } from \"react\";\n\nexport function AnnotationsIcon(props: SVGProps<SVGSVGElement>) {\n return (\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"1em\" height=\"1em\" viewBox=\"0 0 24 24\" {...props}>\n <path\n fill=\"currentColor\"\n d=\"M20 2H4c-1.1 0-1.99.9-1.99 2L2 22l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2m0 14H5.17l-.59.59l-.58.58V4h16zm-9.5-2H18v-2h-5.5zm3.86-5.87c.2-.2.2-.51 0-.71l-1.77-1.77c-.2-.2-.51-.2-.71 0L6 11.53V14h2.47z\"\n />\n </svg>\n );\n}\n\nexport function AddAnnotationIcon(props: SVGProps<SVGSVGElement>) {\n return (\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"1em\" height=\"1em\" viewBox=\"0 0 24 24\" {...props}>\n <path\n fill=\"currentColor\"\n d=\"M9 22a1 1 0 0 1-1-1v-3H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2h-6.1l-3.7 3.71c-.2.19-.45.29-.7.29zm1-6v3.08L13.08 16H20V4H4v12zm1-10h2v3h3v2h-3v3h-2v-3H8V9h3z\"\n />\n </svg>\n );\n}\n","import { ActionButton } from \"@manifest-editor/components\";\nimport {\n type AvailableBackgroundAction,\n runBackgroundAction,\n useAvailableBackgroundActions,\n useBackgroundActionsStoreApi,\n useCanvasProgressStatus,\n} from \"@manifest-editor/shell\";\nimport { useCanvas } from \"react-iiif-vault\";\n\nconst OCR_ACTIONS = [\n {\n id: \"@manifest-editor/ocr-docling/run-ocr\",\n label: \"Run Local OCR\",\n preparingLabel: \"Preparing OCR\",\n queuedLabel: \"OCR queued\",\n pendingLabel: \"OCR in progress\",\n },\n {\n id: \"@manifest-editor/remote-inference/action\",\n label: \"Run remote OCR\",\n preparingLabel: \"Preparing local OCR\",\n queuedLabel: \"OCR queued\",\n pendingLabel: \"OCR in progress\",\n },\n {\n id: \"@manifest-editor/remote-inference/structured-output\",\n label: \"Run structured output\",\n preparingLabel: \"Preparing structured output\",\n queuedLabel: \"Structured output queued\",\n pendingLabel: \"Structured output in progress\",\n },\n];\n\nexport function AnnotationsOcrActions() {\n const store = useBackgroundActionsStoreApi();\n const groups = useAvailableBackgroundActions();\n const canvas = useCanvas();\n const canvasProgressStatus = useCanvasProgressStatus(canvas);\n const actions = groups.flatMap((group) => group.actions);\n const availableActions = OCR_ACTIONS.map((ocrAction) => {\n const action = actions.find((item) => item.definition.id === ocrAction.id);\n return action ? { ...ocrAction, action } : null;\n }).filter(\n (\n item,\n ): item is {\n id: string;\n label: string;\n preparingLabel: string;\n queuedLabel: string;\n pendingLabel: string;\n action: AvailableBackgroundAction;\n } => !!item,\n );\n\n if (!availableActions.length) {\n return null;\n }\n\n const activeAction = availableActions.find(({ action }) => {\n const status = action.instance?.status;\n const isBusy = status === \"preparing\" || status === \"running\";\n if (!isBusy) return false;\n\n if (canvasProgressStatus === \"queued\" || canvasProgressStatus === \"pending\") {\n return true;\n }\n\n return action.context.currentCanvas?.id === canvas?.id;\n });\n\n return (\n <div className=\"mt-5 flex w-full flex-col items-stretch gap-2 border-t border-gray-200 pt-4\">\n <div className=\"text-center text-xs font-semibold uppercase tracking-wide text-gray-500\">\n OCR and structured output\n </div>\n {activeAction ? (\n <div className=\"rounded border border-amber-200 bg-amber-50 px-3 py-2 text-center text-sm text-amber-800\">\n <div className=\"font-medium\">\n {canvasProgressStatus === \"queued\"\n ? activeAction.queuedLabel\n : canvasProgressStatus === \"pending\"\n ? activeAction.pendingLabel\n : activeAction.preparingLabel}\n </div>\n <div className=\"mt-1 text-xs text-amber-700\">\n {activeAction.action.instance?.statusText || activeAction.label}\n </div>\n </div>\n ) : null}\n {activeAction\n ? null\n : availableActions.map(({ id, label, action }) => {\n const busy = action.instance?.status === \"preparing\" || action.instance?.status === \"running\";\n return (\n <ActionButton\n key={id}\n large\n isDisabled={busy}\n onPress={() => {\n if (busy) return;\n void runBackgroundAction({\n store,\n context: action.context,\n prepareData: { scope: \"selected\" },\n });\n }}\n >\n {label}\n </ActionButton>\n );\n })}\n </div>\n );\n}\n","import {\n ActionButton,\n AddIcon,\n Sidebar,\n SidebarContent,\n SidebarHeader,\n} from \"@manifest-editor/components\";\nimport { useInStack } from \"@manifest-editor/editors\";\nimport { useInlineCreator } from \"@manifest-editor/shell\";\nimport { useCanvas } from \"react-iiif-vault\";\nimport { AddAnnotationIcon } from \"../icons\";\nimport { AnnotationsOcrActions } from \"./AnnotationsOcrActions\";\n\nexport function AnnotationsCreateEmptyPage() {\n const canvasRef = useInStack(\"Canvas\");\n const canvasId = canvasRef?.resource.source?.id;\n const canvas = useCanvas({ id: canvasId });\n const creator = useInlineCreator();\n\n const createEmptyAnnotationPage = () => {\n if (!canvas) return;\n creator.create(\n \"@manifest-editor/empty-annotation-page\",\n {\n label: { en: [\"Inline annotations\"] },\n },\n {\n target: {\n id: canvas.id,\n type: \"Canvas\",\n },\n targetType: \"AnnotationPage\",\n parent: {\n property: \"annotations\",\n resource: {\n id: canvas.id,\n type: \"Canvas\",\n },\n },\n },\n );\n };\n\n return (\n <Sidebar>\n <SidebarHeader\n title=\"Annotations\"\n actions={[\n {\n icon: <AddAnnotationIcon className=\"text-2xl\" />,\n title: \"Add annotation\",\n disabled: true,\n onClick: () => void 0,\n },\n ]}\n />\n <SidebarContent>\n <div className=\"flex flex-col items-center justify-center p-4\">\n <div className=\"p-4 opacity-50 text-center\">\n This canvas does not yet have any inline annotations. To add inline\n annotations, an AnnotationPage is created which will be linked to\n this canvas, and can then used to add your annotations. Simply use\n the link below to start adding your annotations\n </div>\n\n <ActionButton\n large\n primary\n onPress={() => createEmptyAnnotationPage()}\n >\n <AddIcon className=\"text-xl\" /> Create empty page\n </ActionButton>\n\n <AnnotationsOcrActions />\n </div>\n </SidebarContent>\n </Sidebar>\n );\n}\n","import { AnnotationPreview, CanvasTargetContext } from \"@manifest-editor/editors\";\nimport { useLayoutActions } from \"@manifest-editor/shell\";\nimport { LocaleString, useAnnotation, useAtlasStore, useCanvas } from \"react-iiif-vault\";\nimport { useStore } from \"zustand\";\n\nexport function RenderPaintingAnnotationPreview() {\n const annotation = useAnnotation();\n const canvas = useCanvas();\n const store = useAtlasStore();\n const { edit } = useLayoutActions();\n const viewport = useStore(store, (state) => (canvas?.id ? state.canvasViewports[canvas.id] : null));\n\n if (!annotation || !canvas || !viewport) return null;\n\n return (\n <div className=\"p-2\">\n <LocaleString\n as=\"div\"\n defaultText={(<span className=\"opacity-50\">Untitled</span>) as any}\n className=\"whitespace-nowrap overflow-ellipsis w-full overflow-x-hidden\"\n >\n {annotation?.label}\n </LocaleString>\n <LocaleString className=\"text-gray-500 text-sm bg-white line-clamp-2 mb-4\" as=\"div\">\n {annotation?.summary}\n </LocaleString>\n <CanvasTargetContext>\n <AnnotationPreview viewport={viewport} onClick={() => edit(annotation, undefined, { forceOpen: true })} />\n </CanvasTargetContext>\n </div>\n );\n}\n","import { ActionButton, CheckIcon, DeleteIcon, EditTextIcon, HTMLAnnotationBodyRender } from \"@manifest-editor/components\";\nimport { HTMLAnnotationEditor, useAnnotationEditor, useAnnotationInfo } from \"@manifest-editor/editors\";\nimport { useLayoutActions } from \"@manifest-editor/shell\";\nimport { useState } from \"react\";\nimport { AnnotationContext } from \"react-iiif-vault\";\nimport { RenderPaintingAnnotationPreview } from \"./RenderPaintingAnnotationPreview\";\n\nexport function AnnotationsSidebarListItem() {\n const { isPending, cancelRequest, busy, requestAnnotationFromTarget, deleteAnnotation } = useAnnotationEditor();\n const [annotation, { highlightProps, annotationTarget }] = useAnnotationInfo();\n const { edit } = useLayoutActions();\n const bodies = annotation?.body || [];\n const isBodyEmpty = !annotation || bodies.length === 0;\n const [isOpen, setIsOpen] = useState(false);\n\n return (\n <div {...highlightProps} className=\"border border-gray-300 hover:border-me-500 shadow-sm rounded bg-white relative\">\n <div className=\"relative\">\n {annotationTarget ? (\n <AnnotationContext annotation={annotationTarget}>\n <RenderPaintingAnnotationPreview />\n </AnnotationContext>\n ) : isBodyEmpty ? (\n <div className=\"flex items-center justify-center px-4 py-6 text-gray-400 text-sm\">This annotation has no body.</div>\n ) : isOpen ? (\n <HTMLAnnotationEditor className=\"border-none\" />\n ) : (\n <HTMLAnnotationBodyRender className=\"px-3 pt-3 line-clamp-3 prose-p:text-slate-600\" locale=\"en\" />\n )}\n </div>\n <div className=\"flex gap-2 p-2\">\n {annotationTarget ? (\n <ActionButton onPress={() => edit({ id: annotationTarget, type: \"Annotation\" }, undefined, { forceOpen: true })}>\n Edit painting annotation\n </ActionButton>\n ) : isOpen && isPending ? (\n <ActionButton\n primary\n onPress={() => {\n setIsOpen(false);\n cancelRequest();\n }}\n >\n <CheckIcon /> Finish editing\n </ActionButton>\n ) : (\n <ActionButton\n isDisabled={busy}\n onPress={() => {\n setIsOpen(true);\n requestAnnotationFromTarget().then(() => {\n setIsOpen(false);\n });\n }}\n >\n <EditTextIcon /> {isBodyEmpty ? \"Edit target\" : \"Edit\"}\n </ActionButton>\n )}\n <ActionButton className=\"gap-2 flex\" onPress={() => deleteAnnotation()}>\n <DeleteIcon /> Delete\n </ActionButton>\n </div>\n </div>\n );\n}\n","import {\n ActionButton,\n Sidebar,\n SidebarContent,\n SidebarHeader,\n TargetIcon,\n} from \"@manifest-editor/components\";\nimport { AnnotationCreationPopup } from \"@manifest-editor/editors\";\nimport {\n AnnotationContext,\n useAnnotationPage,\n useCanvas,\n useRenderingStrategy,\n useRequestAnnotation,\n} from \"react-iiif-vault\";\nimport { AddAnnotationIcon } from \"../icons\";\nimport { AnnotationsSidebarListItem } from \"./AnnotationsSidebarListItem\";\nimport { AnnotationsOcrActions } from \"./AnnotationsOcrActions\";\n\nexport function AnnotationsListingAnnotations() {\n const canvas = useCanvas();\n const page = useAnnotationPage();\n const { requestAnnotation, isActive, busy, cancelRequest } =\n useRequestAnnotation();\n const [strategy] = useRenderingStrategy();\n\n if (strategy.type !== \"images\") {\n return <div>Not supported</div>;\n }\n\n if (!page) {\n return null;\n }\n\n const createAnnotation = () =>\n requestAnnotation({\n type: \"box\",\n annotationPopup: (\n <AnnotationCreationPopup\n annotationPageId={page.id}\n canvasId={canvas!.id}\n />\n ),\n });\n\n return (\n <Sidebar>\n <SidebarHeader\n title=\"Annotations\"\n actions={[\n {\n icon: <AddAnnotationIcon className=\"text-2xl\" />,\n title: \"Add annotation\",\n disabled: isActive || busy,\n onClick: createAnnotation,\n },\n ]}\n />\n {isActive ? (\n <>\n <button\n aria-label=\"cancel add annotation\"\n className=\"m-2 rounded border border-gray-300 bg-white px-3 py-2 text-sm text-gray-700\"\n type=\"button\"\n onClick={() => cancelRequest()}\n >\n Exit edit mode\n </button>\n <div className=\"flex flex-col gap-5 text-center p-4 items-center justify-center\">\n <TargetIcon className=\"w-32 h-32 text-gray-300\" />\n <p className=\"text-gray-500\">Draw a box on the canvas</p>\n </div>\n </>\n ) : null}\n <SidebarContent className=\"w-full p-2 flex flex-col gap-2\">\n {page.items.map((annotation) => (\n <AnnotationContext key={annotation.id} annotation={annotation.id}>\n <AnnotationsSidebarListItem />\n </AnnotationContext>\n ))}\n\n {!isActive && page.items.length === 0 ? (\n <div className=\"flex flex-col items-center justify-center p-4\">\n <div className=\"p-4 opacity-50 text-center\">\n This canvas does not yet have any inline annotations.\n </div>\n\n <ActionButton\n large\n primary\n isDisabled={isActive}\n onPress={() => createAnnotation()}\n >\n <AddAnnotationIcon className=\"text-xl\" /> Add annotation\n </ActionButton>\n\n <AnnotationsOcrActions />\n </div>\n ) : null}\n </SidebarContent>\n </Sidebar>\n );\n}\n","import { useInStack } from \"@manifest-editor/editors\";\nimport type { LayoutPanel } from \"@manifest-editor/shell\";\nimport {\n AnnotationPageContext,\n CanvasContext,\n useCanvas,\n} from \"react-iiif-vault\";\nimport { ANNOTATIONS_LEFT_PANEL_ID } from \"./constants\";\nimport { AnnotationsCreateEmptyPage } from \"./components/AnnotationsCreateEmptyPage\";\nimport { AnnotationsListingAnnotations } from \"./components/AnnotationsListingAnnotations\";\nimport { AnnotationsIcon } from \"./icons\";\n\nexport const annotationsPanel: LayoutPanel = {\n id: ANNOTATIONS_LEFT_PANEL_ID,\n label: \"Annotations\",\n icon: <AnnotationsIcon />,\n focusedMode: {\n closeOnMainPanelClick: false,\n },\n render: () => <AnnotationsPanel />,\n};\n\nfunction AnnotationsPanel() {\n const canvasRef = useInStack(\"Canvas\");\n const canvasId = canvasRef?.resource.source?.id;\n const canvas = useCanvas({ id: canvasId });\n const firstPage = canvas?.annotations[0];\n\n if (!canvas) {\n return (\n <div className=\"flex flex-col gap-5 text-center p-4 items-center justify-center\">\n <AnnotationsIcon className=\"w-32 h-32 text-gray-300\" />\n <p className=\"text-gray-500\">\n Annotations are associated with Canvases in a IIIF Manifest. To view\n or add annotations, first create a Canvas and then select the\n Annotations link\n </p>\n </div>\n );\n }\n\n if (firstPage) {\n return (\n <AnnotationPageContext annotationPage={firstPage.id}>\n <CanvasContext canvas={canvas.id}>\n <AnnotationsListingAnnotations />\n </CanvasContext>\n </AnnotationPageContext>\n );\n }\n\n return (\n <CanvasContext canvas={canvas.id}>\n <AnnotationsCreateEmptyPage />\n </CanvasContext>\n );\n}\n","import { ViewerAnnotationPage } from \"@manifest-editor/editors\";\nimport { type AnnotationPanel, useAtlasStore, useLayoutState } from \"@manifest-editor/shell\";\nimport { AnnotationPageContext, useCanvas } from \"react-iiif-vault\";\nimport { useStore } from \"zustand\";\nimport { ANNOTATIONS_LEFT_PANEL_ID, CANVAS_ANNOTATIONS_PANEL_ID } from \"./constants\";\n\nexport const canvasAnnotations: AnnotationPanel = {\n id: CANVAS_ANNOTATIONS_PANEL_ID,\n label: \"Canvas annotations\",\n render: () => <CanvasAnnotations />,\n};\n\nfunction CanvasAnnotations() {\n const canvas = useCanvas();\n const store = useAtlasStore();\n const toolEnabled = useStore(store, (state) => state.tool.enabled);\n const { leftPanel } = useLayoutState();\n const isLeftPanel = leftPanel.current === ANNOTATIONS_LEFT_PANEL_ID;\n const firstAnnotationPage = canvas?.annotations[0];\n\n if (!canvas || toolEnabled || !firstAnnotationPage || !isLeftPanel) {\n return null;\n }\n\n return (\n <AnnotationPageContext annotationPage={firstAnnotationPage.id}>\n <ViewerAnnotationPage />\n </AnnotationPageContext>\n );\n}\n","import { Modal } from \"@manifest-editor/components\";\nimport { useEffect, useMemo, useState } from \"react\";\n\nexport const BULK_ANNOTATION_IMPORT_CONFIG_EVENT =\n \"@manifest-editor/annotations:bulk-import-config\";\n\nexport const BULK_ANNOTATION_IMPORT_MOTIVATIONS = [\n \"commenting\",\n \"supplementing\",\n \"tagging\",\n \"describing\",\n \"linking\",\n \"painting\",\n \"highlighting\",\n \"classifying\",\n \"identifying\",\n \"replying\",\n] as const;\n\nexport type BulkAnnotationImportScope = \"all\" | \"tag\";\nexport type BulkAnnotationImportMotivationMode = \"all\" | \"selected\";\n\nexport type BulkAnnotationImportRunOptions = {\n scope: BulkAnnotationImportScope;\n tagKey?: string;\n motivationMode: BulkAnnotationImportMotivationMode;\n motivations: string[];\n};\n\nexport type BulkAnnotationImportTagOption = {\n key: string;\n label: string;\n canvasCount: number;\n externalPageCount: number;\n};\n\nexport type BulkAnnotationImportConfigRequest = {\n actionId: string;\n instanceKey: string;\n totalExternalPages: number;\n tags: BulkAnnotationImportTagOption[];\n defaults: BulkAnnotationImportRunOptions;\n signal?: AbortSignal;\n resolve: (options: BulkAnnotationImportRunOptions | false) => void;\n};\n\nexport function requestBulkAnnotationImportConfig(\n request: Omit<BulkAnnotationImportConfigRequest, \"resolve\">,\n): Promise<BulkAnnotationImportRunOptions | false> {\n return new Promise((resolve) => {\n if (request.signal?.aborted) {\n resolve(false);\n return;\n }\n\n let settled = false;\n const settle = (options: BulkAnnotationImportRunOptions | false) => {\n if (settled) {\n return;\n }\n\n settled = true;\n request.signal?.removeEventListener(\"abort\", handleAbort);\n resolve(options);\n };\n const handleAbort = () => settle(false);\n\n request.signal?.addEventListener(\"abort\", handleAbort, { once: true });\n window.dispatchEvent(\n new CustomEvent<BulkAnnotationImportConfigRequest>(\n BULK_ANNOTATION_IMPORT_CONFIG_EVENT,\n {\n detail: { ...request, resolve: settle },\n },\n ),\n );\n });\n}\n\nexport function renderBulkAnnotationImportConfigModal(actionId: string) {\n return <BulkAnnotationImportConfigModal actionId={actionId} />;\n}\n\nexport function getDefaultRunOptions(): BulkAnnotationImportRunOptions {\n return {\n scope: \"all\",\n motivationMode: \"all\",\n motivations: [],\n };\n}\n\nfunction BulkAnnotationImportConfigModal({ actionId }: { actionId: string }) {\n const [request, setRequest] =\n useState<BulkAnnotationImportConfigRequest | null>(null);\n const [options, setOptions] = useState<BulkAnnotationImportRunOptions>(\n getDefaultRunOptions(),\n );\n const [customMotivations, setCustomMotivations] = useState(\"\");\n\n useEffect(() => {\n const listener = (event: Event) => {\n const detail = (event as CustomEvent<BulkAnnotationImportConfigRequest>)\n .detail;\n if (detail?.actionId === actionId) {\n setRequest(detail);\n setOptions(normaliseDefaults(detail.defaults, detail.tags));\n setCustomMotivations(\"\");\n }\n };\n\n window.addEventListener(BULK_ANNOTATION_IMPORT_CONFIG_EVENT, listener);\n return () =>\n window.removeEventListener(BULK_ANNOTATION_IMPORT_CONFIG_EVENT, listener);\n }, [actionId]);\n\n useEffect(() => {\n if (!request?.signal) {\n return;\n }\n\n if (request.signal.aborted) {\n setRequest(null);\n return;\n }\n\n const handleAbort = () => setRequest(null);\n request.signal.addEventListener(\"abort\", handleAbort, { once: true });\n return () => request.signal?.removeEventListener(\"abort\", handleAbort);\n }, [request]);\n\n const selectedTag = useMemo(\n () => request?.tags.find((tag) => tag.key === options.tagKey),\n [request?.tags, options.tagKey],\n );\n const selectedExternalPages =\n options.scope === \"tag\"\n ? selectedTag?.externalPageCount || 0\n : request?.totalExternalPages || 0;\n const selectedMotivations = useMemo(\n () => getSelectedMotivations(options, customMotivations),\n [customMotivations, options],\n );\n const motivationSelectionInvalid =\n options.motivationMode === \"selected\" && selectedMotivations.length === 0;\n\n if (!request) {\n return null;\n }\n\n const close = (value: BulkAnnotationImportRunOptions | false) => {\n request.resolve(value);\n setRequest(null);\n };\n\n const tagSelectionDisabled = !request.tags.length;\n\n return (\n <Modal\n title=\"Import External Annotation Pages\"\n onClose={() => close(false)}\n className=\"max-w-2xl\"\n actions={\n <div className=\"flex gap-2\">\n <button\n type=\"button\"\n className=\"rounded border border-zinc-300 bg-white px-3 py-2 text-sm text-zinc-700\"\n onClick={() => close(false)}\n >\n Cancel\n </button>\n <button\n type=\"button\"\n className=\"rounded border border-me-primary-500 bg-me-primary-500 px-3 py-2 text-sm text-white disabled:cursor-not-allowed disabled:opacity-50\"\n disabled={selectedExternalPages === 0 || motivationSelectionInvalid}\n onClick={() =>\n close({\n ...options,\n motivations:\n options.motivationMode === \"selected\"\n ? selectedMotivations\n : [],\n })\n }\n >\n Import pages\n </button>\n </div>\n }\n >\n <div className=\"flex min-h-0 flex-col gap-4 p-4 text-sm text-zinc-700\">\n <fieldset className=\"grid gap-2\">\n <legend className=\"font-medium text-zinc-900\">Canvases</legend>\n <label className=\"flex items-center gap-2\">\n <input\n type=\"radio\"\n checked={options.scope === \"all\"}\n onChange={() =>\n setOptions((current) => ({ ...current, scope: \"all\" }))\n }\n />\n <span>\n All canvases with external annotation pages (\n {request.totalExternalPages})\n </span>\n </label>\n <label className=\"flex items-center gap-2\">\n <input\n type=\"radio\"\n checked={options.scope === \"tag\"}\n disabled={tagSelectionDisabled}\n onChange={() =>\n setOptions((current) => ({\n ...current,\n scope: \"tag\",\n tagKey: current.tagKey || request.tags[0]?.key,\n }))\n }\n />\n <span>Only canvases with tag</span>\n </label>\n <select\n className=\"rounded border border-zinc-300 bg-white p-2 disabled:bg-zinc-100\"\n disabled={options.scope !== \"tag\" || tagSelectionDisabled}\n value={options.tagKey || \"\"}\n onChange={(event) =>\n setOptions((current) => ({\n ...current,\n tagKey: event.target.value,\n }))\n }\n >\n {request.tags.map((tag) => (\n <option key={tag.key} value={tag.key}>\n {tag.label} ({tag.externalPageCount})\n </option>\n ))}\n </select>\n </fieldset>\n\n <fieldset className=\"grid gap-2\">\n <legend className=\"font-medium text-zinc-900\">Motivations</legend>\n <label className=\"flex items-center gap-2\">\n <input\n type=\"radio\"\n checked={options.motivationMode === \"all\"}\n onChange={() =>\n setOptions((current) => ({ ...current, motivationMode: \"all\" }))\n }\n />\n <span>All motivations</span>\n </label>\n <label className=\"flex items-center gap-2\">\n <input\n type=\"radio\"\n checked={options.motivationMode === \"selected\"}\n onChange={() =>\n setOptions((current) => ({\n ...current,\n motivationMode: \"selected\",\n motivations: current.motivations.length\n ? current.motivations\n : [\"commenting\"],\n }))\n }\n />\n <span>Only selected motivations</span>\n </label>\n <div className=\"grid grid-cols-2 gap-2 rounded border border-zinc-200 p-3\">\n {BULK_ANNOTATION_IMPORT_MOTIVATIONS.map((motivation) => (\n <label key={motivation} className=\"flex items-center gap-2\">\n <input\n type=\"checkbox\"\n disabled={options.motivationMode !== \"selected\"}\n checked={options.motivations.includes(motivation)}\n onChange={(event) =>\n setOptions((current) => ({\n ...current,\n motivationMode: \"selected\",\n motivations: event.target.checked\n ? uniqueStrings([...current.motivations, motivation])\n : current.motivations.filter(\n (item) => item !== motivation,\n ),\n }))\n }\n />\n <span>{motivation}</span>\n </label>\n ))}\n </div>\n <label className=\"grid gap-1\">\n <span className=\"font-medium text-zinc-900\">\n Additional motivations\n </span>\n <input\n type=\"text\"\n className=\"rounded border border-zinc-300 p-2\"\n disabled={options.motivationMode !== \"selected\"}\n value={customMotivations}\n placeholder=\"transcribing, reviewing\"\n onChange={(event) => setCustomMotivations(event.target.value)}\n />\n </label>\n </fieldset>\n\n <div className=\"rounded border border-zinc-200 bg-white p-3 text-zinc-600\">\n {selectedExternalPages} external annotation page\n {selectedExternalPages === 1 ? \"\" : \"s\"} selected.\n {options.motivationMode === \"selected\" ? (\n <>\n {\" \"}\n {selectedMotivations.length} motivation\n {selectedMotivations.length === 1 ? \"\" : \"s\"} selected.\n </>\n ) : null}\n </div>\n </div>\n </Modal>\n );\n}\n\nfunction normaliseDefaults(\n defaults: BulkAnnotationImportRunOptions,\n tags: BulkAnnotationImportTagOption[],\n): BulkAnnotationImportRunOptions {\n const hasSelectedTag = defaults.tagKey\n ? tags.some((tag) => tag.key === defaults.tagKey)\n : false;\n\n return {\n scope: defaults.scope === \"tag\" && tags.length ? \"tag\" : \"all\",\n tagKey: hasSelectedTag ? defaults.tagKey : tags[0]?.key,\n motivationMode: defaults.motivationMode === \"selected\" ? \"selected\" : \"all\",\n motivations: uniqueStrings(defaults.motivations || []),\n };\n}\n\nfunction getSelectedMotivations(\n options: BulkAnnotationImportRunOptions,\n customMotivations: string,\n) {\n if (options.motivationMode !== \"selected\") {\n return [];\n }\n\n return uniqueStrings([\n ...options.motivations,\n ...parseMotivationText(customMotivations),\n ]);\n}\n\nfunction parseMotivationText(value: string) {\n return value\n .split(/[,\\n]/)\n .map((item) => item.trim())\n .filter(Boolean);\n}\n\nfunction uniqueStrings(values: string[]) {\n return Array.from(new Set(values.map((item) => item.trim()).filter(Boolean)));\n}\n","import {\n addReference,\n batchActions,\n importEntities,\n modifyEntityField,\n} from \"@iiif/helpers/vault/actions\";\nimport { convertPresentation2 } from \"@iiif/parser/presentation-2\";\n\nconst IS_EXTERNAL = \"iiif-parser:isExternal\";\nconst HAS_PART = \"iiif-parser:hasPart\";\nconst RESOURCE_TYPES = [\n \"Annotation\",\n \"AnnotationPage\",\n \"ContentResource\",\n \"Canvas\",\n \"Manifest\",\n \"Range\",\n];\n\nexport type ExternalAnnotationPageReference = {\n key: string;\n canvasId: string;\n canvasLabel: string;\n pageId: string;\n annotationPageIndex: number;\n existingPage?: any;\n};\n\nexport type LoadedExternalAnnotationPage = {\n reference: ExternalAnnotationPageReference;\n json?: unknown;\n error?: string;\n};\n\nexport type SkippedExternalAnnotationPage = {\n key: string;\n canvasId: string;\n canvasLabel: string;\n pageId: string;\n reason: string;\n};\n\nexport type InlineAnnotationPageImport = {\n reference: ExternalAnnotationPageReference;\n page: any;\n annotations: any[];\n skippedAnnotations: number;\n skippedByMotivation: number;\n};\n\nexport type ExternalAnnotationPageInlinePlan = {\n totalExternalPages: number;\n totalAnnotations: number;\n pages: InlineAnnotationPageImport[];\n skippedPages: SkippedExternalAnnotationPage[];\n warnings: string[];\n errors: string[];\n};\n\nexport type ExternalAnnotationPageInlineResult = {\n totalExternalPages: number;\n pagesInlined: number;\n canvasesUpdated: number;\n annotationsWritten: number;\n skippedPages: SkippedExternalAnnotationPage[];\n warnings: string[];\n};\n\ntype EntityBuckets = {\n AnnotationPage: Record<string, any>;\n Annotation: Record<string, any>;\n ContentResource: Record<string, any>;\n};\n\nexport function findExternalAnnotationPageReferences(\n vault: any,\n canvases: any[],\n): ExternalAnnotationPageReference[] {\n const references: ExternalAnnotationPageReference[] = [];\n\n for (const canvas of canvases) {\n if (!canvas?.id || !Array.isArray(canvas.annotations)) {\n continue;\n }\n\n canvas.annotations.forEach((annotationPageRef: any, index: number) => {\n const pageId = getResourceId(annotationPageRef);\n if (!pageId) {\n return;\n }\n\n const existingPage =\n vault.get({ id: pageId, type: \"AnnotationPage\" }) ||\n vault.get(annotationPageRef) ||\n annotationPageRef;\n\n if (!isExternalAnnotationPage(existingPage)) {\n return;\n }\n\n references.push({\n key: `${canvas.id}:annotations:${index}:${pageId}`,\n canvasId: canvas.id,\n canvasLabel: getLabelText(canvas.label) || canvas.id,\n pageId,\n annotationPageIndex: index,\n existingPage,\n });\n });\n }\n\n return references;\n}\n\nexport function createExternalAnnotationPageInlinePlan(options: {\n loadedPages: LoadedExternalAnnotationPage[];\n motivationFilter?: string[];\n}): ExternalAnnotationPageInlinePlan {\n const pages: InlineAnnotationPageImport[] = [];\n const skippedPages: SkippedExternalAnnotationPage[] = [];\n const warnings: string[] = [];\n const seenPageIds = new Set<string>();\n const motivationFilter = createMotivationFilter(options.motivationFilter);\n let totalAnnotations = 0;\n\n for (const loaded of options.loadedPages) {\n const { reference } = loaded;\n\n if (seenPageIds.has(reference.pageId)) {\n skippedPages.push(\n toSkippedPage(\n reference,\n \"External annotation page is referenced more than once.\",\n ),\n );\n continue;\n }\n seenPageIds.add(reference.pageId);\n\n if (loaded.error) {\n skippedPages.push(toSkippedPage(reference, loaded.error));\n continue;\n }\n\n const pageResult = normaliseFetchedAnnotationPage(loaded.json, reference);\n if (pageResult.warning) {\n warnings.push(pageResult.warning);\n }\n if (!pageResult.page) {\n skippedPages.push(toSkippedPage(reference, pageResult.error));\n continue;\n }\n\n const page = pageResult.page;\n if (!Array.isArray(page.items)) {\n skippedPages.push(\n toSkippedPage(\n reference,\n \"Fetched annotation page does not contain an items array.\",\n ),\n );\n continue;\n }\n\n const annotationItems = page.items.filter(\n (item: any) => item?.type === \"Annotation\",\n );\n const annotations = annotationItems.filter((annotation: any) =>\n annotationMatchesMotivationFilter(annotation, motivationFilter),\n );\n const skippedAnnotations = page.items.length - annotationItems.length;\n const skippedByMotivation = annotationItems.length - annotations.length;\n\n if (skippedAnnotations) {\n warnings.push(\n `${reference.pageId}: skipped ${skippedAnnotations} non-Annotation item${skippedAnnotations === 1 ? \"\" : \"s\"}.`,\n );\n }\n if (skippedByMotivation) {\n warnings.push(\n `${reference.pageId}: skipped ${skippedByMotivation} annotation${skippedByMotivation === 1 ? \"\" : \"s\"} outside the selected motivation filter.`,\n );\n }\n\n if (!annotations.length) {\n skippedPages.push(\n toSkippedPage(\n reference,\n getEmptyPageReason(\n page.items.length,\n annotationItems.length,\n motivationFilter,\n ),\n ),\n );\n continue;\n }\n\n totalAnnotations += annotations.length;\n pages.push({\n reference,\n page,\n annotations,\n skippedAnnotations,\n skippedByMotivation,\n });\n }\n\n return {\n totalExternalPages: options.loadedPages.length,\n totalAnnotations,\n pages,\n skippedPages,\n warnings,\n errors: [],\n };\n}\n\nexport function writeExternalAnnotationPageInlinePlan(\n vault: any,\n plan: ExternalAnnotationPageInlinePlan,\n) {\n const entities: EntityBuckets = {\n AnnotationPage: {},\n Annotation: {},\n ContentResource: {},\n };\n const relationshipActions: any[] = [];\n const idFactory = createIdFactory(vault);\n const updatedCanvasIds = new Set<string>();\n let annotationsWritten = 0;\n\n for (const pageImport of plan.pages) {\n const { reference } = pageImport;\n const pageId = reference.pageId;\n const inlinePage = cloneJson(pageImport.page);\n\n inlinePage.id = pageId;\n inlinePage.type = \"AnnotationPage\";\n inlinePage.items = [];\n inlinePage[IS_EXTERNAL] = false;\n\n if (reference.existingPage?.[HAS_PART]) {\n inlinePage[HAS_PART] = cloneJson(reference.existingPage[HAS_PART]);\n }\n\n entities.AnnotationPage[pageId] = inlinePage;\n updatedCanvasIds.add(reference.canvasId);\n relationshipActions.push(\n modifyEntityField({\n id: pageId,\n type: \"AnnotationPage\",\n key: IS_EXTERNAL,\n value: false,\n }),\n );\n\n for (const sourceAnnotation of pageImport.annotations) {\n const annotation = cloneJson(sourceAnnotation);\n const annotationId = idFactory.preserveOrCreate(\n getResourceId(annotation),\n \"Annotation\",\n reference.canvasId,\n \"external-annotation\",\n );\n const bodyResult = normaliseAnnotationBodies(\n annotation.body,\n idFactory,\n reference.canvasId,\n annotationId,\n );\n\n annotation.id = annotationId;\n annotation.type = \"Annotation\";\n annotation.body = bodyResult.body;\n annotation.target = rewriteAnnotationTarget(\n annotation.target,\n reference.canvasId,\n );\n\n Object.assign(entities.ContentResource, bodyResult.entities);\n entities.Annotation[annotationId] = annotation;\n relationshipActions.push(\n addReference({\n id: pageId,\n type: \"AnnotationPage\",\n key: \"items\",\n reference: {\n id: annotationId,\n type: \"Annotation\",\n },\n }),\n );\n annotationsWritten += 1;\n }\n }\n\n const actions = [\n importEntities({\n entities: removeEmptyEntityBuckets(entities),\n }),\n ...relationshipActions,\n ];\n\n if (\n relationshipActions.length ||\n Object.values(entities).some((bucket) => Object.keys(bucket).length)\n ) {\n vault.dispatch(batchActions({ actions }));\n }\n\n return {\n totalExternalPages: plan.totalExternalPages,\n pagesInlined: plan.pages.length,\n canvasesUpdated: updatedCanvasIds.size,\n annotationsWritten,\n skippedPages: plan.skippedPages,\n warnings: plan.warnings,\n } satisfies ExternalAnnotationPageInlineResult;\n}\n\nexport function rewriteAnnotationTarget(\n target: unknown,\n canvasId: string,\n): unknown {\n if (Array.isArray(target)) {\n return target.map((item) => rewriteAnnotationTarget(item, canvasId));\n }\n\n if (typeof target === \"string\") {\n return withCanvasId(target, canvasId);\n }\n\n if (!target || typeof target !== \"object\") {\n return target;\n }\n\n const clone = cloneJson(target as any);\n\n if (typeof clone.source === \"string\") {\n clone.source = withCanvasId(clone.source, canvasId);\n return clone;\n }\n\n if (clone.source && typeof clone.source === \"object\") {\n clone.source = {\n ...clone.source,\n id: canvasId,\n type: clone.source.type || \"Canvas\",\n };\n return clone;\n }\n\n if (typeof clone.id === \"string\") {\n clone.id = withCanvasId(clone.id, canvasId);\n }\n\n return clone;\n}\n\nfunction isExternalAnnotationPage(page: any) {\n return !!page?.[IS_EXTERNAL];\n}\n\nfunction toSkippedPage(\n reference: ExternalAnnotationPageReference,\n reason: string,\n): SkippedExternalAnnotationPage {\n return {\n key: reference.key,\n canvasId: reference.canvasId,\n canvasLabel: reference.canvasLabel,\n pageId: reference.pageId,\n reason,\n };\n}\n\nfunction normaliseFetchedAnnotationPage(\n json: unknown,\n reference: ExternalAnnotationPageReference,\n): { page?: any; error: string; warning?: string } {\n if (!json || typeof json !== \"object\") {\n return { error: \"Fetched resource is not a JSON object.\" };\n }\n\n const resource = json as any;\n if (resource.type === \"AnnotationPage\") {\n return { page: resource, error: \"\" };\n }\n\n if (isPresentation2AnnotationList(resource)) {\n try {\n const upgraded = convertPresentation2(resource) as any;\n if (upgraded?.type === \"AnnotationPage\") {\n return {\n page: upgraded,\n error: \"\",\n warning: `${reference.pageId}: upgraded Presentation 2 sc:AnnotationList to AnnotationPage.`,\n };\n }\n\n return {\n error: `IIIF upgrade produced ${upgraded?.type || \"missing a type\"}, not AnnotationPage.`,\n };\n } catch (error) {\n return {\n error: `Unable to upgrade Presentation 2 sc:AnnotationList: ${error instanceof Error ? error.message : String(error)}`,\n };\n }\n }\n\n return {\n error: `Fetched resource is ${resource.type || resource[\"@type\"] || \"missing a type\"}, not AnnotationPage.`,\n };\n}\n\nfunction getEmptyPageReason(\n itemCount: number,\n annotationCount: number,\n motivationFilter: Set<string> | null,\n) {\n if (!itemCount) {\n return \"Fetched annotation page is empty.\";\n }\n\n if (!annotationCount) {\n return \"Fetched annotation page does not contain Annotation items.\";\n }\n\n if (motivationFilter?.size) {\n return `No annotations matched the selected motivation filter (${Array.from(motivationFilter).join(\", \")}).`;\n }\n\n return \"Fetched annotation page does not contain importable annotations.\";\n}\n\nfunction createMotivationFilter(values: string[] | undefined) {\n const normalised = dedupeStrings(\n (values || []).map(normaliseMotivation).filter(Boolean),\n );\n return normalised.length ? new Set(normalised) : null;\n}\n\nfunction annotationMatchesMotivationFilter(\n annotation: any,\n motivationFilter: Set<string> | null,\n) {\n if (!motivationFilter?.size) {\n return true;\n }\n\n return getAnnotationMotivations(annotation).some((motivation) =>\n motivationFilter.has(motivation),\n );\n}\n\nfunction getAnnotationMotivations(annotation: any) {\n return dedupeStrings(\n toArray(annotation?.motivation).map(normaliseMotivation).filter(Boolean),\n );\n}\n\nfunction normaliseMotivation(value: unknown) {\n if (typeof value !== \"string\") {\n return \"\";\n }\n\n const trimmed = value.trim().toLowerCase();\n const compact = trimmed.includes(\":\")\n ? trimmed.slice(trimmed.lastIndexOf(\":\") + 1)\n : trimmed;\n const slashIndex = compact.lastIndexOf(\"/\");\n const hashIndex = compact.lastIndexOf(\"#\");\n const separator = Math.max(slashIndex, hashIndex);\n return separator >= 0 ? compact.slice(separator + 1) : compact;\n}\n\nfunction isPresentation2AnnotationList(resource: any) {\n const type = resource?.[\"@type\"] || resource?.type;\n return type === \"sc:AnnotationList\" || type === \"AnnotationList\";\n}\n\nfunction normaliseAnnotationBodies(\n body: unknown,\n idFactory: ReturnType<typeof createIdFactory>,\n canvasId: string,\n annotationId: string,\n) {\n const bodyItems =\n typeof body === \"undefined\" || body === null ? [] : toArray(body);\n const entities: Record<string, any> = {};\n const normalised =\n bodyItems.length > 1 && bodyItems.every(isTextualBodyLike)\n ? [\n normaliseChoiceBody(\n {\n type: \"Choice\",\n items: bodyItems,\n },\n idFactory,\n canvasId,\n annotationId,\n \"body-choice\",\n entities,\n ),\n ]\n : bodyItems.map((item, index) =>\n normaliseBodyItem(\n item,\n idFactory,\n canvasId,\n annotationId,\n `body-${index + 1}`,\n entities,\n ),\n );\n\n return {\n body: normalised,\n entities,\n };\n}\n\nfunction normaliseBodyItem(\n item: unknown,\n idFactory: ReturnType<typeof createIdFactory>,\n canvasId: string,\n annotationId: string,\n seed: string,\n entities: Record<string, any>,\n) {\n if (isChoiceBody(item)) {\n return normaliseChoiceBody(\n item,\n idFactory,\n canvasId,\n annotationId,\n seed,\n entities,\n );\n }\n\n const bodyId = idFactory.preserveOrCreate(\n item && typeof item === \"object\" ? getResourceId(item) : undefined,\n \"ContentResource\",\n canvasId,\n `${annotationId}-${seed}`,\n );\n\n if (typeof item === \"string\") {\n entities[bodyId] = {\n id: bodyId,\n type: \"TextualBody\",\n format: \"text/plain\",\n value: item,\n };\n return { id: bodyId, type: \"ContentResource\" };\n }\n\n if (item && typeof item === \"object\") {\n const resource = normaliseImportedBodyResource(item);\n entities[bodyId] = {\n ...resource,\n id: bodyId,\n type: resource.type || \"ContentResource\",\n };\n return { id: bodyId, type: \"ContentResource\" };\n }\n\n entities[bodyId] = {\n id: bodyId,\n type: \"TextualBody\",\n format: \"text/plain\",\n value: String(item),\n };\n return { id: bodyId, type: \"ContentResource\" };\n}\n\nfunction normaliseChoiceBody(\n choice: any,\n idFactory: ReturnType<typeof createIdFactory>,\n canvasId: string,\n annotationId: string,\n seed: string,\n entities: Record<string, any>,\n) {\n const choiceId = idFactory.preserveOrCreate(\n getResourceId(choice),\n \"ContentResource\",\n canvasId,\n `${annotationId}-${seed}`,\n );\n const items = toArray(choice.items).map((item, index) =>\n normaliseBodyItem(\n item,\n idFactory,\n canvasId,\n annotationId,\n `${seed}-item-${index + 1}`,\n entities,\n ),\n );\n\n entities[choiceId] = {\n ...cloneJson(choice),\n id: choiceId,\n type: \"Choice\",\n items,\n };\n\n return { id: choiceId, type: \"ContentResource\" };\n}\n\nfunction normaliseImportedBodyResource(item: unknown) {\n const resource = cloneJson(item as any);\n\n if (\n typeof resource.chars === \"string\" &&\n typeof resource.value === \"undefined\"\n ) {\n resource.value = resource.chars;\n delete resource.chars;\n\n if (resource.type === \"Text\") {\n resource.type = \"TextualBody\";\n }\n }\n\n return resource;\n}\n\nfunction isChoiceBody(item: unknown) {\n return !!item && typeof item === \"object\" && (item as any).type === \"Choice\";\n}\n\nfunction isTextualBodyLike(item: unknown) {\n if (typeof item === \"string\") {\n return true;\n }\n\n if (!item || typeof item !== \"object\") {\n return false;\n }\n\n const type = (item as any).type;\n return type === \"TextualBody\" || type === \"Text\";\n}\n\nfunction createIdFactory(vault: any) {\n const used = new Set<string>();\n let counter = 0;\n\n function isInUse(id: string) {\n if (used.has(id)) {\n return true;\n }\n\n return RESOURCE_TYPES.some((type) => !!vault.get({ id, type }));\n }\n\n function create(canvasId: string, type: string, seed: string) {\n let id: string;\n do {\n counter += 1;\n id = `${trimTrailingSlash(canvasId)}/external-annotation-pages/${slugify(type)}/${slugify(seed)}-${counter}`;\n } while (isInUse(id));\n\n used.add(id);\n return id;\n }\n\n function preserveOrCreate(\n id: string | undefined,\n type: string,\n canvasId: string,\n seed: string,\n ) {\n if (id && !isInUse(id)) {\n used.add(id);\n return id;\n }\n\n return create(canvasId, type, seed);\n }\n\n return { create, preserveOrCreate };\n}\n\nfunction splitTargetId(value: string) {\n const hashIndex = value.indexOf(\"#\");\n return {\n sourceId: hashIndex >= 0 ? value.slice(0, hashIndex) : value,\n fragment: hashIndex >= 0 ? value.slice(hashIndex) : \"\",\n };\n}\n\nfunction withCanvasId(value: string, canvasId: string) {\n return `${canvasId}${splitTargetId(value).fragment}`;\n}\n\nfunction getResourceId(resource: unknown) {\n if (typeof resource === \"string\") return resource;\n if (!resource || typeof resource !== \"object\") return undefined;\n return typeof (resource as any).id === \"string\"\n ? (resource as any).id\n : typeof (resource as any)[\"@id\"] === \"string\"\n ? (resource as any)[\"@id\"]\n : undefined;\n}\n\nfunction getLabelTexts(label: unknown): string[] {\n if (!label) return [];\n if (typeof label === \"string\") return [label];\n if (Array.isArray(label))\n return label.filter((item): item is string => typeof item === \"string\");\n if (typeof label === \"object\") {\n return Object.values(label as Record<string, unknown>).flatMap(\n getLabelTexts,\n );\n }\n return [];\n}\n\nfunction getLabelText(label: unknown) {\n return getLabelTexts(label)[0] || \"\";\n}\n\nfunction dedupeStrings(values: string[]) {\n return Array.from(new Set(values.filter(Boolean)));\n}\n\nfunction toArray<T>(value: T | T[] | null | undefined): T[] {\n if (Array.isArray(value)) return value;\n if (typeof value === \"undefined\" || value === null) return [];\n return [value];\n}\n\nfunction cloneJson<T>(value: T): T {\n return JSON.parse(JSON.stringify(value));\n}\n\nfunction slugify(value: string) {\n return (\n value\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\")\n .slice(0, 80) || \"item\"\n );\n}\n\nfunction trimTrailingSlash(value: string) {\n return value.endsWith(\"/\") ? value.slice(0, -1) : value;\n}\n\nfunction removeEmptyEntityBuckets(entities: EntityBuckets) {\n return Object.fromEntries(\n Object.entries(entities).filter(([, value]) => Object.keys(value).length),\n );\n}\n","import { Modal } from \"@manifest-editor/components\";\nimport { useEffect, useState } from \"react\";\nimport type { ExternalAnnotationPageInlineResult } from \"./importer\";\n\nconst resultsEventName = \"@manifest-editor/annotations:bulk-import-results\";\n\ntype BulkAnnotationImportResultsEvent = {\n actionId: string;\n result?: ExternalAnnotationPageInlineResult;\n};\n\nexport function openBulkAnnotationImportResults(actionId: string, result: unknown) {\n window.dispatchEvent(\n new CustomEvent<BulkAnnotationImportResultsEvent>(resultsEventName, {\n detail: {\n actionId,\n result: result as ExternalAnnotationPageInlineResult | undefined,\n },\n }),\n );\n}\n\nexport function renderBulkAnnotationImportResults(actionId: string) {\n return <BulkAnnotationImportResultsModal actionId={actionId} />;\n}\n\nfunction BulkAnnotationImportResultsModal({ actionId }: { actionId: string }) {\n const [activeResult, setActiveResult] = useState<ExternalAnnotationPageInlineResult | null>(null);\n\n useEffect(() => {\n const listener = (event: Event) => {\n const detail = (event as CustomEvent<BulkAnnotationImportResultsEvent>).detail;\n if (detail?.actionId === actionId && detail.result) {\n setActiveResult(detail.result);\n }\n };\n\n window.addEventListener(resultsEventName, listener);\n return () => window.removeEventListener(resultsEventName, listener);\n }, [actionId]);\n\n if (!activeResult) {\n return null;\n }\n\n return (\n <Modal title=\"External annotation page import results\" onClose={() => setActiveResult(null)} className=\"max-w-3xl\">\n <div className=\"flex min-h-0 flex-col gap-4 p-4 text-sm text-zinc-700\">\n <div className=\"grid grid-cols-4 gap-2\">\n <ResultStat label=\"External pages\" value={activeResult.totalExternalPages} />\n <ResultStat label=\"Inlined pages\" value={activeResult.pagesInlined} />\n <ResultStat label=\"Canvases\" value={activeResult.canvasesUpdated} />\n <ResultStat label=\"Annotations\" value={activeResult.annotationsWritten} />\n </div>\n\n {activeResult.warnings.length ? (\n <div className=\"rounded border border-amber-200 bg-amber-50 p-3 text-amber-900\">\n {activeResult.warnings.map((warning) => (\n <div key={warning}>{warning}</div>\n ))}\n </div>\n ) : null}\n\n {activeResult.skippedPages.length ? (\n <div className=\"rounded border border-zinc-200\">\n <div className=\"border-b border-zinc-200 bg-zinc-50 px-3 py-2 font-medium\">Skipped external pages</div>\n <div className=\"max-h-64 overflow-auto\">\n {activeResult.skippedPages.map((item) => (\n <div key={item.key} className=\"grid gap-1 border-b border-zinc-100 px-3 py-2 last:border-0\">\n <div className=\"truncate font-medium text-zinc-900\">{item.pageId}</div>\n <div className=\"truncate text-zinc-500\">{item.canvasLabel}</div>\n <div className=\"text-zinc-500\">{item.reason}</div>\n </div>\n ))}\n </div>\n </div>\n ) : null}\n </div>\n </Modal>\n );\n}\n\nfunction ResultStat({ label, value }: { label: string; value: number }) {\n return (\n <div className=\"rounded border border-zinc-200 bg-zinc-50 p-3\">\n <div className=\"text-xl font-semibold text-zinc-900\">{value}</div>\n <div className=\"text-xs uppercase tracking-wide text-zinc-500\">{label}</div>\n </div>\n );\n}\n","import {\n FLAG_TAG,\n type BackgroundActionDefinition,\n type BackgroundActionRunContext,\n type ManifestEditorTag,\n} from \"@manifest-editor/shell\";\nimport { BULK_ANNOTATION_IMPORT_ACTION_ID } from \"../constants\";\nimport {\n getDefaultRunOptions,\n renderBulkAnnotationImportConfigModal,\n requestBulkAnnotationImportConfig,\n type BulkAnnotationImportRunOptions,\n type BulkAnnotationImportTagOption,\n} from \"./config-modal\";\nimport {\n createExternalAnnotationPageInlinePlan,\n findExternalAnnotationPageReferences,\n writeExternalAnnotationPageInlinePlan,\n type ExternalAnnotationPageInlineResult,\n type ExternalAnnotationPageReference,\n type LoadedExternalAnnotationPage,\n} from \"./importer\";\nimport {\n openBulkAnnotationImportResults,\n renderBulkAnnotationImportResults,\n} from \"./results\";\n\nconst runOptions = new Map<\n string,\n {\n references: ExternalAnnotationPageReference[];\n options: BulkAnnotationImportRunOptions;\n }\n>();\n\nexport type BulkAnnotationImportActionDependencies = {\n fetchPage?: (\n pageId: string,\n reference: ExternalAnnotationPageReference,\n ctx: BackgroundActionRunContext,\n ) => Promise<unknown>;\n requestConfig?: (\n ctx: BackgroundActionRunContext,\n references: ExternalAnnotationPageReference[],\n defaults: BulkAnnotationImportRunOptions,\n ) => Promise<BulkAnnotationImportRunOptions | false>;\n};\n\nexport function createBulkAnnotationImportBackgroundAction(\n dependencies: BulkAnnotationImportActionDependencies = {},\n): BackgroundActionDefinition {\n const fetchPage = dependencies.fetchPage || defaultFetchPage;\n const requestConfig = dependencies.requestConfig || defaultRequestConfig;\n\n return {\n id: BULK_ANNOTATION_IMPORT_ACTION_ID,\n label: \"Bulk Annotation Page Importer\",\n summary:\n \"Load external Canvas annotation pages and make them editable inline\",\n section: \"Annotations\",\n order: 10,\n resourceTypes: [\"Manifest\"],\n resumable: false,\n render: (ctx) => (\n <>\n {renderBulkAnnotationImportConfigModal(ctx.definition.id)}\n {renderBulkAnnotationImportResults(ctx.definition.id)}\n </>\n ),\n onResults: (ctx) =>\n openBulkAnnotationImportResults(ctx.definition.id, ctx.instance?.result),\n supports: (ctx) =>\n findExternalAnnotationPageReferences(ctx.vault, getManifestCanvases(ctx))\n .length > 0,\n prepare: async (ctx) => {\n const references = findExternalAnnotationPageReferences(\n ctx.vault,\n getManifestCanvases(ctx),\n );\n if (!references.length) {\n return false;\n }\n\n const options = await requestConfig(\n ctx,\n references,\n getDefaultRunOptions(),\n );\n if (options === false) {\n return false;\n }\n\n const selectedReferences = selectReferences(ctx, references, options);\n if (!selectedReferences.length) {\n return false;\n }\n\n runOptions.set(ctx.instanceKey, {\n references: selectedReferences,\n options,\n });\n return true;\n },\n run: async (ctx) => {\n const prepared = runOptions.get(ctx.instanceKey);\n const options = prepared?.options || getDefaultRunOptions();\n const references =\n prepared?.references ||\n selectReferences(\n ctx,\n findExternalAnnotationPageReferences(\n ctx.vault,\n getManifestCanvases(ctx),\n ),\n options,\n );\n\n try {\n ctx.setActionLabel(\"Importing external annotation pages\");\n ctx.setActionProgress({\n current: 0,\n total: Math.max(references.length, 1),\n label: \"Loading external annotation pages\",\n });\n\n if (!references.length) {\n ctx.setActionStatus(\"running\", \"No external annotation pages found\");\n return createEmptyResult();\n }\n\n const loadedPages: LoadedExternalAnnotationPage[] = [];\n for (const [index, reference] of references.entries()) {\n throwIfAborted(ctx.signal);\n ctx.setActionStatus(\n \"running\",\n `Loading ${index + 1}/${references.length}`,\n );\n ctx.appendActionLog(\"Loading external annotation page\", \"info\", {\n canvasId: reference.canvasId,\n pageId: reference.pageId,\n });\n\n try {\n const json = await fetchPage(reference.pageId, reference, ctx);\n loadedPages.push({ reference, json });\n } catch (error) {\n const message = getErrorMessage(error);\n loadedPages.push({ reference, error: message });\n ctx.appendActionLog(\n \"Failed to load external annotation page\",\n \"warn\",\n {\n canvasId: reference.canvasId,\n pageId: reference.pageId,\n reason: message,\n },\n );\n }\n\n ctx.setActionProgress({\n current: index + 1,\n total: references.length,\n label: \"Loading external annotation pages\",\n });\n }\n\n const plan = createExternalAnnotationPageInlinePlan({\n loadedPages,\n motivationFilter:\n options.motivationMode === \"selected\"\n ? options.motivations\n : undefined,\n });\n if (plan.errors.length) {\n throw new Error(\n plan.errors[0] || \"External annotation page import failed.\",\n );\n }\n\n ctx.setActionStatus(\"running\", \"Writing inline annotation pages\");\n ctx.setActionProgress({\n current: 0,\n total: Math.max(plan.totalAnnotations, plan.pages.length, 1),\n label: \"Writing inline annotations\",\n });\n\n const result = writeExternalAnnotationPageInlinePlan(ctx.vault, plan);\n ctx.appendActionLog(\n \"External annotation page import complete\",\n \"info\",\n {\n pages: result.pagesInlined,\n annotations: result.annotationsWritten,\n skipped: result.skippedPages.length,\n },\n );\n ctx.setActionStatus(\n \"running\",\n `Imported ${result.pagesInlined}/${result.totalExternalPages} external pages`,\n );\n ctx.setActionProgress({\n current: Math.max(result.annotationsWritten, result.pagesInlined),\n total: Math.max(result.annotationsWritten, result.pagesInlined, 1),\n label: \"Import complete\",\n });\n return result;\n } finally {\n runOptions.delete(ctx.instanceKey);\n }\n },\n };\n}\n\nasync function defaultFetchPage(\n pageId: string,\n _reference: ExternalAnnotationPageReference,\n ctx: BackgroundActionRunContext,\n) {\n const response = await fetch(pageId, {\n signal: ctx.signal,\n headers: {\n Accept: \"application/ld+json, application/json;q=0.9, */*;q=0.1\",\n },\n });\n\n if (!response.ok) {\n throw new Error(`Unable to fetch ${pageId} (${response.status}).`);\n }\n\n return response.json();\n}\n\nasync function defaultRequestConfig(\n ctx: BackgroundActionRunContext,\n references: ExternalAnnotationPageReference[],\n defaults: BulkAnnotationImportRunOptions,\n) {\n return requestBulkAnnotationImportConfig({\n actionId: ctx.definition.id,\n instanceKey: ctx.instanceKey,\n totalExternalPages: references.length,\n tags: getCanvasTagOptions(ctx, references),\n defaults,\n signal: ctx.signal,\n });\n}\n\nfunction getManifestCanvases(\n ctx: BackgroundActionRunContext | { vault: any; target: unknown },\n) {\n const manifest = ctx.vault.get(ctx.target as any) as any;\n return manifest?.items\n ? (ctx.vault.get(manifest.items) || []).filter(Boolean)\n : [];\n}\n\nfunction selectReferences(\n ctx: BackgroundActionRunContext,\n references: ExternalAnnotationPageReference[],\n options: BulkAnnotationImportRunOptions,\n) {\n if (options.scope !== \"tag\" || !options.tagKey) {\n return references;\n }\n\n const selectedTag = parseTagKey(options.tagKey);\n if (!selectedTag) {\n return [];\n }\n\n return references.filter((reference) =>\n ctx.tags.hasTag(\n { id: reference.canvasId, type: \"Canvas\" },\n selectedTag.type,\n selectedTag.id,\n ),\n );\n}\n\nfunction getCanvasTagOptions(\n ctx: BackgroundActionRunContext,\n references: ExternalAnnotationPageReference[],\n): BulkAnnotationImportTagOption[] {\n const tags = new Map<\n string,\n BulkAnnotationImportTagOption & ManifestEditorTag\n >();\n const pageCountByCanvas = new Map<string, number>();\n\n tags.set(getTagKey(FLAG_TAG), {\n ...FLAG_TAG,\n key: getTagKey(FLAG_TAG),\n canvasCount: 0,\n externalPageCount: 0,\n });\n\n for (const reference of references) {\n pageCountByCanvas.set(\n reference.canvasId,\n (pageCountByCanvas.get(reference.canvasId) || 0) + 1,\n );\n }\n\n for (const [canvasId, externalPageCount] of pageCountByCanvas) {\n for (const tag of ctx.tags.getTags({ id: canvasId, type: \"Canvas\" })) {\n const key = getTagKey(tag);\n const existing = tags.get(key);\n\n if (existing) {\n existing.canvasCount += 1;\n existing.externalPageCount += externalPageCount;\n } else {\n tags.set(key, {\n ...tag,\n key,\n canvasCount: 1,\n externalPageCount,\n });\n }\n }\n }\n\n return Array.from(tags.values()).sort((a, b) => {\n if (a.type === FLAG_TAG.type && a.id === FLAG_TAG.id) return -1;\n if (b.type === FLAG_TAG.type && b.id === FLAG_TAG.id) return 1;\n return (\n a.label.localeCompare(b.label) ||\n a.type.localeCompare(b.type) ||\n a.id.localeCompare(b.id)\n );\n });\n}\n\nfunction getTagKey(tag: Pick<ManifestEditorTag, \"type\" | \"id\">) {\n return `${tag.type}:${tag.id}`;\n}\n\nfunction parseTagKey(key: string): { type: string; id: string } | null {\n const separator = key.indexOf(\":\");\n if (separator === -1) {\n return null;\n }\n\n return {\n type: key.slice(0, separator),\n id: key.slice(separator + 1),\n };\n}\n\nfunction createEmptyResult(): ExternalAnnotationPageInlineResult {\n return {\n totalExternalPages: 0,\n pagesInlined: 0,\n canvasesUpdated: 0,\n annotationsWritten: 0,\n skippedPages: [],\n warnings: [],\n };\n}\n\nfunction throwIfAborted(signal: AbortSignal) {\n if (signal.aborted) {\n throw new DOMException(\"Aborted\", \"AbortError\");\n }\n}\n\nfunction getErrorMessage(error: unknown) {\n return error instanceof Error\n ? error.message\n : String(error || \"Unknown error\");\n}\n","import { useInStack } from \"@manifest-editor/editors\";\nimport {\n type BackgroundPanel,\n useLayoutActions,\n useLayoutMode,\n useLayoutState,\n} from \"@manifest-editor/shell\";\nimport { useEffect, useRef, useState } from \"react\";\nimport { useManifest } from \"react-iiif-vault\";\nimport { ANNOTATIONS_LEFT_PANEL_ID } from \"./constants\";\n\nconst RANGES_PANEL_ID = \"@manifest-editor/ranges-listing\";\n\nexport const annotationRoutingBackground: BackgroundPanel = {\n id: \"@manifest-editor/annotations-routing\",\n label: \"Annotation routing\",\n render: () => <AnnotationRoutingBackground />,\n};\n\nfunction AnnotationRoutingBackground() {\n const manifest = useManifest();\n const canvas = useInStack(\"Canvas\");\n const layoutMode = useLayoutMode();\n const { leftPanel, rightPanel } = useLayoutState();\n const { edit, open, rightPanel: rightPanelActions } = useLayoutActions();\n const lastCanvas = useRef<string | null>(null);\n const [closedRightPanel, setClosedRightPanel] = useState(false);\n\n useEffect(() => {\n const canvasId = canvas?.resource?.source?.id;\n if (canvasId) {\n lastCanvas.current = canvasId;\n }\n }, [canvas?.resource?.source?.id]);\n\n useEffect(() => {\n if (leftPanel.current === ANNOTATIONS_LEFT_PANEL_ID) {\n const firstCanvas = lastCanvas.current || manifest?.items?.[0]?.id;\n if (firstCanvas) {\n open({ id: \"current-canvas\" });\n edit({ id: firstCanvas, type: \"Canvas\" });\n }\n\n if (layoutMode === \"focused\") {\n return;\n }\n\n if (rightPanel.open) {\n rightPanelActions.close();\n setClosedRightPanel(true);\n }\n return;\n }\n\n if (\n closedRightPanel &&\n !rightPanel.open &&\n leftPanel.current !== RANGES_PANEL_ID\n ) {\n rightPanelActions.open();\n setClosedRightPanel(false);\n }\n }, [leftPanel.current, layoutMode]);\n\n return null;\n}\n","import type { AnnotationPanel, BackgroundActionDefinition, BackgroundPanel, LayoutPanel, PluginMetadata } from \"@manifest-editor/shell\";\nimport { annotationsPanel } from \"./annotation-panel\";\nimport { canvasAnnotations } from \"./canvas-annotations\";\nimport { ANNOTATIONS_PLUGIN_ID } from \"./constants\";\nimport { createBulkAnnotationImportBackgroundAction } from \"./importer/background-action\";\nimport { annotationRoutingBackground } from \"./routing-background\";\n\nexport default {\n id: ANNOTATIONS_PLUGIN_ID,\n label: \"Annotations\",\n description: \"Create, view, and inline external supplemental canvas annotation pages.\",\n author: \"Digirati\",\n official: true,\n defaultEnabled: true,\n tags: [\"annotations\", \"iiif\", \"external-pages\"],\n supports: {\n apps: [\"manifest-editor\"],\n projectTypes: [\"Manifest\"],\n },\n} satisfies PluginMetadata;\n\nexport const leftPanels: LayoutPanel[] = [annotationsPanel];\nexport const annotations: AnnotationPanel[] = [canvasAnnotations];\nexport const background: BackgroundPanel[] = [annotationRoutingBackground];\nexport const backgroundActions: BackgroundActionDefinition[] = [createBulkAnnotationImportBackgroundAction()];\n\nexport * from \"./constants\";\nexport * from \"./importer/background-action\";\nexport * from \"./importer/importer\";\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["useAtlasStore"],"sources":["../src/constants.ts","../src/icons.tsx","../src/components/AnnotationsOcrActions.tsx","../src/components/AnnotationsCreateEmptyPage.tsx","../src/components/RenderPaintingAnnotationPreview.tsx","../src/components/AnnotationsSidebarListItem.tsx","../src/components/AnnotationsListingAnnotations.tsx","../src/annotation-panel.tsx","../src/canvas-annotations.tsx","../src/importer/config-modal.tsx","../src/importer/importer.ts","../src/importer/results.tsx","../src/importer/background-action.tsx","../src/routing-background.tsx","../src/index.ts"],"sourcesContent":["export const ANNOTATIONS_PLUGIN_ID = \"@manifest-editor/annotations\";\nexport const ANNOTATIONS_LEFT_PANEL_ID = \"@manifest-editor/canvas-annotation-listing\";\nexport const CANVAS_ANNOTATIONS_PANEL_ID = \"@manifest-editor/canvas-annotations\";\nexport const BULK_ANNOTATION_IMPORT_ACTION_ID = \"@manifest-editor/annotations/bulk-import-pages\";\n","import type { SVGProps } from \"react\";\n\nexport function AnnotationsIcon(props: SVGProps<SVGSVGElement>) {\n return (\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"1em\" height=\"1em\" viewBox=\"0 0 24 24\" {...props}>\n <path\n fill=\"currentColor\"\n d=\"M20 2H4c-1.1 0-1.99.9-1.99 2L2 22l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2m0 14H5.17l-.59.59l-.58.58V4h16zm-9.5-2H18v-2h-5.5zm3.86-5.87c.2-.2.2-.51 0-.71l-1.77-1.77c-.2-.2-.51-.2-.71 0L6 11.53V14h2.47z\"\n />\n </svg>\n );\n}\n\nexport function AddAnnotationIcon(props: SVGProps<SVGSVGElement>) {\n return (\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"1em\" height=\"1em\" viewBox=\"0 0 24 24\" {...props}>\n <path\n fill=\"currentColor\"\n d=\"M9 22a1 1 0 0 1-1-1v-3H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2h-6.1l-3.7 3.71c-.2.19-.45.29-.7.29zm1-6v3.08L13.08 16H20V4H4v12zm1-10h2v3h3v2h-3v3h-2v-3H8V9h3z\"\n />\n </svg>\n );\n}\n","import { ActionButton } from \"@manifest-editor/components\";\nimport {\n type AvailableBackgroundAction,\n runBackgroundAction,\n useAvailableBackgroundActions,\n useBackgroundActionsStoreApi,\n useCanvasProgressStatus,\n} from \"@manifest-editor/shell\";\nimport { useCanvas } from \"react-iiif-vault\";\n\nconst OCR_ACTIONS = [\n {\n id: \"@manifest-editor/ocr-docling/run-ocr\",\n label: \"Run Local OCR\",\n preparingLabel: \"Preparing OCR\",\n queuedLabel: \"OCR queued\",\n pendingLabel: \"OCR in progress\",\n },\n {\n id: \"@manifest-editor/remote-inference/action\",\n label: \"Run remote OCR\",\n preparingLabel: \"Preparing local OCR\",\n queuedLabel: \"OCR queued\",\n pendingLabel: \"OCR in progress\",\n },\n {\n id: \"@manifest-editor/remote-inference/structured-output\",\n label: \"Run structured output\",\n preparingLabel: \"Preparing structured output\",\n queuedLabel: \"Structured output queued\",\n pendingLabel: \"Structured output in progress\",\n },\n];\n\nexport function AnnotationsOcrActions() {\n const store = useBackgroundActionsStoreApi();\n const groups = useAvailableBackgroundActions();\n const canvas = useCanvas();\n const canvasProgressStatus = useCanvasProgressStatus(canvas);\n const actions = groups.flatMap((group) => group.actions);\n const availableActions = OCR_ACTIONS.map((ocrAction) => {\n const action = actions.find((item) => item.definition.id === ocrAction.id);\n return action ? { ...ocrAction, action } : null;\n }).filter(\n (\n item,\n ): item is {\n id: string;\n label: string;\n preparingLabel: string;\n queuedLabel: string;\n pendingLabel: string;\n action: AvailableBackgroundAction;\n } => !!item,\n );\n\n if (!availableActions.length) {\n return null;\n }\n\n const activeAction = availableActions.find(({ action }) => {\n const status = action.instance?.status;\n const isBusy = status === \"preparing\" || status === \"running\";\n if (!isBusy) return false;\n\n if (canvasProgressStatus === \"queued\" || canvasProgressStatus === \"pending\") {\n return true;\n }\n\n return action.context.currentCanvas?.id === canvas?.id;\n });\n\n return (\n <div className=\"mt-5 flex w-full flex-col items-stretch gap-2 border-t border-gray-200 pt-4\">\n <div className=\"text-center text-xs font-semibold uppercase tracking-wide text-gray-500\">\n OCR and structured output\n </div>\n {activeAction ? (\n <div className=\"rounded border border-amber-200 bg-amber-50 px-3 py-2 text-center text-sm text-amber-800\">\n <div className=\"font-medium\">\n {canvasProgressStatus === \"queued\"\n ? activeAction.queuedLabel\n : canvasProgressStatus === \"pending\"\n ? activeAction.pendingLabel\n : activeAction.preparingLabel}\n </div>\n <div className=\"mt-1 text-xs text-amber-700\">\n {activeAction.action.instance?.statusText || activeAction.label}\n </div>\n </div>\n ) : null}\n {activeAction\n ? null\n : availableActions.map(({ id, label, action }) => {\n const busy = action.instance?.status === \"preparing\" || action.instance?.status === \"running\";\n return (\n <ActionButton\n key={id}\n large\n isDisabled={busy}\n onPress={() => {\n if (busy) return;\n void runBackgroundAction({\n store,\n context: action.context,\n prepareData: { scope: \"selected\" },\n });\n }}\n >\n {label}\n </ActionButton>\n );\n })}\n </div>\n );\n}\n","import {\n ActionButton,\n AddIcon,\n Sidebar,\n SidebarContent,\n SidebarHeader,\n} from \"@manifest-editor/components\";\nimport { useInStack } from \"@manifest-editor/editors\";\nimport { useInlineCreator } from \"@manifest-editor/shell\";\nimport { useCanvas } from \"react-iiif-vault\";\nimport { AddAnnotationIcon } from \"../icons\";\nimport { AnnotationsOcrActions } from \"./AnnotationsOcrActions\";\n\nexport function AnnotationsCreateEmptyPage() {\n const canvasRef = useInStack(\"Canvas\");\n const canvasId = canvasRef?.resource.source?.id;\n const canvas = useCanvas({ id: canvasId });\n const creator = useInlineCreator();\n\n const createEmptyAnnotationPage = () => {\n if (!canvas) return;\n creator.create(\n \"@manifest-editor/empty-annotation-page\",\n {\n label: { en: [\"Inline annotations\"] },\n },\n {\n target: {\n id: canvas.id,\n type: \"Canvas\",\n },\n targetType: \"AnnotationPage\",\n parent: {\n property: \"annotations\",\n resource: {\n id: canvas.id,\n type: \"Canvas\",\n },\n },\n },\n );\n };\n\n return (\n <Sidebar>\n <SidebarHeader\n title=\"Annotations\"\n actions={[\n {\n icon: <AddAnnotationIcon className=\"text-2xl\" />,\n title: \"Add annotation\",\n disabled: true,\n onClick: () => void 0,\n },\n ]}\n />\n <SidebarContent>\n <div className=\"flex flex-col items-center justify-center p-4\">\n <div className=\"p-4 opacity-50 text-center\">\n This canvas does not yet have any inline annotations. To add inline\n annotations, an AnnotationPage is created which will be linked to\n this canvas, and can then used to add your annotations. Simply use\n the link below to start adding your annotations\n </div>\n\n <ActionButton\n large\n primary\n onPress={() => createEmptyAnnotationPage()}\n >\n <AddIcon className=\"text-xl\" /> Create empty page\n </ActionButton>\n\n <AnnotationsOcrActions />\n </div>\n </SidebarContent>\n </Sidebar>\n );\n}\n","import { AnnotationPreview, CanvasTargetContext } from \"@manifest-editor/editors\";\nimport { useLayoutActions } from \"@manifest-editor/shell\";\nimport { LocaleString, useAnnotation, useAtlasStore, useCanvas } from \"react-iiif-vault\";\nimport { useStore } from \"zustand\";\n\nexport function RenderPaintingAnnotationPreview() {\n const annotation = useAnnotation();\n const canvas = useCanvas();\n const store = useAtlasStore();\n const { edit } = useLayoutActions();\n const viewport = useStore(store, (state) => (canvas?.id ? state.canvasViewports[canvas.id] : null));\n\n if (!annotation || !canvas || !viewport) return null;\n\n return (\n <div className=\"p-2\">\n <LocaleString\n as=\"div\"\n defaultText={(<span className=\"opacity-50\">Untitled</span>) as any}\n className=\"whitespace-nowrap overflow-ellipsis w-full overflow-x-hidden\"\n >\n {annotation?.label}\n </LocaleString>\n <LocaleString className=\"text-gray-500 text-sm bg-white line-clamp-2 mb-4\" as=\"div\">\n {annotation?.summary}\n </LocaleString>\n <CanvasTargetContext>\n <AnnotationPreview viewport={viewport} onClick={() => edit(annotation, undefined, { forceOpen: true })} />\n </CanvasTargetContext>\n </div>\n );\n}\n","import { ActionButton, CheckIcon, DeleteIcon, EditTextIcon, HTMLAnnotationBodyRender } from \"@manifest-editor/components\";\nimport { HTMLAnnotationEditor, useAnnotationEditor, useAnnotationInfo } from \"@manifest-editor/editors\";\nimport { useLayoutActions } from \"@manifest-editor/shell\";\nimport { useState } from \"react\";\nimport { AnnotationContext } from \"react-iiif-vault\";\nimport { RenderPaintingAnnotationPreview } from \"./RenderPaintingAnnotationPreview\";\n\nexport function AnnotationsSidebarListItem() {\n const { isPending, cancelRequest, busy, requestAnnotationFromTarget, deleteAnnotation } = useAnnotationEditor();\n const [annotation, { highlightProps, annotationTarget }] = useAnnotationInfo();\n const { edit } = useLayoutActions();\n const bodies = annotation?.body || [];\n const isBodyEmpty = !annotation || bodies.length === 0;\n const [isOpen, setIsOpen] = useState(false);\n\n return (\n <div {...highlightProps} className=\"border border-gray-300 hover:border-me-500 shadow-sm rounded bg-white relative\">\n <div className=\"relative\">\n {annotationTarget ? (\n <AnnotationContext annotation={annotationTarget}>\n <RenderPaintingAnnotationPreview />\n </AnnotationContext>\n ) : isBodyEmpty ? (\n <div className=\"flex items-center justify-center px-4 py-6 text-gray-400 text-sm\">This annotation has no body.</div>\n ) : isOpen ? (\n <HTMLAnnotationEditor className=\"border-none\" />\n ) : (\n <HTMLAnnotationBodyRender className=\"px-3 pt-3 line-clamp-3 prose-p:text-slate-600\" locale=\"en\" />\n )}\n </div>\n <div className=\"flex gap-2 p-2\">\n {annotationTarget ? (\n <ActionButton onPress={() => edit({ id: annotationTarget, type: \"Annotation\" }, undefined, { forceOpen: true })}>\n Edit painting annotation\n </ActionButton>\n ) : isOpen && isPending ? (\n <ActionButton\n primary\n onPress={() => {\n setIsOpen(false);\n cancelRequest();\n }}\n >\n <CheckIcon /> Finish editing\n </ActionButton>\n ) : (\n <ActionButton\n isDisabled={busy}\n onPress={() => {\n setIsOpen(true);\n requestAnnotationFromTarget().then(() => {\n setIsOpen(false);\n });\n }}\n >\n <EditTextIcon /> {isBodyEmpty ? \"Edit target\" : \"Edit\"}\n </ActionButton>\n )}\n <ActionButton className=\"gap-2 flex\" onPress={() => deleteAnnotation()}>\n <DeleteIcon /> Delete\n </ActionButton>\n </div>\n </div>\n );\n}\n","import {\n ActionButton,\n Sidebar,\n SidebarContent,\n SidebarHeader,\n TargetIcon,\n} from \"@manifest-editor/components\";\nimport { AnnotationCreationPopup } from \"@manifest-editor/editors\";\nimport {\n AnnotationContext,\n useAnnotationPage,\n useCanvas,\n useRenderingStrategy,\n useRequestAnnotation,\n} from \"react-iiif-vault\";\nimport { AddAnnotationIcon } from \"../icons\";\nimport { AnnotationsSidebarListItem } from \"./AnnotationsSidebarListItem\";\nimport { AnnotationsOcrActions } from \"./AnnotationsOcrActions\";\n\nexport function AnnotationsListingAnnotations() {\n const canvas = useCanvas();\n const page = useAnnotationPage();\n const { requestAnnotation, isActive, busy, cancelRequest } =\n useRequestAnnotation();\n const [strategy] = useRenderingStrategy();\n\n if (strategy.type !== \"images\") {\n return <div>Not supported</div>;\n }\n\n if (!page) {\n return null;\n }\n\n const createAnnotation = () =>\n requestAnnotation({\n type: \"box\",\n annotationPopup: (\n <AnnotationCreationPopup\n annotationPageId={page.id}\n canvasId={canvas!.id}\n />\n ),\n });\n\n return (\n <Sidebar>\n <SidebarHeader\n title=\"Annotations\"\n actions={[\n {\n icon: <AddAnnotationIcon className=\"text-2xl\" />,\n title: \"Add annotation\",\n disabled: isActive || busy,\n onClick: createAnnotation,\n },\n ]}\n />\n {isActive ? (\n <>\n <button\n aria-label=\"cancel add annotation\"\n className=\"m-2 rounded border border-gray-300 bg-white px-3 py-2 text-sm text-gray-700\"\n type=\"button\"\n onClick={() => cancelRequest()}\n >\n Exit edit mode\n </button>\n <div className=\"flex flex-col gap-5 text-center p-4 items-center justify-center\">\n <TargetIcon className=\"w-32 h-32 text-gray-300\" />\n <p className=\"text-gray-500\">Draw a box on the canvas</p>\n </div>\n </>\n ) : null}\n <SidebarContent className=\"w-full p-2 flex flex-col gap-2\">\n {page.items.map((annotation) => (\n <AnnotationContext key={annotation.id} annotation={annotation.id}>\n <AnnotationsSidebarListItem />\n </AnnotationContext>\n ))}\n\n {!isActive && page.items.length === 0 ? (\n <div className=\"flex flex-col items-center justify-center p-4\">\n <div className=\"p-4 opacity-50 text-center\">\n This canvas does not yet have any inline annotations.\n </div>\n\n <ActionButton\n large\n primary\n isDisabled={isActive}\n onPress={() => createAnnotation()}\n >\n <AddAnnotationIcon className=\"text-xl\" /> Add annotation\n </ActionButton>\n\n <AnnotationsOcrActions />\n </div>\n ) : null}\n </SidebarContent>\n </Sidebar>\n );\n}\n","import { useInStack } from \"@manifest-editor/editors\";\nimport type { LayoutPanel } from \"@manifest-editor/shell\";\nimport {\n AnnotationPageContext,\n CanvasContext,\n useCanvas,\n} from \"react-iiif-vault\";\nimport { ANNOTATIONS_LEFT_PANEL_ID } from \"./constants\";\nimport { AnnotationsCreateEmptyPage } from \"./components/AnnotationsCreateEmptyPage\";\nimport { AnnotationsListingAnnotations } from \"./components/AnnotationsListingAnnotations\";\nimport { AnnotationsIcon } from \"./icons\";\n\nexport const annotationsPanel: LayoutPanel = {\n id: ANNOTATIONS_LEFT_PANEL_ID,\n label: \"Annotations\",\n icon: <AnnotationsIcon />,\n focusedMode: {\n closeOnMainPanelClick: false,\n },\n render: () => <AnnotationsPanel />,\n};\n\nfunction AnnotationsPanel() {\n const canvasRef = useInStack(\"Canvas\");\n const canvasId = canvasRef?.resource.source?.id;\n const canvas = useCanvas({ id: canvasId });\n const firstPage = canvas?.annotations[0];\n\n if (!canvas) {\n return (\n <div className=\"flex flex-col gap-5 text-center p-4 items-center justify-center\">\n <AnnotationsIcon className=\"w-32 h-32 text-gray-300\" />\n <p className=\"text-gray-500\">\n Annotations are associated with Canvases in a IIIF Manifest. To view\n or add annotations, first create a Canvas and then select the\n Annotations link\n </p>\n </div>\n );\n }\n\n if (firstPage) {\n return (\n <AnnotationPageContext annotationPage={firstPage.id}>\n <CanvasContext canvas={canvas.id}>\n <AnnotationsListingAnnotations />\n </CanvasContext>\n </AnnotationPageContext>\n );\n }\n\n return (\n <CanvasContext canvas={canvas.id}>\n <AnnotationsCreateEmptyPage />\n </CanvasContext>\n );\n}\n","import { ViewerAnnotationPage } from \"@manifest-editor/editors\";\nimport { type AnnotationPanel, useAtlasStore, useLayoutState } from \"@manifest-editor/shell\";\nimport { AnnotationPageContext, useCanvas } from \"react-iiif-vault\";\nimport { useStore } from \"zustand\";\nimport { ANNOTATIONS_LEFT_PANEL_ID, CANVAS_ANNOTATIONS_PANEL_ID } from \"./constants\";\n\nexport const canvasAnnotations: AnnotationPanel = {\n id: CANVAS_ANNOTATIONS_PANEL_ID,\n label: \"Canvas annotations\",\n render: () => <CanvasAnnotations />,\n};\n\nfunction CanvasAnnotations() {\n const canvas = useCanvas();\n const store = useAtlasStore();\n const toolEnabled = useStore(store, (state) => state.tool.enabled);\n const { leftPanel } = useLayoutState();\n const isLeftPanel = leftPanel.current === ANNOTATIONS_LEFT_PANEL_ID;\n const firstAnnotationPage = canvas?.annotations[0];\n\n if (!canvas || toolEnabled || !firstAnnotationPage || !isLeftPanel) {\n return null;\n }\n\n return (\n <AnnotationPageContext annotationPage={firstAnnotationPage.id}>\n <ViewerAnnotationPage />\n </AnnotationPageContext>\n );\n}\n","import { Modal } from \"@manifest-editor/components\";\nimport { useEffect, useMemo, useState } from \"react\";\n\nexport const BULK_ANNOTATION_IMPORT_CONFIG_EVENT =\n \"@manifest-editor/annotations:bulk-import-config\";\n\nexport const BULK_ANNOTATION_IMPORT_MOTIVATIONS = [\n \"commenting\",\n \"supplementing\",\n \"tagging\",\n \"describing\",\n \"linking\",\n \"painting\",\n \"highlighting\",\n \"classifying\",\n \"identifying\",\n \"replying\",\n] as const;\n\nexport type BulkAnnotationImportScope = \"all\" | \"tag\";\nexport type BulkAnnotationImportMotivationMode = \"all\" | \"selected\";\n\nexport type BulkAnnotationImportRunOptions = {\n scope: BulkAnnotationImportScope;\n tagKey?: string;\n motivationMode: BulkAnnotationImportMotivationMode;\n motivations: string[];\n};\n\nexport type BulkAnnotationImportTagOption = {\n key: string;\n label: string;\n canvasCount: number;\n externalPageCount: number;\n};\n\nexport type BulkAnnotationImportConfigRequest = {\n actionId: string;\n instanceKey: string;\n totalExternalPages: number;\n tags: BulkAnnotationImportTagOption[];\n defaults: BulkAnnotationImportRunOptions;\n signal?: AbortSignal;\n resolve: (options: BulkAnnotationImportRunOptions | false) => void;\n};\n\nexport function requestBulkAnnotationImportConfig(\n request: Omit<BulkAnnotationImportConfigRequest, \"resolve\">,\n): Promise<BulkAnnotationImportRunOptions | false> {\n return new Promise((resolve) => {\n if (request.signal?.aborted) {\n resolve(false);\n return;\n }\n\n let settled = false;\n const settle = (options: BulkAnnotationImportRunOptions | false) => {\n if (settled) {\n return;\n }\n\n settled = true;\n request.signal?.removeEventListener(\"abort\", handleAbort);\n resolve(options);\n };\n const handleAbort = () => settle(false);\n\n request.signal?.addEventListener(\"abort\", handleAbort, { once: true });\n window.dispatchEvent(\n new CustomEvent<BulkAnnotationImportConfigRequest>(\n BULK_ANNOTATION_IMPORT_CONFIG_EVENT,\n {\n detail: { ...request, resolve: settle },\n },\n ),\n );\n });\n}\n\nexport function renderBulkAnnotationImportConfigModal(actionId: string) {\n return <BulkAnnotationImportConfigModal actionId={actionId} />;\n}\n\nexport function getDefaultRunOptions(): BulkAnnotationImportRunOptions {\n return {\n scope: \"all\",\n motivationMode: \"all\",\n motivations: [],\n };\n}\n\nfunction BulkAnnotationImportConfigModal({ actionId }: { actionId: string }) {\n const [request, setRequest] =\n useState<BulkAnnotationImportConfigRequest | null>(null);\n const [options, setOptions] = useState<BulkAnnotationImportRunOptions>(\n getDefaultRunOptions(),\n );\n const [customMotivations, setCustomMotivations] = useState(\"\");\n\n useEffect(() => {\n const listener = (event: Event) => {\n const detail = (event as CustomEvent<BulkAnnotationImportConfigRequest>)\n .detail;\n if (detail?.actionId === actionId) {\n setRequest(detail);\n setOptions(normaliseDefaults(detail.defaults, detail.tags));\n setCustomMotivations(\"\");\n }\n };\n\n window.addEventListener(BULK_ANNOTATION_IMPORT_CONFIG_EVENT, listener);\n return () =>\n window.removeEventListener(BULK_ANNOTATION_IMPORT_CONFIG_EVENT, listener);\n }, [actionId]);\n\n useEffect(() => {\n if (!request?.signal) {\n return;\n }\n\n if (request.signal.aborted) {\n setRequest(null);\n return;\n }\n\n const handleAbort = () => setRequest(null);\n request.signal.addEventListener(\"abort\", handleAbort, { once: true });\n return () => request.signal?.removeEventListener(\"abort\", handleAbort);\n }, [request]);\n\n const selectedTag = useMemo(\n () => request?.tags.find((tag) => tag.key === options.tagKey),\n [request?.tags, options.tagKey],\n );\n const selectedExternalPages =\n options.scope === \"tag\"\n ? selectedTag?.externalPageCount || 0\n : request?.totalExternalPages || 0;\n const selectedMotivations = useMemo(\n () => getSelectedMotivations(options, customMotivations),\n [customMotivations, options],\n );\n const motivationSelectionInvalid =\n options.motivationMode === \"selected\" && selectedMotivations.length === 0;\n\n if (!request) {\n return null;\n }\n\n const close = (value: BulkAnnotationImportRunOptions | false) => {\n request.resolve(value);\n setRequest(null);\n };\n\n const tagSelectionDisabled = !request.tags.length;\n\n return (\n <Modal\n title=\"Import External Annotation Pages\"\n onClose={() => close(false)}\n className=\"max-w-2xl\"\n actions={\n <div className=\"flex gap-2\">\n <button\n type=\"button\"\n className=\"rounded border border-zinc-300 bg-white px-3 py-2 text-sm text-zinc-700\"\n onClick={() => close(false)}\n >\n Cancel\n </button>\n <button\n type=\"button\"\n className=\"rounded border border-me-primary-500 bg-me-primary-500 px-3 py-2 text-sm text-white disabled:cursor-not-allowed disabled:opacity-50\"\n disabled={selectedExternalPages === 0 || motivationSelectionInvalid}\n onClick={() =>\n close({\n ...options,\n motivations:\n options.motivationMode === \"selected\"\n ? selectedMotivations\n : [],\n })\n }\n >\n Import pages\n </button>\n </div>\n }\n >\n <div className=\"flex min-h-0 flex-col gap-4 p-4 text-sm text-zinc-700\">\n <fieldset className=\"grid gap-2\">\n <legend className=\"font-medium text-zinc-900\">Canvases</legend>\n <label className=\"flex items-center gap-2\">\n <input\n type=\"radio\"\n checked={options.scope === \"all\"}\n onChange={() =>\n setOptions((current) => ({ ...current, scope: \"all\" }))\n }\n />\n <span>\n All canvases with external annotation pages (\n {request.totalExternalPages})\n </span>\n </label>\n <label className=\"flex items-center gap-2\">\n <input\n type=\"radio\"\n checked={options.scope === \"tag\"}\n disabled={tagSelectionDisabled}\n onChange={() =>\n setOptions((current) => ({\n ...current,\n scope: \"tag\",\n tagKey: current.tagKey || request.tags[0]?.key,\n }))\n }\n />\n <span>Only canvases with tag</span>\n </label>\n <select\n className=\"rounded border border-zinc-300 bg-white p-2 disabled:bg-zinc-100\"\n disabled={options.scope !== \"tag\" || tagSelectionDisabled}\n value={options.tagKey || \"\"}\n onChange={(event) =>\n setOptions((current) => ({\n ...current,\n tagKey: event.target.value,\n }))\n }\n >\n {request.tags.map((tag) => (\n <option key={tag.key} value={tag.key}>\n {tag.label} ({tag.externalPageCount})\n </option>\n ))}\n </select>\n </fieldset>\n\n <fieldset className=\"grid gap-2\">\n <legend className=\"font-medium text-zinc-900\">Motivations</legend>\n <label className=\"flex items-center gap-2\">\n <input\n type=\"radio\"\n checked={options.motivationMode === \"all\"}\n onChange={() =>\n setOptions((current) => ({ ...current, motivationMode: \"all\" }))\n }\n />\n <span>All motivations</span>\n </label>\n <label className=\"flex items-center gap-2\">\n <input\n type=\"radio\"\n checked={options.motivationMode === \"selected\"}\n onChange={() =>\n setOptions((current) => ({\n ...current,\n motivationMode: \"selected\",\n motivations: current.motivations.length\n ? current.motivations\n : [\"commenting\"],\n }))\n }\n />\n <span>Only selected motivations</span>\n </label>\n <div className=\"grid grid-cols-2 gap-2 rounded border border-zinc-200 p-3\">\n {BULK_ANNOTATION_IMPORT_MOTIVATIONS.map((motivation) => (\n <label key={motivation} className=\"flex items-center gap-2\">\n <input\n type=\"checkbox\"\n disabled={options.motivationMode !== \"selected\"}\n checked={options.motivations.includes(motivation)}\n onChange={(event) =>\n setOptions((current) => ({\n ...current,\n motivationMode: \"selected\",\n motivations: event.target.checked\n ? uniqueStrings([...current.motivations, motivation])\n : current.motivations.filter(\n (item) => item !== motivation,\n ),\n }))\n }\n />\n <span>{motivation}</span>\n </label>\n ))}\n </div>\n <label className=\"grid gap-1\">\n <span className=\"font-medium text-zinc-900\">\n Additional motivations\n </span>\n <input\n type=\"text\"\n className=\"rounded border border-zinc-300 p-2\"\n disabled={options.motivationMode !== \"selected\"}\n value={customMotivations}\n placeholder=\"transcribing, reviewing\"\n onChange={(event) => setCustomMotivations(event.target.value)}\n />\n </label>\n </fieldset>\n\n <div className=\"rounded border border-zinc-200 bg-white p-3 text-zinc-600\">\n {selectedExternalPages} external annotation page\n {selectedExternalPages === 1 ? \"\" : \"s\"} selected.\n {options.motivationMode === \"selected\" ? (\n <>\n {\" \"}\n {selectedMotivations.length} motivation\n {selectedMotivations.length === 1 ? \"\" : \"s\"} selected.\n </>\n ) : null}\n </div>\n </div>\n </Modal>\n );\n}\n\nfunction normaliseDefaults(\n defaults: BulkAnnotationImportRunOptions,\n tags: BulkAnnotationImportTagOption[],\n): BulkAnnotationImportRunOptions {\n const hasSelectedTag = defaults.tagKey\n ? tags.some((tag) => tag.key === defaults.tagKey)\n : false;\n\n return {\n scope: defaults.scope === \"tag\" && tags.length ? \"tag\" : \"all\",\n tagKey: hasSelectedTag ? defaults.tagKey : tags[0]?.key,\n motivationMode: defaults.motivationMode === \"selected\" ? \"selected\" : \"all\",\n motivations: uniqueStrings(defaults.motivations || []),\n };\n}\n\nfunction getSelectedMotivations(\n options: BulkAnnotationImportRunOptions,\n customMotivations: string,\n) {\n if (options.motivationMode !== \"selected\") {\n return [];\n }\n\n return uniqueStrings([\n ...options.motivations,\n ...parseMotivationText(customMotivations),\n ]);\n}\n\nfunction parseMotivationText(value: string) {\n return value\n .split(/[,\\n]/)\n .map((item) => item.trim())\n .filter(Boolean);\n}\n\nfunction uniqueStrings(values: string[]) {\n return Array.from(new Set(values.map((item) => item.trim()).filter(Boolean)));\n}\n","import {\n addReference,\n batchActions,\n importEntities,\n modifyEntityField,\n} from \"@iiif/helpers/vault/actions\";\nimport { convertPresentation2 } from \"@iiif/parser/presentation-2\";\n\nconst IS_EXTERNAL = \"iiif-parser:isExternal\";\nconst HAS_PART = \"iiif-parser:hasPart\";\nconst RESOURCE_TYPES = [\n \"Annotation\",\n \"AnnotationPage\",\n \"ContentResource\",\n \"Canvas\",\n \"Manifest\",\n \"Range\",\n];\n\nexport type ExternalAnnotationPageReference = {\n key: string;\n canvasId: string;\n canvasLabel: string;\n pageId: string;\n annotationPageIndex: number;\n existingPage?: any;\n};\n\nexport type LoadedExternalAnnotationPage = {\n reference: ExternalAnnotationPageReference;\n json?: unknown;\n error?: string;\n};\n\nexport type SkippedExternalAnnotationPage = {\n key: string;\n canvasId: string;\n canvasLabel: string;\n pageId: string;\n reason: string;\n};\n\nexport type InlineAnnotationPageImport = {\n reference: ExternalAnnotationPageReference;\n page: any;\n annotations: any[];\n skippedAnnotations: number;\n skippedByMotivation: number;\n};\n\nexport type ExternalAnnotationPageInlinePlan = {\n totalExternalPages: number;\n totalAnnotations: number;\n pages: InlineAnnotationPageImport[];\n skippedPages: SkippedExternalAnnotationPage[];\n warnings: string[];\n errors: string[];\n};\n\nexport type ExternalAnnotationPageInlineResult = {\n totalExternalPages: number;\n pagesInlined: number;\n canvasesUpdated: number;\n annotationsWritten: number;\n skippedPages: SkippedExternalAnnotationPage[];\n warnings: string[];\n};\n\ntype EntityBuckets = {\n AnnotationPage: Record<string, any>;\n Annotation: Record<string, any>;\n ContentResource: Record<string, any>;\n};\n\nexport function findExternalAnnotationPageReferences(\n vault: any,\n canvases: any[],\n): ExternalAnnotationPageReference[] {\n const references: ExternalAnnotationPageReference[] = [];\n\n for (const canvas of canvases) {\n if (!canvas?.id || !Array.isArray(canvas.annotations)) {\n continue;\n }\n\n canvas.annotations.forEach((annotationPageRef: any, index: number) => {\n const pageId = getResourceId(annotationPageRef);\n if (!pageId) {\n return;\n }\n\n const existingPage =\n vault.get({ id: pageId, type: \"AnnotationPage\" }) ||\n vault.get(annotationPageRef) ||\n annotationPageRef;\n\n if (!isExternalAnnotationPage(existingPage)) {\n return;\n }\n\n references.push({\n key: `${canvas.id}:annotations:${index}:${pageId}`,\n canvasId: canvas.id,\n canvasLabel: getLabelText(canvas.label) || canvas.id,\n pageId,\n annotationPageIndex: index,\n existingPage,\n });\n });\n }\n\n return references;\n}\n\nexport function createExternalAnnotationPageInlinePlan(options: {\n loadedPages: LoadedExternalAnnotationPage[];\n motivationFilter?: string[];\n}): ExternalAnnotationPageInlinePlan {\n const pages: InlineAnnotationPageImport[] = [];\n const skippedPages: SkippedExternalAnnotationPage[] = [];\n const warnings: string[] = [];\n const seenPageIds = new Set<string>();\n const motivationFilter = createMotivationFilter(options.motivationFilter);\n let totalAnnotations = 0;\n\n for (const loaded of options.loadedPages) {\n const { reference } = loaded;\n\n if (seenPageIds.has(reference.pageId)) {\n skippedPages.push(\n toSkippedPage(\n reference,\n \"External annotation page is referenced more than once.\",\n ),\n );\n continue;\n }\n seenPageIds.add(reference.pageId);\n\n if (loaded.error) {\n skippedPages.push(toSkippedPage(reference, loaded.error));\n continue;\n }\n\n const pageResult = normaliseFetchedAnnotationPage(loaded.json, reference);\n if (pageResult.warning) {\n warnings.push(pageResult.warning);\n }\n if (!pageResult.page) {\n skippedPages.push(toSkippedPage(reference, pageResult.error));\n continue;\n }\n\n const page = pageResult.page;\n if (!Array.isArray(page.items)) {\n skippedPages.push(\n toSkippedPage(\n reference,\n \"Fetched annotation page does not contain an items array.\",\n ),\n );\n continue;\n }\n\n const annotationItems = page.items.filter(\n (item: any) => item?.type === \"Annotation\",\n );\n const annotations = annotationItems.filter((annotation: any) =>\n annotationMatchesMotivationFilter(annotation, motivationFilter),\n );\n const skippedAnnotations = page.items.length - annotationItems.length;\n const skippedByMotivation = annotationItems.length - annotations.length;\n\n if (skippedAnnotations) {\n warnings.push(\n `${reference.pageId}: skipped ${skippedAnnotations} non-Annotation item${skippedAnnotations === 1 ? \"\" : \"s\"}.`,\n );\n }\n if (skippedByMotivation) {\n warnings.push(\n `${reference.pageId}: skipped ${skippedByMotivation} annotation${skippedByMotivation === 1 ? \"\" : \"s\"} outside the selected motivation filter.`,\n );\n }\n\n if (!annotations.length) {\n skippedPages.push(\n toSkippedPage(\n reference,\n getEmptyPageReason(\n page.items.length,\n annotationItems.length,\n motivationFilter,\n ),\n ),\n );\n continue;\n }\n\n totalAnnotations += annotations.length;\n pages.push({\n reference,\n page,\n annotations,\n skippedAnnotations,\n skippedByMotivation,\n });\n }\n\n return {\n totalExternalPages: options.loadedPages.length,\n totalAnnotations,\n pages,\n skippedPages,\n warnings,\n errors: [],\n };\n}\n\nexport function writeExternalAnnotationPageInlinePlan(\n vault: any,\n plan: ExternalAnnotationPageInlinePlan,\n) {\n const entities: EntityBuckets = {\n AnnotationPage: {},\n Annotation: {},\n ContentResource: {},\n };\n const relationshipActions: any[] = [];\n const idFactory = createIdFactory(vault);\n const updatedCanvasIds = new Set<string>();\n let annotationsWritten = 0;\n\n for (const pageImport of plan.pages) {\n const { reference } = pageImport;\n const pageId = reference.pageId;\n const inlinePage = cloneJson(pageImport.page);\n\n inlinePage.id = pageId;\n inlinePage.type = \"AnnotationPage\";\n inlinePage.items = [];\n inlinePage[IS_EXTERNAL] = false;\n\n if (reference.existingPage?.[HAS_PART]) {\n inlinePage[HAS_PART] = cloneJson(reference.existingPage[HAS_PART]);\n }\n\n entities.AnnotationPage[pageId] = inlinePage;\n updatedCanvasIds.add(reference.canvasId);\n relationshipActions.push(\n modifyEntityField({\n id: pageId,\n type: \"AnnotationPage\",\n key: IS_EXTERNAL,\n value: false,\n }),\n );\n\n for (const sourceAnnotation of pageImport.annotations) {\n const annotation = cloneJson(sourceAnnotation);\n const annotationId = idFactory.preserveOrCreate(\n getResourceId(annotation),\n \"Annotation\",\n reference.canvasId,\n \"external-annotation\",\n );\n const bodyResult = normaliseAnnotationBodies(\n annotation.body,\n idFactory,\n reference.canvasId,\n annotationId,\n );\n\n annotation.id = annotationId;\n annotation.type = \"Annotation\";\n annotation.body = bodyResult.body;\n annotation.target = rewriteAnnotationTarget(\n annotation.target,\n reference.canvasId,\n );\n\n Object.assign(entities.ContentResource, bodyResult.entities);\n entities.Annotation[annotationId] = annotation;\n relationshipActions.push(\n addReference({\n id: pageId,\n type: \"AnnotationPage\",\n key: \"items\",\n reference: {\n id: annotationId,\n type: \"Annotation\",\n },\n }),\n );\n annotationsWritten += 1;\n }\n }\n\n const actions = [\n importEntities({\n entities: removeEmptyEntityBuckets(entities),\n }),\n ...relationshipActions,\n ];\n\n if (\n relationshipActions.length ||\n Object.values(entities).some((bucket) => Object.keys(bucket).length)\n ) {\n vault.dispatch(batchActions({ actions }));\n }\n\n return {\n totalExternalPages: plan.totalExternalPages,\n pagesInlined: plan.pages.length,\n canvasesUpdated: updatedCanvasIds.size,\n annotationsWritten,\n skippedPages: plan.skippedPages,\n warnings: plan.warnings,\n } satisfies ExternalAnnotationPageInlineResult;\n}\n\nexport function rewriteAnnotationTarget(\n target: unknown,\n canvasId: string,\n): unknown {\n if (Array.isArray(target)) {\n return target.map((item) => rewriteAnnotationTarget(item, canvasId));\n }\n\n if (typeof target === \"string\") {\n return withCanvasId(target, canvasId);\n }\n\n if (!target || typeof target !== \"object\") {\n return target;\n }\n\n const clone = cloneJson(target as any);\n\n if (typeof clone.source === \"string\") {\n clone.source = withCanvasId(clone.source, canvasId);\n return clone;\n }\n\n if (clone.source && typeof clone.source === \"object\") {\n clone.source = {\n ...clone.source,\n id: canvasId,\n type: clone.source.type || \"Canvas\",\n };\n return clone;\n }\n\n if (typeof clone.id === \"string\") {\n clone.id = withCanvasId(clone.id, canvasId);\n }\n\n return clone;\n}\n\nfunction isExternalAnnotationPage(page: any) {\n return !!page?.[IS_EXTERNAL];\n}\n\nfunction toSkippedPage(\n reference: ExternalAnnotationPageReference,\n reason: string,\n): SkippedExternalAnnotationPage {\n return {\n key: reference.key,\n canvasId: reference.canvasId,\n canvasLabel: reference.canvasLabel,\n pageId: reference.pageId,\n reason,\n };\n}\n\nfunction normaliseFetchedAnnotationPage(\n json: unknown,\n reference: ExternalAnnotationPageReference,\n): { page?: any; error: string; warning?: string } {\n if (!json || typeof json !== \"object\") {\n return { error: \"Fetched resource is not a JSON object.\" };\n }\n\n const resource = json as any;\n if (resource.type === \"AnnotationPage\") {\n return { page: resource, error: \"\" };\n }\n\n if (isPresentation2AnnotationList(resource)) {\n try {\n const upgraded = convertPresentation2(resource) as any;\n if (upgraded?.type === \"AnnotationPage\") {\n return {\n page: upgraded,\n error: \"\",\n warning: `${reference.pageId}: upgraded Presentation 2 sc:AnnotationList to AnnotationPage.`,\n };\n }\n\n return {\n error: `IIIF upgrade produced ${upgraded?.type || \"missing a type\"}, not AnnotationPage.`,\n };\n } catch (error) {\n return {\n error: `Unable to upgrade Presentation 2 sc:AnnotationList: ${error instanceof Error ? error.message : String(error)}`,\n };\n }\n }\n\n return {\n error: `Fetched resource is ${resource.type || resource[\"@type\"] || \"missing a type\"}, not AnnotationPage.`,\n };\n}\n\nfunction getEmptyPageReason(\n itemCount: number,\n annotationCount: number,\n motivationFilter: Set<string> | null,\n) {\n if (!itemCount) {\n return \"Fetched annotation page is empty.\";\n }\n\n if (!annotationCount) {\n return \"Fetched annotation page does not contain Annotation items.\";\n }\n\n if (motivationFilter?.size) {\n return `No annotations matched the selected motivation filter (${Array.from(motivationFilter).join(\", \")}).`;\n }\n\n return \"Fetched annotation page does not contain importable annotations.\";\n}\n\nfunction createMotivationFilter(values: string[] | undefined) {\n const normalised = dedupeStrings(\n (values || []).map(normaliseMotivation).filter(Boolean),\n );\n return normalised.length ? new Set(normalised) : null;\n}\n\nfunction annotationMatchesMotivationFilter(\n annotation: any,\n motivationFilter: Set<string> | null,\n) {\n if (!motivationFilter?.size) {\n return true;\n }\n\n return getAnnotationMotivations(annotation).some((motivation) =>\n motivationFilter.has(motivation),\n );\n}\n\nfunction getAnnotationMotivations(annotation: any) {\n return dedupeStrings(\n toArray(annotation?.motivation).map(normaliseMotivation).filter(Boolean),\n );\n}\n\nfunction normaliseMotivation(value: unknown) {\n if (typeof value !== \"string\") {\n return \"\";\n }\n\n const trimmed = value.trim().toLowerCase();\n const compact = trimmed.includes(\":\")\n ? trimmed.slice(trimmed.lastIndexOf(\":\") + 1)\n : trimmed;\n const slashIndex = compact.lastIndexOf(\"/\");\n const hashIndex = compact.lastIndexOf(\"#\");\n const separator = Math.max(slashIndex, hashIndex);\n return separator >= 0 ? compact.slice(separator + 1) : compact;\n}\n\nfunction isPresentation2AnnotationList(resource: any) {\n const type = resource?.[\"@type\"] || resource?.type;\n return type === \"sc:AnnotationList\" || type === \"AnnotationList\";\n}\n\nfunction normaliseAnnotationBodies(\n body: unknown,\n idFactory: ReturnType<typeof createIdFactory>,\n canvasId: string,\n annotationId: string,\n) {\n const bodyItems =\n typeof body === \"undefined\" || body === null ? [] : toArray(body);\n const entities: Record<string, any> = {};\n const normalised =\n bodyItems.length > 1 && bodyItems.every(isTextualBodyLike)\n ? [\n normaliseChoiceBody(\n {\n type: \"Choice\",\n items: bodyItems,\n },\n idFactory,\n canvasId,\n annotationId,\n \"body-choice\",\n entities,\n ),\n ]\n : bodyItems.map((item, index) =>\n normaliseBodyItem(\n item,\n idFactory,\n canvasId,\n annotationId,\n `body-${index + 1}`,\n entities,\n ),\n );\n\n return {\n body: normalised,\n entities,\n };\n}\n\nfunction normaliseBodyItem(\n item: unknown,\n idFactory: ReturnType<typeof createIdFactory>,\n canvasId: string,\n annotationId: string,\n seed: string,\n entities: Record<string, any>,\n) {\n if (isChoiceBody(item)) {\n return normaliseChoiceBody(\n item,\n idFactory,\n canvasId,\n annotationId,\n seed,\n entities,\n );\n }\n\n const bodyId = idFactory.preserveOrCreate(\n item && typeof item === \"object\" ? getResourceId(item) : undefined,\n \"ContentResource\",\n canvasId,\n `${annotationId}-${seed}`,\n );\n\n if (typeof item === \"string\") {\n entities[bodyId] = {\n id: bodyId,\n type: \"TextualBody\",\n format: \"text/plain\",\n value: item,\n };\n return { id: bodyId, type: \"ContentResource\" };\n }\n\n if (item && typeof item === \"object\") {\n const resource = normaliseImportedBodyResource(item);\n entities[bodyId] = {\n ...resource,\n id: bodyId,\n type: resource.type || \"ContentResource\",\n };\n return { id: bodyId, type: \"ContentResource\" };\n }\n\n entities[bodyId] = {\n id: bodyId,\n type: \"TextualBody\",\n format: \"text/plain\",\n value: String(item),\n };\n return { id: bodyId, type: \"ContentResource\" };\n}\n\nfunction normaliseChoiceBody(\n choice: any,\n idFactory: ReturnType<typeof createIdFactory>,\n canvasId: string,\n annotationId: string,\n seed: string,\n entities: Record<string, any>,\n) {\n const choiceId = idFactory.preserveOrCreate(\n getResourceId(choice),\n \"ContentResource\",\n canvasId,\n `${annotationId}-${seed}`,\n );\n const items = toArray(choice.items).map((item, index) =>\n normaliseBodyItem(\n item,\n idFactory,\n canvasId,\n annotationId,\n `${seed}-item-${index + 1}`,\n entities,\n ),\n );\n\n entities[choiceId] = {\n ...cloneJson(choice),\n id: choiceId,\n type: \"Choice\",\n items,\n };\n\n return { id: choiceId, type: \"ContentResource\" };\n}\n\nfunction normaliseImportedBodyResource(item: unknown) {\n const resource = cloneJson(item as any);\n\n if (\n typeof resource.chars === \"string\" &&\n typeof resource.value === \"undefined\"\n ) {\n resource.value = resource.chars;\n delete resource.chars;\n\n if (resource.type === \"Text\") {\n resource.type = \"TextualBody\";\n }\n }\n\n return resource;\n}\n\nfunction isChoiceBody(item: unknown) {\n return !!item && typeof item === \"object\" && (item as any).type === \"Choice\";\n}\n\nfunction isTextualBodyLike(item: unknown) {\n if (typeof item === \"string\") {\n return true;\n }\n\n if (!item || typeof item !== \"object\") {\n return false;\n }\n\n const type = (item as any).type;\n return type === \"TextualBody\" || type === \"Text\";\n}\n\nfunction createIdFactory(vault: any) {\n const used = new Set<string>();\n let counter = 0;\n\n function isInUse(id: string) {\n if (used.has(id)) {\n return true;\n }\n\n return RESOURCE_TYPES.some((type) => !!vault.get({ id, type }));\n }\n\n function create(canvasId: string, type: string, seed: string) {\n let id: string;\n do {\n counter += 1;\n id = `${trimTrailingSlash(canvasId)}/external-annotation-pages/${slugify(type)}/${slugify(seed)}-${counter}`;\n } while (isInUse(id));\n\n used.add(id);\n return id;\n }\n\n function preserveOrCreate(\n id: string | undefined,\n type: string,\n canvasId: string,\n seed: string,\n ) {\n if (id && !isInUse(id)) {\n used.add(id);\n return id;\n }\n\n return create(canvasId, type, seed);\n }\n\n return { create, preserveOrCreate };\n}\n\nfunction splitTargetId(value: string) {\n const hashIndex = value.indexOf(\"#\");\n return {\n sourceId: hashIndex >= 0 ? value.slice(0, hashIndex) : value,\n fragment: hashIndex >= 0 ? value.slice(hashIndex) : \"\",\n };\n}\n\nfunction withCanvasId(value: string, canvasId: string) {\n return `${canvasId}${splitTargetId(value).fragment}`;\n}\n\nfunction getResourceId(resource: unknown) {\n if (typeof resource === \"string\") return resource;\n if (!resource || typeof resource !== \"object\") return undefined;\n return typeof (resource as any).id === \"string\"\n ? (resource as any).id\n : typeof (resource as any)[\"@id\"] === \"string\"\n ? (resource as any)[\"@id\"]\n : undefined;\n}\n\nfunction getLabelTexts(label: unknown): string[] {\n if (!label) return [];\n if (typeof label === \"string\") return [label];\n if (Array.isArray(label))\n return label.filter((item): item is string => typeof item === \"string\");\n if (typeof label === \"object\") {\n return Object.values(label as Record<string, unknown>).flatMap(\n getLabelTexts,\n );\n }\n return [];\n}\n\nfunction getLabelText(label: unknown) {\n return getLabelTexts(label)[0] || \"\";\n}\n\nfunction dedupeStrings(values: string[]) {\n return Array.from(new Set(values.filter(Boolean)));\n}\n\nfunction toArray<T>(value: T | T[] | null | undefined): T[] {\n if (Array.isArray(value)) return value;\n if (typeof value === \"undefined\" || value === null) return [];\n return [value];\n}\n\nfunction cloneJson<T>(value: T): T {\n return JSON.parse(JSON.stringify(value));\n}\n\nfunction slugify(value: string) {\n return (\n value\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\")\n .slice(0, 80) || \"item\"\n );\n}\n\nfunction trimTrailingSlash(value: string) {\n return value.endsWith(\"/\") ? value.slice(0, -1) : value;\n}\n\nfunction removeEmptyEntityBuckets(entities: EntityBuckets) {\n return Object.fromEntries(\n Object.entries(entities).filter(([, value]) => Object.keys(value).length),\n );\n}\n","import { Modal } from \"@manifest-editor/components\";\nimport { useEffect, useState } from \"react\";\nimport type { ExternalAnnotationPageInlineResult } from \"./importer\";\n\nconst resultsEventName = \"@manifest-editor/annotations:bulk-import-results\";\n\ntype BulkAnnotationImportResultsEvent = {\n actionId: string;\n result?: ExternalAnnotationPageInlineResult;\n};\n\nexport function openBulkAnnotationImportResults(actionId: string, result: unknown) {\n window.dispatchEvent(\n new CustomEvent<BulkAnnotationImportResultsEvent>(resultsEventName, {\n detail: {\n actionId,\n result: result as ExternalAnnotationPageInlineResult | undefined,\n },\n }),\n );\n}\n\nexport function renderBulkAnnotationImportResults(actionId: string) {\n return <BulkAnnotationImportResultsModal actionId={actionId} />;\n}\n\nfunction BulkAnnotationImportResultsModal({ actionId }: { actionId: string }) {\n const [activeResult, setActiveResult] = useState<ExternalAnnotationPageInlineResult | null>(null);\n\n useEffect(() => {\n const listener = (event: Event) => {\n const detail = (event as CustomEvent<BulkAnnotationImportResultsEvent>).detail;\n if (detail?.actionId === actionId && detail.result) {\n setActiveResult(detail.result);\n }\n };\n\n window.addEventListener(resultsEventName, listener);\n return () => window.removeEventListener(resultsEventName, listener);\n }, [actionId]);\n\n if (!activeResult) {\n return null;\n }\n\n return (\n <Modal title=\"External annotation page import results\" onClose={() => setActiveResult(null)} className=\"max-w-3xl\">\n <div className=\"flex min-h-0 flex-col gap-4 p-4 text-sm text-zinc-700\">\n <div className=\"grid grid-cols-4 gap-2\">\n <ResultStat label=\"External pages\" value={activeResult.totalExternalPages} />\n <ResultStat label=\"Inlined pages\" value={activeResult.pagesInlined} />\n <ResultStat label=\"Canvases\" value={activeResult.canvasesUpdated} />\n <ResultStat label=\"Annotations\" value={activeResult.annotationsWritten} />\n </div>\n\n {activeResult.warnings.length ? (\n <div className=\"rounded border border-amber-200 bg-amber-50 p-3 text-amber-900\">\n {activeResult.warnings.map((warning) => (\n <div key={warning}>{warning}</div>\n ))}\n </div>\n ) : null}\n\n {activeResult.skippedPages.length ? (\n <div className=\"rounded border border-zinc-200\">\n <div className=\"border-b border-zinc-200 bg-zinc-50 px-3 py-2 font-medium\">Skipped external pages</div>\n <div className=\"max-h-64 overflow-auto\">\n {activeResult.skippedPages.map((item) => (\n <div key={item.key} className=\"grid gap-1 border-b border-zinc-100 px-3 py-2 last:border-0\">\n <div className=\"truncate font-medium text-zinc-900\">{item.pageId}</div>\n <div className=\"truncate text-zinc-500\">{item.canvasLabel}</div>\n <div className=\"text-zinc-500\">{item.reason}</div>\n </div>\n ))}\n </div>\n </div>\n ) : null}\n </div>\n </Modal>\n );\n}\n\nfunction ResultStat({ label, value }: { label: string; value: number }) {\n return (\n <div className=\"rounded border border-zinc-200 bg-zinc-50 p-3\">\n <div className=\"text-xl font-semibold text-zinc-900\">{value}</div>\n <div className=\"text-xs uppercase tracking-wide text-zinc-500\">{label}</div>\n </div>\n );\n}\n","import {\n FLAG_TAG,\n type BackgroundActionDefinition,\n type BackgroundActionRunContext,\n type ManifestEditorTag,\n} from \"@manifest-editor/shell\";\nimport { BULK_ANNOTATION_IMPORT_ACTION_ID } from \"../constants\";\nimport {\n getDefaultRunOptions,\n renderBulkAnnotationImportConfigModal,\n requestBulkAnnotationImportConfig,\n type BulkAnnotationImportRunOptions,\n type BulkAnnotationImportTagOption,\n} from \"./config-modal\";\nimport {\n createExternalAnnotationPageInlinePlan,\n findExternalAnnotationPageReferences,\n writeExternalAnnotationPageInlinePlan,\n type ExternalAnnotationPageInlineResult,\n type ExternalAnnotationPageReference,\n type LoadedExternalAnnotationPage,\n} from \"./importer\";\nimport {\n openBulkAnnotationImportResults,\n renderBulkAnnotationImportResults,\n} from \"./results\";\n\nconst runOptions = new Map<\n string,\n {\n references: ExternalAnnotationPageReference[];\n options: BulkAnnotationImportRunOptions;\n }\n>();\n\nexport type BulkAnnotationImportActionDependencies = {\n fetchPage?: (\n pageId: string,\n reference: ExternalAnnotationPageReference,\n ctx: BackgroundActionRunContext,\n ) => Promise<unknown>;\n requestConfig?: (\n ctx: BackgroundActionRunContext,\n references: ExternalAnnotationPageReference[],\n defaults: BulkAnnotationImportRunOptions,\n ) => Promise<BulkAnnotationImportRunOptions | false>;\n};\n\nexport function createBulkAnnotationImportBackgroundAction(\n dependencies: BulkAnnotationImportActionDependencies = {},\n): BackgroundActionDefinition {\n const fetchPage = dependencies.fetchPage || defaultFetchPage;\n const requestConfig = dependencies.requestConfig || defaultRequestConfig;\n\n return {\n id: BULK_ANNOTATION_IMPORT_ACTION_ID,\n label: \"Bulk Annotation Page Importer\",\n summary:\n \"Load external Canvas annotation pages and make them editable inline\",\n section: \"Annotations\",\n order: 10,\n resourceTypes: [\"Manifest\"],\n resumable: false,\n render: (ctx) => (\n <>\n {renderBulkAnnotationImportConfigModal(ctx.definition.id)}\n {renderBulkAnnotationImportResults(ctx.definition.id)}\n </>\n ),\n onResults: (ctx) =>\n openBulkAnnotationImportResults(ctx.definition.id, ctx.instance?.result),\n supports: (ctx) =>\n findExternalAnnotationPageReferences(ctx.vault, getManifestCanvases(ctx))\n .length > 0,\n prepare: async (ctx) => {\n const references = findExternalAnnotationPageReferences(\n ctx.vault,\n getManifestCanvases(ctx),\n );\n if (!references.length) {\n return false;\n }\n\n const options = await requestConfig(\n ctx,\n references,\n getDefaultRunOptions(),\n );\n if (options === false) {\n return false;\n }\n\n const selectedReferences = selectReferences(ctx, references, options);\n if (!selectedReferences.length) {\n return false;\n }\n\n runOptions.set(ctx.instanceKey, {\n references: selectedReferences,\n options,\n });\n return true;\n },\n run: async (ctx) => {\n const prepared = runOptions.get(ctx.instanceKey);\n const options = prepared?.options || getDefaultRunOptions();\n const references =\n prepared?.references ||\n selectReferences(\n ctx,\n findExternalAnnotationPageReferences(\n ctx.vault,\n getManifestCanvases(ctx),\n ),\n options,\n );\n\n try {\n ctx.setActionLabel(\"Importing external annotation pages\");\n ctx.setActionProgress({\n current: 0,\n total: Math.max(references.length, 1),\n label: \"Loading external annotation pages\",\n });\n\n if (!references.length) {\n ctx.setActionStatus(\"running\", \"No external annotation pages found\");\n return createEmptyResult();\n }\n\n const loadedPages: LoadedExternalAnnotationPage[] = [];\n for (const [index, reference] of references.entries()) {\n throwIfAborted(ctx.signal);\n ctx.setActionStatus(\n \"running\",\n `Loading ${index + 1}/${references.length}`,\n );\n ctx.appendActionLog(\"Loading external annotation page\", \"info\", {\n canvasId: reference.canvasId,\n pageId: reference.pageId,\n });\n\n try {\n const json = await fetchPage(reference.pageId, reference, ctx);\n loadedPages.push({ reference, json });\n } catch (error) {\n const message = getErrorMessage(error);\n loadedPages.push({ reference, error: message });\n ctx.appendActionLog(\n \"Failed to load external annotation page\",\n \"warn\",\n {\n canvasId: reference.canvasId,\n pageId: reference.pageId,\n reason: message,\n },\n );\n }\n\n ctx.setActionProgress({\n current: index + 1,\n total: references.length,\n label: \"Loading external annotation pages\",\n });\n }\n\n const plan = createExternalAnnotationPageInlinePlan({\n loadedPages,\n motivationFilter:\n options.motivationMode === \"selected\"\n ? options.motivations\n : undefined,\n });\n if (plan.errors.length) {\n throw new Error(\n plan.errors[0] || \"External annotation page import failed.\",\n );\n }\n\n ctx.setActionStatus(\"running\", \"Writing inline annotation pages\");\n ctx.setActionProgress({\n current: 0,\n total: Math.max(plan.totalAnnotations, plan.pages.length, 1),\n label: \"Writing inline annotations\",\n });\n\n const result = writeExternalAnnotationPageInlinePlan(ctx.vault, plan);\n ctx.appendActionLog(\n \"External annotation page import complete\",\n \"info\",\n {\n pages: result.pagesInlined,\n annotations: result.annotationsWritten,\n skipped: result.skippedPages.length,\n },\n );\n ctx.setActionStatus(\n \"running\",\n `Imported ${result.pagesInlined}/${result.totalExternalPages} external pages`,\n );\n ctx.setActionProgress({\n current: Math.max(result.annotationsWritten, result.pagesInlined),\n total: Math.max(result.annotationsWritten, result.pagesInlined, 1),\n label: \"Import complete\",\n });\n return result;\n } finally {\n runOptions.delete(ctx.instanceKey);\n }\n },\n };\n}\n\nasync function defaultFetchPage(\n pageId: string,\n _reference: ExternalAnnotationPageReference,\n ctx: BackgroundActionRunContext,\n) {\n const response = await fetch(pageId, {\n signal: ctx.signal,\n headers: {\n Accept: \"application/ld+json, application/json;q=0.9, */*;q=0.1\",\n },\n });\n\n if (!response.ok) {\n throw new Error(`Unable to fetch ${pageId} (${response.status}).`);\n }\n\n return response.json();\n}\n\nasync function defaultRequestConfig(\n ctx: BackgroundActionRunContext,\n references: ExternalAnnotationPageReference[],\n defaults: BulkAnnotationImportRunOptions,\n) {\n return requestBulkAnnotationImportConfig({\n actionId: ctx.definition.id,\n instanceKey: ctx.instanceKey,\n totalExternalPages: references.length,\n tags: getCanvasTagOptions(ctx, references),\n defaults,\n signal: ctx.signal,\n });\n}\n\nfunction getManifestCanvases(\n ctx: BackgroundActionRunContext | { vault: any; target: unknown },\n) {\n const manifest = ctx.vault.get(ctx.target as any) as any;\n return manifest?.items\n ? (ctx.vault.get(manifest.items) || []).filter(Boolean)\n : [];\n}\n\nfunction selectReferences(\n ctx: BackgroundActionRunContext,\n references: ExternalAnnotationPageReference[],\n options: BulkAnnotationImportRunOptions,\n) {\n if (options.scope !== \"tag\" || !options.tagKey) {\n return references;\n }\n\n const selectedTag = parseTagKey(options.tagKey);\n if (!selectedTag) {\n return [];\n }\n\n return references.filter((reference) =>\n ctx.tags.hasTag(\n { id: reference.canvasId, type: \"Canvas\" },\n selectedTag.type,\n selectedTag.id,\n ),\n );\n}\n\nfunction getCanvasTagOptions(\n ctx: BackgroundActionRunContext,\n references: ExternalAnnotationPageReference[],\n): BulkAnnotationImportTagOption[] {\n const tags = new Map<\n string,\n BulkAnnotationImportTagOption & ManifestEditorTag\n >();\n const pageCountByCanvas = new Map<string, number>();\n\n tags.set(getTagKey(FLAG_TAG), {\n ...FLAG_TAG,\n key: getTagKey(FLAG_TAG),\n canvasCount: 0,\n externalPageCount: 0,\n });\n\n for (const reference of references) {\n pageCountByCanvas.set(\n reference.canvasId,\n (pageCountByCanvas.get(reference.canvasId) || 0) + 1,\n );\n }\n\n for (const [canvasId, externalPageCount] of pageCountByCanvas) {\n for (const tag of ctx.tags.getTags({ id: canvasId, type: \"Canvas\" })) {\n const key = getTagKey(tag);\n const existing = tags.get(key);\n\n if (existing) {\n existing.canvasCount += 1;\n existing.externalPageCount += externalPageCount;\n } else {\n tags.set(key, {\n ...tag,\n key,\n canvasCount: 1,\n externalPageCount,\n });\n }\n }\n }\n\n return Array.from(tags.values()).sort((a, b) => {\n if (a.type === FLAG_TAG.type && a.id === FLAG_TAG.id) return -1;\n if (b.type === FLAG_TAG.type && b.id === FLAG_TAG.id) return 1;\n return (\n a.label.localeCompare(b.label) ||\n a.type.localeCompare(b.type) ||\n a.id.localeCompare(b.id)\n );\n });\n}\n\nfunction getTagKey(tag: Pick<ManifestEditorTag, \"type\" | \"id\">) {\n return `${tag.type}:${tag.id}`;\n}\n\nfunction parseTagKey(key: string): { type: string; id: string } | null {\n const separator = key.indexOf(\":\");\n if (separator === -1) {\n return null;\n }\n\n return {\n type: key.slice(0, separator),\n id: key.slice(separator + 1),\n };\n}\n\nfunction createEmptyResult(): ExternalAnnotationPageInlineResult {\n return {\n totalExternalPages: 0,\n pagesInlined: 0,\n canvasesUpdated: 0,\n annotationsWritten: 0,\n skippedPages: [],\n warnings: [],\n };\n}\n\nfunction throwIfAborted(signal: AbortSignal) {\n if (signal.aborted) {\n throw new DOMException(\"Aborted\", \"AbortError\");\n }\n}\n\nfunction getErrorMessage(error: unknown) {\n return error instanceof Error\n ? error.message\n : String(error || \"Unknown error\");\n}\n","import { useInStack } from \"@manifest-editor/editors\";\nimport {\n type BackgroundPanel,\n useLayoutActions,\n useLayoutMode,\n useLayoutState,\n} from \"@manifest-editor/shell\";\nimport { useEffect, useRef, useState } from \"react\";\nimport { useManifest } from \"react-iiif-vault\";\nimport { ANNOTATIONS_LEFT_PANEL_ID } from \"./constants\";\n\nconst RANGES_PANEL_ID = \"@manifest-editor/ranges-listing\";\n\nexport const annotationRoutingBackground: BackgroundPanel = {\n id: \"@manifest-editor/annotations-routing\",\n label: \"Annotation routing\",\n render: () => <AnnotationRoutingBackground />,\n};\n\nfunction AnnotationRoutingBackground() {\n const manifest = useManifest();\n const canvas = useInStack(\"Canvas\");\n const layoutMode = useLayoutMode();\n const { leftPanel, rightPanel } = useLayoutState();\n const { edit, open, rightPanel: rightPanelActions } = useLayoutActions();\n const lastCanvas = useRef<string | null>(null);\n const [closedRightPanel, setClosedRightPanel] = useState(false);\n\n useEffect(() => {\n const canvasId = canvas?.resource?.source?.id;\n if (canvasId) {\n lastCanvas.current = canvasId;\n }\n }, [canvas?.resource?.source?.id]);\n\n useEffect(() => {\n if (leftPanel.current === ANNOTATIONS_LEFT_PANEL_ID) {\n const firstCanvas = lastCanvas.current || manifest?.items?.[0]?.id;\n if (firstCanvas) {\n open({ id: \"current-canvas\" });\n edit({ id: firstCanvas, type: \"Canvas\" });\n }\n\n if (layoutMode === \"focused\") {\n return;\n }\n\n if (rightPanel.open) {\n rightPanelActions.close();\n setClosedRightPanel(true);\n }\n return;\n }\n\n if (\n closedRightPanel &&\n !rightPanel.open &&\n leftPanel.current !== RANGES_PANEL_ID\n ) {\n rightPanelActions.open();\n setClosedRightPanel(false);\n }\n }, [leftPanel.current, layoutMode]);\n\n return null;\n}\n","import type { AnnotationPanel, BackgroundActionDefinition, BackgroundPanel, LayoutPanel, PluginMetadata } from \"@manifest-editor/shell\";\nimport { annotationsPanel } from \"./annotation-panel\";\nimport { canvasAnnotations } from \"./canvas-annotations\";\nimport { ANNOTATIONS_PLUGIN_ID } from \"./constants\";\nimport { createBulkAnnotationImportBackgroundAction } from \"./importer/background-action\";\nimport { annotationRoutingBackground } from \"./routing-background\";\n\nexport default {\n id: ANNOTATIONS_PLUGIN_ID,\n label: \"Annotations\",\n description: \"Create, view, and inline external supplemental canvas annotation pages.\",\n author: \"Digirati\",\n official: true,\n defaultEnabled: true,\n tags: [\"annotations\", \"iiif\", \"external-pages\"],\n supports: {\n apps: [\"manifest-editor\"],\n projectTypes: [\"Manifest\"],\n },\n} satisfies PluginMetadata;\n\nexport const leftPanels: LayoutPanel[] = [annotationsPanel];\nexport const annotations: AnnotationPanel[] = [canvasAnnotations];\nexport const background: BackgroundPanel[] = [annotationRoutingBackground];\nexport const backgroundActions: BackgroundActionDefinition[] = [createBulkAnnotationImportBackgroundAction()];\n\nexport * from \"./constants\";\nexport * from \"./importer/background-action\";\nexport * from \"./importer/importer\";\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@manifest-editor/annotations",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.2.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"bugs": "https://github.com/digirati-co-uk/iiif-manifest-editor/issues",
|
|
6
6
|
"repository": {
|
|
@@ -37,23 +37,23 @@
|
|
|
37
37
|
"prepack": "tsdown --clean"
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
|
-
"@
|
|
41
|
-
"@iiif/
|
|
42
|
-
"@
|
|
43
|
-
"@manifest-editor/
|
|
44
|
-
"@manifest-editor/
|
|
45
|
-
"
|
|
46
|
-
"react
|
|
40
|
+
"@atlas-viewer/atlas": "3.2.3",
|
|
41
|
+
"@iiif/helpers": "1.6.1",
|
|
42
|
+
"@iiif/parser": "2.2.14",
|
|
43
|
+
"@manifest-editor/components": "2.2.0",
|
|
44
|
+
"@manifest-editor/editors": "2.2.0",
|
|
45
|
+
"@manifest-editor/shell": "2.2.0",
|
|
46
|
+
"react": "19.2.8",
|
|
47
|
+
"react-iiif-vault": "2.0.18",
|
|
47
48
|
"zustand": "4.5.2"
|
|
48
49
|
},
|
|
49
50
|
"devDependencies": {
|
|
50
|
-
"@
|
|
51
|
-
"
|
|
52
|
-
"
|
|
53
|
-
"vitest": "v3.0.9"
|
|
51
|
+
"@types/react": "19.2.18",
|
|
52
|
+
"tsdown": "0.22.14",
|
|
53
|
+
"vitest": "4.1.10"
|
|
54
54
|
},
|
|
55
55
|
"publishConfig": {
|
|
56
56
|
"access": "public"
|
|
57
57
|
},
|
|
58
|
-
"gitHead": "
|
|
58
|
+
"gitHead": "9ee7ce32bf7728205e22d852fb80061b86067471"
|
|
59
59
|
}
|