@popmelt.com/core 0.23.0 → 0.24.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.
Files changed (38) hide show
  1. package/README.md +30 -0
  2. package/claude-plugin/.claude-plugin/plugin.json +1 -1
  3. package/claude-plugin/skills/popmelt-core/SKILL.md +1 -0
  4. package/codex-plugin/.codex-plugin/plugin.json +1 -1
  5. package/codex-plugin/skills/popmelt-core/SKILL.md +1 -0
  6. package/dist/ParticipantRuntime-PTBGXKSH.mjs +139 -0
  7. package/dist/PreviewRuntime-2SCFCGWC.mjs +2 -0
  8. package/dist/adapter-react-three-fiber.mjs +1 -1
  9. package/dist/bridge-entry.mjs +85 -83
  10. package/dist/browser-runtime-3Z4U66AP.mjs +2 -0
  11. package/dist/browser.d.mts +2 -1
  12. package/dist/browser.mjs +1 -1
  13. package/dist/chunk-6URDGUIL.mjs +2 -0
  14. package/dist/chunk-BYLH3WFB.mjs +2 -0
  15. package/dist/chunk-C4ONFAGF.mjs +399 -0
  16. package/dist/{chunk-4IUZX7YN.mjs → chunk-DHAOAIKK.mjs} +1 -1
  17. package/dist/{chunk-EXYZQ76K.mjs → chunk-EUDGPGCQ.mjs} +1 -1
  18. package/dist/chunk-EX63NVDN.mjs +2 -0
  19. package/dist/chunk-J3UIBBU2.mjs +1 -1
  20. package/dist/chunk-M3HCNQ4T.mjs +250 -0
  21. package/dist/chunk-N2ZEZCHO.mjs +1 -1
  22. package/dist/cli.mjs +102 -98
  23. package/dist/index.d.mts +3 -3
  24. package/dist/index.mjs +1 -1
  25. package/dist/media.mjs +1 -1
  26. package/dist/{options-5yRxW1AX.d.mts → participantBootstrap-Dqu2h47B.d.mts} +22 -1
  27. package/dist/plugin-astro.d.mts +2 -0
  28. package/dist/plugin-astro.mjs +3 -3
  29. package/dist/plugin-nuxt.d.mts +3 -1
  30. package/dist/plugin-nuxt.mjs +2 -1
  31. package/dist/plugin-vite.mjs +1 -1
  32. package/dist/server-T4EMCHVP.mjs +228 -0
  33. package/dist/server.d.mts +121 -1
  34. package/dist/server.mjs +95 -84
  35. package/package.json +1 -1
  36. package/dist/browser-runtime-FWYFRPVT.mjs +0 -2
  37. package/dist/chunk-VHUJQWVP.mjs +0 -453
  38. package/dist/server-7AUQAYVY.mjs +0 -217
@@ -1,2 +1,2 @@
1
1
  "use client";
2
- var S=(n,e=0,i=1)=>Math.min(i,Math.max(e,n));function ne(n){let{width:e,height:i}=n.rect,t=Math.max(1,n.naturalWidth),s=Math.max(1,n.naturalHeight),r=Math.min(e/t,i/s),o=Math.max(e/t,i/s);switch(n.objectFit){case"contain":return{width:t*r,height:s*r};case"cover":return{width:t*o,height:s*o};case"none":return{width:t,height:s};case"scale-down":{let a=Math.min(1,r);return{width:t*a,height:s*a}}default:return{width:e,height:i}}}function _(n,e){let i=n.trim().toLowerCase();if(i.endsWith("%")){let t=Number.parseFloat(i);return Number.isFinite(t)?e*(t/100):0}if(i.endsWith("px")){let t=Number.parseFloat(i);return Number.isFinite(t)?t:0}return i==="center"?e/2:i==="right"||i==="bottom"?e:0}function re(n,e,i){let t=n.objectPosition.trim().split(/\s+/),s=t[0]||"50%",r=t[1]||"50%";return{x:_(s,n.rect.width-e),y:_(r,n.rect.height-i)}}function E(n){let e=n.getBoundingClientRect();if(e.width<=0||e.height<=0||n.naturalWidth<=0||n.naturalHeight<=0)return null;let i=n.ownerDocument.defaultView?.getComputedStyle(n)??getComputedStyle(n),t={rect:e,naturalWidth:n.naturalWidth,naturalHeight:n.naturalHeight,objectFit:i.objectFit||"fill",objectPosition:i.objectPosition||"50% 50%"},s=ne(t);return{layout:t,rendered:s,position:re(t,s.width,s.height)}}function H(n,e){let i=E(n);if(!i)return null;let{layout:t,rendered:s,position:r}=i;if(e.x<t.rect.left||e.x>t.rect.left+t.rect.width||e.y<t.rect.top||e.y>t.rect.top+t.rect.height)return null;let o=(e.x-t.rect.left-r.x)/s.width,a=(e.y-t.rect.top-r.y)/s.height;return o>=0&&o<=1&&a>=0&&a<=1?{x:o,y:a}:null}function q(n,e){let i=E(n);if(!i)return null;let{layout:t,rendered:s,position:r}=i,o=(e.left-t.rect.left-r.x)/s.width,a=(e.top-t.rect.top-r.y)/s.height,l=(e.left+e.width-t.rect.left-r.x)/s.width,d=(e.top+e.height-t.rect.top-r.y)/s.height,c=S(Math.min(o,l)),h=S(Math.min(a,d)),u=S(Math.max(o,l)),m=S(Math.max(a,d));return u<=c||m<=h?null:{left:c,top:h,width:u-c,height:m-h}}function K(n,e){if(![e.left,e.top,e.width,e.height].every(Number.isFinite))return null;let i=E(n);if(!i)return null;let{layout:t,rendered:s,position:r}=i,{rect:o}=t,a=o.left+r.x+S(e.left)*s.width,l=o.top+r.y+S(e.top)*s.height,d=o.left+r.x+S(e.left+Math.max(0,e.width))*s.width,c=o.top+r.y+S(e.top+Math.max(0,e.height))*s.height,h=Math.max(o.left,a),u=Math.max(o.top,l),m=Math.min(o.left+o.width,d),g=Math.min(o.top+o.height,c);return m<=h||g<=u?null:{left:h,top:u,width:m-h,height:g-u}}var oe="popmelt:see:v1";function R(n){if(!n||typeof n!="object")return!1;let e=n;return["left","top","width","height"].every(i=>typeof e[i]=="number"&&Number.isFinite(e[i]))}function ae(n){if(!n||typeof n!="object")return!1;let e=n;return typeof e.id=="string"&&typeof e.label=="string"&&typeof e.score=="number"&&(e.origin==="detected"||e.origin==="manual")&&R(e.box)&&(e.detectedBox===void 0||R(e.detectedBox))}function de(n){if(!n||typeof n!="object")return!1;let e=n;return typeof e.detectedLabel=="string"&&R(e.detectedBox)}function U(n){if(!n||typeof n!="object")return!1;let e=n;return e.schemaVersion===1&&typeof e.source=="string"&&typeof e.imageHash=="string"&&typeof e.inferenceKey=="string"&&typeof e.dedupeKey=="string"&&typeof e.updatedAt=="number"&&Array.isArray(e.subjects)&&e.subjects.every(ae)&&(e.suppressions===void 0||Array.isArray(e.suppressions)&&e.suppressions.every(de))}function Ae(n={}){let e=n.namespace??oe,i=()=>n.storage??window.localStorage,t=a=>`${e}:${a}`,s=a=>`${t(a)}:history`,r=a=>{try{let l=i().getItem(t(a));if(!l)return null;let d=JSON.parse(l);return U(d)?d:null}catch{return null}},o=a=>{try{let l=i().getItem(s(a));if(!l)return[];let d=JSON.parse(l);return Array.isArray(d)?d.filter(U).slice(0,10):[]}catch{return[]}};return{load:r,save(a,l){let d=r(a);if(d&&d.imageHash!==l.imageHash){let c=o(a).filter(h=>h.imageHash!==d.imageHash||h.updatedAt!==d.updatedAt);i().setItem(s(a),JSON.stringify([d,...c].slice(0,10)))}i().setItem(t(a),JSON.stringify(l))},remove(a){i().removeItem(t(a)),i().removeItem(s(a))},loadHistory:o}}function Le(){let n=new Map,e=new Map;return{load:i=>n.get(i)??null,save:(i,t)=>{let s=n.get(i);if(s&&s.imageHash!==t.imageHash){let r=e.get(i)??[];e.set(i,[s,...r.filter(o=>o.imageHash!==s.imageHash||o.updatedAt!==s.updatedAt)].slice(0,10))}n.set(i,t)},remove:i=>{n.delete(i),e.delete(i)},loadHistory:i=>e.get(i)??[]}}function Q(n){return{label:n.label,score:n.score,box:{...n.box}}}var B="img";function P(n){let e=2166136261;for(let i=0;i<n.length;i+=1)e^=n.charCodeAt(i),e=Math.imul(e,16777619);return(e>>>0).toString(36)}function O(n){return new URL(y(n),n.ownerDocument.baseURI).href}async function ce(n){let e=O(n);try{let i=await fetch(e,{cache:"force-cache",credentials:"same-origin"});if(!i.ok)throw new Error(`Unable to hash image (${i.status})`);let t=await i.arrayBuffer();if(!globalThis.crypto?.subtle)throw new Error("SubtleCrypto unavailable");let s=await globalThis.crypto.subtle.digest("SHA-256",t);return Array.from(new Uint8Array(s),r=>r.toString(16).padStart(2,"0")).join("")}catch{return`source:${P(e)}:${n.naturalWidth}x${n.naturalHeight}`}}function y(n){return n.currentSrc||n.src||n.getAttribute("src")||""}function le(n){return n.complete&&n.naturalWidth>0&&n.naturalHeight>0?Promise.resolve():new Promise((e,i)=>{let t=()=>{r(),e()},s=()=>{r(),i(new Error(`Unable to load image: ${y(n)}`))},r=()=>{n.removeEventListener("load",t),n.removeEventListener("error",s)};n.addEventListener("load",t,{once:!0}),n.addEventListener("error",s,{once:!0})})}function ue(n,e){return{id:e.id,image:n,detection:Q(e),detectedLabel:e.detectedLabel,detectedBox:e.detectedBox?{...e.detectedBox}:void 0,boundsOverridden:e.boundsOverridden,manual:e.origin==="manual"}}function he(n){return{id:n.id,label:n.detection.label,detectedLabel:n.detectedLabel,score:n.detection.score,box:{...n.detection.box},detectedBox:n.detectedBox?{...n.detectedBox}:void 0,origin:n.manual?"manual":"detected",boundsOverridden:n.boundsOverridden}}function me(n){return n.origin==="manual"||n.boundsOverridden===!0||!!(n.detectedLabel&&n.label!==n.detectedLabel)}function pe(n,e){return e.x>=n.left&&e.x<=n.left+n.width&&e.y>=n.top&&e.y<=n.top+n.height}var F=class{constructor(e={}){this.options=e;this.surfaceKind="image";this.records=new Map;this.imageKeys=new Map;this.analyzedSources=new WeakMap;this.pending=new WeakMap;this.analysisMetadata=new WeakMap;this.suppressions=new WeakMap;this.writeChains=new WeakMap;this.pendingWrites=new Set;this.refreshQueued=!1;this.destroyed=!1;this.manualSequence=0;this.id=e.id??"see:image",this.readyPromise=this.refresh();let i=e.root??document;this.observer=e.observe!==!1&&typeof MutationObserver<"u"?new MutationObserver(()=>this.queueRefresh()):null,this.observer?.observe(i,{childList:!0,subtree:!0,attributes:!0,attributeFilter:["src","srcset","sizes"]})}whenReady(){return this.readyPromise}listSubjects(){let e=[];for(let i of this.records.keys()){let t=this.resolve(i);t&&e.push(t)}return e}async refresh(){if(this.destroyed)return;let e=this.options.root??document,i=this.options.selector??B,t=new Set;e instanceof HTMLImageElement&&e.matches(i)&&t.add(e);for(let s of e.querySelectorAll(i))s instanceof HTMLImageElement&&t.add(s);for(let s of this.imageKeys.keys())(!t.has(s)||!s.isConnected)&&this.removeImage(s);if(this.options.recognition)for(let s of t)await this.analyze(s);else await Promise.all(Array.from(t,s=>this.analyze(s)))}hitTest(e){let i=null;for(let t of this.records.keys()){let s=this.resolve(t),r=this.records.get(t);if(!s||!r||!pe(s.bounds,e))continue;let o=s.bounds.width*s.bounds.height;(!i||o<i.area||o===i.area&&r.detection.score>i.score)&&(i={subject:s,area:o,score:r.detection.score})}return i?.subject??null}resolve(e){let i=this.records.get(e);if(!i||!i.image.isConnected)return null;let t=K(i.image,i.detection.box);if(!t)return null;let s=i.image.getBoundingClientRect(),r=Math.round(i.detection.score*1e3)/1e3;return{key:e,label:i.detection.label,sourceElement:i.image,imageObject:this.imageObjectContext(i),bounds:t,surfaceBounds:{left:s.left,top:s.top,width:s.width,height:s.height},context:`${i.detection.label} ${i.manual?"labelled":"detected"} in ${i.image.alt||"image"}`,data:{kind:"image-object",label:i.detection.label,origin:i.manual?"manual":"detected",...i.detectedLabel?{detectedLabel:i.detectedLabel}:{},score:String(r),imageSrc:y(i.image)}}}restoreSubject(e,i){if(this.records.has(e))return this.resolve(e);let t=i.imageObject;if(!t)return null;let s=i.sourceElement?.dataAttributes,r=s?.["data-popmelt-media-id"]??s?.["data-popmelt-see-id"],o=this.matchingImages().find(p=>{let f=y(p),b=this.imageIdentity(p,f);return!(!e.startsWith(`${b}:`)||r&&b!==r)});if(!o)return null;let a=this.imageIdentity(o,y(o)),l=e.slice(a.length+1),d={left:t.normalizedBox.x,top:t.normalizedBox.y,width:t.normalizedBox.width,height:t.normalizedBox.height};if(!l||!Object.values(d).every(p=>Number.isFinite(p)&&p>=0&&p<=1))return null;let c=i.dataAttributes,h=i.subjectLabel??c?.label??i.textContent;if(!h)return null;let u=Number(c?.score),m=c?.origin==="manual";this.records.set(e,{id:l,image:o,detection:{label:h,score:Number.isFinite(u)?u:1,box:d},detectedLabel:c?.detectedLabel,detectedBox:m?void 0:{...d},boundsOverridden:!0,manual:m});let g=this.imageKeys.get(o)??new Set;if(g.add(e),this.imageKeys.set(o,g),!this.analysisMetadata.has(o)){let p=O(o);this.analysisMetadata.set(o,{storeKey:`${this.id}:${a}`,source:p,imageHash:`recovered:${P(p)}`,inferenceKey:"",dedupeKey:""}),this.suppressions.set(o,[])}return this.persistImage(o),this.resolve(e)}imageObjectContext(e){let{image:i,detection:{box:t}}=e;return{src:y(i),alt:i.alt,width:i.naturalWidth,height:i.naturalHeight,normalizedBox:{x:t.left,y:t.top,width:t.width,height:t.height},box:{x:t.left*i.naturalWidth,y:t.top*i.naturalHeight,width:t.width*i.naturalWidth,height:t.height*i.naturalHeight}}}async captureSubject(e){let i=this.records.get(e);if(!i?.image.isConnected||!i.image.complete)return null;let{box:t}=this.imageObjectContext(i);if(t.width<=0||t.height<=0)return null;let s=Math.min(1,1024/Math.max(t.width,t.height)),r=document.createElement("canvas");r.width=Math.max(1,Math.round(t.width*s)),r.height=Math.max(1,Math.round(t.height*s));let o=r.getContext("2d");return o?(o.drawImage(i.image,t.x,t.y,t.width,t.height,0,0,r.width,r.height),new Promise((a,l)=>{try{r.toBlob(a,"image/webp",.95)}catch(d){l(d)}})):null}beginCreate(e){let i=this.matchingImages();for(let t=i.length-1;t>=0;t-=1){let s=i[t];if(!s)continue;let r=H(s,e);if(!r)continue;let o=y(s),a=this.imageIdentity(s,o),l=`manual:${this.newObjectId()}`,d=`${a}:${l}`,c={label:"object",score:1,box:{left:r.x,top:r.y,width:0,height:0}},h=!1,u=!1,m=()=>{if(u)return;u=!0,this.records.set(d,{id:l,image:s,detection:c,manual:!0});let g=this.imageKeys.get(s)??new Set;g.add(d),this.imageKeys.set(s,g)};return{key:d,update:g=>{if(h)return null;m();let p=this.clampedImagePoint(s,g);return p?(c.box={left:Math.min(r.x,p.x),top:Math.min(r.y,p.y),width:Math.abs(p.x-r.x),height:Math.abs(p.y-r.y)},this.resolve(d)):this.resolve(d)},commit:()=>h?null:(m(),this.persistImage(s),this.resolve(d)),cancel:()=>{h||(h=!0,u&&this.removeSubject(d))}}}return null}renameSubject(e,i){let t=this.records.get(e),s=i.trim();return!t||!s?null:(!t.manual&&!t.detectedLabel&&(t.detectedLabel=t.detection.label),t.detection.label=s,this.persistImage(t.image),this.resolve(e))}updateSubjectBounds(e,i){let t=this.records.get(e);if(!t)return null;let s=q(t.image,i);return s?(t.detection.box=s,t.boundsOverridden=!0,this.persistImage(t.image),this.resolve(e)):null}removeSubject(e){let i=this.records.get(e);if(!i)return;if(!i.manual){let s=this.suppressions.get(i.image)??[];s.push({detectedLabel:i.detectedLabel??i.detection.label,detectedBox:{...i.detectedBox??i.detection.box}}),this.suppressions.set(i.image,s)}this.records.delete(e);let t=this.imageKeys.get(i.image);t?.delete(e),t?.size===0&&this.imageKeys.delete(i.image),this.persistImage(i.image)}async destroy(){this.destroyed||(this.destroyed=!0,this.observer?.disconnect(),this.records.clear(),this.imageKeys.clear(),await Promise.allSettled(this.pendingWrites),await this.options.recognition?.dispose?.())}queueRefresh(){this.refreshQueued||this.destroyed||(this.refreshQueued=!0,queueMicrotask(()=>{this.refreshQueued=!1,this.readyPromise=this.refresh()}))}async analyze(e){let i=y(e);if(!i||this.analyzedSources.get(e)===i)return;let t=this.pending.get(e);if(t)return t.source===i?t.promise:(await t.promise,this.analyze(e));this.analyzedSources.has(e)&&this.removeImage(e);let s={source:i,promise:Promise.resolve()},r=(async()=>{try{if(await le(e),this.destroyed)return;let o=O(e),a=this.imageIdentity(e,i),l=`${this.id}:${a}`,d=this.options.recognition,c=this.options.store?await this.options.store.load(l):null;if(this.destroyed||y(e)!==i)return;let h=d?.cacheKey??c?.inferenceKey??"",u=d?.configurationKey??c?.dedupeKey??"",m=c?.source===o,g=!!(e.dataset.popmeltMediaId||e.dataset.popmeltSeeId),p=m||g;if(c&&p){let j=new Map(c.subjects.map(x=>[x.id,x]));for(let x of this.imageSubjects(e))j.set(x.id,x);this.replaceImageRecords(e,a,[...j.values()]),this.suppressions.set(e,[...c.suppressions??[]]),this.analysisMetadata.set(e,{storeKey:l,source:o,imageHash:c.imageHash,inferenceKey:c.inferenceKey,dedupeKey:c.dedupeKey})}if(this.options.hydrateOnly){this.analyzedSources.set(e,i);return}let f=this.options.store?await(this.options.imageHasher??ce)(e):"ephemeral";if(this.destroyed||y(e)!==i)return;if(!!(c&&p&&c.imageHash===f&&(!d||c.inferenceKey===h&&c.dedupeKey===u))){this.analysisMetadata.set(e,{storeKey:l,source:o,imageHash:f,inferenceKey:h,dedupeKey:u}),this.analyzedSources.set(e,i),await this.saveImage(e);return}let A=p&&c?.imageHash===f;if(c&&!A){let j=new Set(c.subjects.map(L=>L.id)),x=c.subjects.filter(me);this.replaceImageRecords(e,a,[...x,...this.imageSubjects(e).filter(L=>!j.has(L.id))]),this.suppressions.set(e,[])}if(this.analysisMetadata.set(e,{storeKey:l,source:o,imageHash:f,inferenceKey:A?c.inferenceKey:"",dedupeKey:A?c.dedupeKey:""}),!d){this.analyzedSources.set(e,i),await this.saveImage(e);return}let ie=await d.detect(e);if(this.destroyed||y(e)!==i)return;let N=this.suppressions.get(e)??[],se=d.reconcile(ie,this.imageSubjects(e),N);this.replaceImageRecords(e,a,se),this.suppressions.set(e,[...N]),this.analysisMetadata.set(e,{storeKey:l,source:o,imageHash:f,inferenceKey:h,dedupeKey:u}),this.analyzedSources.set(e,i),await this.saveImage(e)}catch(o){this.options.onError?.(o,e)}finally{this.pending.get(e)===s&&this.pending.delete(e)}})();return s.promise=r,this.pending.set(e,s),r}replaceImageRecords(e,i,t){this.removeImage(e);let s=new Set;for(let r of t){let o=`${i}:${r.id}`;s.add(o),this.records.set(o,ue(e,r))}this.imageKeys.set(e,s)}imageIdentity(e,i){if(e.dataset.popmeltMediaId)return e.dataset.popmeltMediaId;if(e.dataset.popmeltSeeId)return e.dataset.popmeltSeeId;let t=new URL(i,e.ownerDocument.baseURI).href,s=this.options.root??e.ownerDocument,r=this.options.selector??B,o=Array.from(s.querySelectorAll(r)).filter(l=>y(l)===i),a=Math.max(0,o.indexOf(e));return`${P(t)}:${a}`}matchingImages(){let e=this.options.root??document,i=this.options.selector??B,t=[];e instanceof HTMLImageElement&&e.matches(i)&&t.push(e);for(let s of e.querySelectorAll(i))s instanceof HTMLImageElement&&t.push(s);return t}clampedImagePoint(e,i){let t=K(e,{left:0,top:0,width:1,height:1});return t?H(e,{x:Math.max(t.left,Math.min(t.left+t.width,i.x)),y:Math.max(t.top,Math.min(t.top+t.height,i.y))}):null}newObjectId(){let e=globalThis.crypto?.randomUUID?.();return e||P(`${Date.now()}:${this.manualSequence++}:${Math.random().toString(36)}`)}persistImage(e){let i=this.persistencePayload(e);if(!i)return Promise.resolve();let s=(this.writeChains.get(e)??Promise.resolve()).catch(()=>{}).then(()=>i.store.save(i.key,i.analysis)).catch(r=>{this.options.onError?.(r,e)});return this.writeChains.set(e,s),this.pendingWrites.add(s),s.finally(()=>this.pendingWrites.delete(s)),s}async saveImage(e){await this.persistImage(e)}imageSubjects(e){return Array.from(this.imageKeys.get(e)??[]).map(i=>this.records.get(i)).filter(i=>!!i).map(he)}persistencePayload(e){let i=this.options.store,t=this.analysisMetadata.get(e);if(!i||!t)return null;let s=this.imageSubjects(e),r={schemaVersion:1,source:t.source,imageHash:t.imageHash,inferenceKey:t.inferenceKey,dedupeKey:t.dedupeKey,subjects:s,suppressions:this.suppressions.get(e)??[],updatedAt:Date.now()};return{store:i,key:t.storeKey,analysis:r}}removeImage(e){for(let i of this.imageKeys.get(e)??[])this.records.delete(i);this.imageKeys.delete(e),this.analyzedSources.delete(e),this.analysisMetadata.delete(e),this.suppressions.delete(e)}};function Re(n={}){return new F(n)}var w=(n,e=0,i=1)=>Math.min(i,Math.max(e,n));function z(n){let e=n.getBoundingClientRect();if(e.width<=0||e.height<=0||n.videoWidth<=0||n.videoHeight<=0)return null;let i=n.ownerDocument.defaultView?.getComputedStyle(n)??getComputedStyle(n),t=i.objectFit||"fill",s=Math.min(e.width/n.videoWidth,e.height/n.videoHeight),r=Math.max(e.width/n.videoWidth,e.height/n.videoHeight),o=t==="contain"?s:t==="cover"?r:t==="none"?1:t==="scale-down"?Math.min(1,s):null,a=o?{width:n.videoWidth*o,height:n.videoHeight*o}:{width:e.width,height:e.height},l=(i.objectPosition||"50% 50%").split(/\s+/),d=(c,h)=>c.endsWith("%")?h*(Number.parseFloat(c)/100):c.endsWith("px")?Number.parseFloat(c):c==="center"?h/2:c==="right"||c==="bottom"?h:0;return{rect:e,rendered:a,position:{x:d(l[0]||"50%",e.width-a.width),y:d(l[1]||"50%",e.height-a.height)}}}function V(n,e){let i=z(n);if(!i)return null;let{rect:t,rendered:s,position:r}=i;if(e.x<t.left||e.x>t.right||e.y<t.top||e.y>t.bottom)return null;let o=(e.x-t.left-r.x)/s.width,a=(e.y-t.top-r.y)/s.height;return o>=0&&o<=1&&a>=0&&a<=1?{x:o,y:a}:null}function Y(n,e){let i=z(n);if(!i)return null;let{rect:t,rendered:s,position:r}=i,o=t.left+r.x+w(e.left)*s.width,a=t.top+r.y+w(e.top)*s.height,l=t.left+r.x+w(e.left+Math.max(0,e.width))*s.width,d=t.top+r.y+w(e.top+Math.max(0,e.height))*s.height,c=Math.max(t.left,o),h=Math.max(t.top,a),u=Math.min(t.right,l),m=Math.min(t.bottom,d);return u<=c||m<=h?null:{left:c,top:h,width:u-c,height:m-h}}function G(n,e){let i=z(n);if(!i)return null;let{rect:t,rendered:s,position:r}=i,o=(e.left-t.left-r.x)/s.width,a=(e.top-t.top-r.y)/s.height,l=(e.left+e.width-t.left-r.x)/s.width,d=(e.top+e.height-t.top-r.y)/s.height,c=w(Math.min(o,l)),h=w(Math.min(a,d)),u=w(Math.max(o,l)),m=w(Math.max(a,d));return u<=c||m<=h?null:{left:c,top:h,width:u-c,height:m-h}}var ge="video",fe=1/60,J=30,ye=.9,be=250,k=.001;function C(n){let e=2166136261;for(let i=0;i<n.length;i+=1)e^=n.charCodeAt(i),e=Math.imul(e,16777619);return(e>>>0).toString(36)}function v(n){return n.currentSrc||n.src||n.querySelector("source")?.src||n.getAttribute("src")||""}function ve(n){return n.readyState>=1&&n.videoWidth>0&&n.videoHeight>0?Promise.resolve():new Promise((e,i)=>{let t=()=>{r(),e()},s=()=>{r(),i(new Error(`Unable to load video: ${v(n)}`))},r=()=>{n.removeEventListener("loadedmetadata",t),n.removeEventListener("error",s)};n.addEventListener("loadedmetadata",t,{once:!0}),n.addEventListener("error",s,{once:!0})})}function Se(n,e,i){let t=(s,r)=>s+(r-s)*i;return{left:t(n.left,e.left),top:t(n.top,e.top),width:t(n.width,e.width),height:t(n.height,e.height)}}function M(n,e){return n.find(i=>e>=i.start-.001&&(i.end===void 0||e<=i.end+.001))??null}function D(n){return!M(n.segments,n.video.currentTime)}function T(n){return n?.motion.createSmoother()??{smooth(e){return{...e,box:{...e.box}}}}}function X(n){return{visible:!D(n),misses:n.misses,hits:n.hits,lostAt:n.lostAt}}function we(n,e){n.misses=e.misses,n.hits=e.hits,n.lostAt=e.lostAt}function xe(n,e){if(e?.length)return e.map(t=>({...t})).sort((t,s)=>t.start-s.start);let i=n.reduce((t,s)=>Math.min(t,s.time),Number.POSITIVE_INFINITY);return Number.isFinite(i)?[{start:i}]:[]}function I(n,e,i){if(n.length===0||i&&!M(i,e))return null;let t=[...n].sort((d,c)=>d.time-c.time),s=t.findIndex(d=>d.time>=e);if(s<=0)return{...t[0],box:{...t[0].box}};if(s<0){let d=t[t.length-1];return{...d,box:{...d.box}}}let r=t[s-1],o=t[s],a=Math.max(Number.EPSILON,o.time-r.time),l=Math.max(0,Math.min(1,(e-r.time)/a));return{time:e,box:Se(r.box,o.box,l),score:r.score+(o.score-r.score)*l,source:r.source==="manual"||o.source==="manual"?"manual":"tracked"}}function $(n){return!n.video.paused&&n.liveFrame?{...n.liveFrame,box:{...n.liveFrame.box}}:I(n.presentationKeyframes,n.video.currentTime,n.segments)}function Te(n,e){return e.x>=n.left&&e.x<=n.left+n.width&&e.y>=n.top&&e.y<=n.top+n.height}function ee(n,e){if(!Te(n.bounds,e))return!1;let i=n.outline;if(!i||i.length<3)return!0;let t=(e.x-n.bounds.left)/n.bounds.width,s=(e.y-n.bounds.top)/n.bounds.height,r=!1;for(let o=0,a=i.length-1;o<i.length;a=o++){let l=i[o],d=i[a];l.y>s!=d.y>s&&t<(d.x-l.x)*(s-l.y)/(d.y-l.y)+l.x&&(r=!r)}return r}function ke(n){let e=n.outline;if(!e||e.length<3)return n.bounds.width*n.bounds.height;let i=0;for(let t=0;t<e.length;t+=1){let s=e[t],r=e[(t+1)%e.length];i+=s.x*r.y-r.x*s.y}return Math.abs(i)/2*n.bounds.width*n.bounds.height}function Z(n,e){return(e.outline?.length?e.outline.map(t=>({x:e.bounds.left+t.x*e.bounds.width,y:e.bounds.top+t.y*e.bounds.height})):[{x:e.bounds.left,y:e.bounds.top},{x:e.bounds.left+e.bounds.width,y:e.bounds.top},{x:e.bounds.left+e.bounds.width,y:e.bounds.top+e.bounds.height},{x:e.bounds.left,y:e.bounds.top+e.bounds.height}]).every(t=>ee(n,t))}function Me(n,e){let i=Math.max(n.left,e.left),t=Math.max(n.top,e.top),s=Math.min(n.left+n.width,e.left+e.width),r=Math.min(n.top+n.height,e.top+e.height),o=Math.max(0,s-i)*Math.max(0,r-t),a=n.width*n.height+e.width*e.height-o;return a>0?o/a:0}var W=class{constructor(e={}){this.options=e;this.surfaceKind="video";this.records=new Map;this.videoKeys=new Map;this.metadata=new WeakMap;this.analyzedSources=new WeakMap;this.listeners=new Map;this.frameHandles=new Map;this.persistTimers=new Map;this.writeChains=new WeakMap;this.pendingWrites=new Set;this.refreshQueued=!1;this.destroyed=!1;this.manualSequence=0;this.detectedSequence=0;this.activeTrackingKey=null;this.segmentationGeneration=0;this.transientKeys=new Set;this.segmentationRequestSignatures=new WeakMap;this.changeListeners=new Set;this.id=e.id??"see:video",this.readyPromise=this.refresh();let i=e.root??document;this.observer=e.observe!==!1&&typeof MutationObserver<"u"?new MutationObserver(()=>this.queueRefresh()):null,this.observer?.observe(i,{childList:!0,subtree:!0,attributes:!0,attributeFilter:["src"]})}whenReady(){return this.readyPromise}subscribe(e){return this.changeListeners.add(e),()=>this.changeListeners.delete(e)}listSubjects(){return Array.from(this.records.keys(),e=>this.transientKeys.has(e)?null:this.resolve(e)).filter(e=>!!e)}async refresh(){if(this.destroyed)return;let e=new Set(this.matchingVideos());for(let i of this.videoKeys.keys())(!e.has(i)||!i.isConnected)&&this.removeVideo(i);await Promise.all(Array.from(e,i=>this.analyze(i)))}hitTest(e){return this.hitTestAll(e)[0]??null}hitTestAll(e){let i=[];for(let t of this.records.keys()){let s=this.resolve(t);!s||!ee(s,e)||i.push({subject:s,area:ke(s)})}return this.options.segmentation&&this.scheduleSegmentation(e),i.sort((t,s)=>Z(t.subject,s.subject)?1:Z(s.subject,t.subject)?-1:t.area-s.area).map(({subject:t})=>t)}promoteSubject(e){let i=this.records.get(e);return i?this.transientKeys.delete(e)?(this.activateTrackingRecord(i),this.persistVideo(i.video),this.startSession(i,!0).then(()=>this.scheduleBackwardAnalysis(i)),this.resolve(e)):this.resolve(e):null}resolve(e){let i=this.records.get(e);if(!i?.video.isConnected)return null;let t=$(i);if(!t)return null;let s=Y(i.video,t.box);if(!s)return null;let r=i.video.getBoundingClientRect();return{key:e,label:i.label,sourceElement:i.video,videoObject:this.videoObjectContext(i,t),trackingAnchors:i.anchors.map(o=>({...o})),outline:t.outline?.map(o=>({...o})),bounds:s,surfaceBounds:{left:r.left,top:r.top,width:r.width,height:r.height},context:`${i.label} tracked in video at ${i.video.currentTime.toFixed(2)}s`,data:{kind:"video-object",label:i.label,origin:i.origin,score:String(Math.round(t.score*1e3)/1e3),videoSrc:v(i.video),currentTime:String(i.video.currentTime)}}}async captureSubject(e){let i=this.records.get(e);if(!i||i.video.readyState<2)return null;let t=$(i);if(!t)return null;let{video:s}=i,r={x:t.box.left*s.videoWidth,y:t.box.top*s.videoHeight,width:t.box.width*s.videoWidth,height:t.box.height*s.videoHeight},o=Math.min(1,1024/Math.max(r.width,r.height)),a=document.createElement("canvas");a.width=Math.max(1,Math.round(r.width*o)),a.height=Math.max(1,Math.round(r.height*o));let l=a.getContext("2d");return l?(l.drawImage(s,r.x,r.y,r.width,r.height,0,0,a.width,a.height),new Promise((d,c)=>{try{a.toBlob(d,"image/webp",.95)}catch(h){c(h)}})):null}beginCreate(e){let i=this.matchingVideos();for(let t=i.length-1;t>=0;t-=1){let s=i[t];if(!s)continue;let r=V(s,e);if(!r)continue;let o=this.videoIdentity(s),a=`manual:${this.newObjectId()}`,l=`${o}:${a}`,d=Date.now(),c={time:s.currentTime,box:{left:r.x,top:r.y,width:0,height:0},score:1,source:"manual"},h=T(this.options.tracking),u={key:l,id:a,video:s,label:"object",origin:"manual",keyframes:[c],segments:[{start:s.currentTime}],anchors:[],presentationKeyframes:[h.smooth(c)],smoother:h,createdAt:d,updatedAt:d,misses:0,hits:0,analyzedThrough:c.time},m=!1,g=!1,p=()=>{if(g)return;g=!0,this.records.set(l,u);let f=this.videoKeys.get(s)??new Set;f.add(l),this.videoKeys.set(s,f)};return{key:l,update:f=>{if(m)return null;p();let b=V(s,f);return b&&(c.box={left:Math.min(r.x,b.x),top:Math.min(r.y,b.y),width:Math.abs(b.x-r.x),height:Math.abs(b.y-r.y)},u.smoother=T(this.options.tracking),u.presentationKeyframes=[u.smoother.smooth(c)]),this.resolve(l)},commit:()=>m?null:(p(),u.backwardSeedTime=c.time,this.activateTrackingRecord(u),this.persistVideo(s),this.startSession(u,!0).then(()=>this.scheduleBackwardAnalysis(u)),this.resolve(l)),cancel:()=>{m||(m=!0,g&&this.removeSubject(l))}}}return null}renameSubject(e,i){let t=this.records.get(e),s=i.trim();return!t||!s?null:(t.label=s,t.updatedAt=Date.now(),this.activateTrackingRecord(t),this.persistVideo(t.video),this.resolve(e))}updateSubjectBounds(e,i){let t=this.records.get(e);if(!t)return null;let s=G(t.video,i);if(!s)return null;this.openSegment(t,t.video.currentTime),this.insertKeyframe(t,{time:t.video.currentTime,box:s,score:1,source:"manual"}),t.liveFrame=void 0,t.trackingFailed=!1,t.misses=0,t.hits=0,t.lostAt=void 0,t.analyzedThrough=t.video.currentTime;let r=M(t.segments,t.video.currentTime);return r&&Math.abs(r.start-t.video.currentTime)<=.05&&(t.backwardSeedTime=t.video.currentTime,this.cancelBackwardAnalysis(t)),this.activateTrackingRecord(t),this.persistVideo(t.video),this.startSession(t,!0).then(()=>this.reseed(t)).then(()=>this.scheduleBackwardAnalysis(t)),this.resolve(e)}updateSubjectTrackingAnchors(e,i){let t=this.records.get(e);return t?(t.anchors=i.slice(0,3).map(s=>({x:Math.max(0,Math.min(1,s.x)),y:Math.max(0,Math.min(1,s.y))})),t.updatedAt=Date.now(),t.trackingFailed=!1,t.analyzedThrough=t.video.currentTime,t.backwardSeedTime!==void 0&&this.cancelBackwardAnalysis(t),this.activateTrackingRecord(t),this.persistVideo(t.video),this.startSession(t,!0).then(()=>this.reseed(t)).then(()=>this.scheduleBackwardAnalysis(t)),this.resolve(e)):null}removeSubject(e){let i=this.records.get(e);if(!i)return;this.cancelBackwardAnalysis(i),i.session?.dispose?.(),this.activeTrackingKey===e&&(this.activeTrackingKey=null),this.transientKeys.delete(e),this.records.delete(e);let t=this.videoKeys.get(i.video);t?.delete(e),t?.size===0&&this.videoKeys.delete(i.video),this.persistVideo(i.video)}async destroy(){if(this.destroyed)return;this.destroyed=!0,this.observer?.disconnect();for(let i of this.listeners.keys())this.removeVideoListeners(i);await Promise.all(Array.from(this.persistTimers.keys(),i=>this.flushScheduledPersistence(i)));let e=Array.from(this.records.values(),i=>i.backwardAnalysis?.promise).filter(i=>!!i);await Promise.allSettled(Array.from(this.records.values(),i=>(this.cancelBackwardAnalysis(i),i.session?.dispose?.()))),await Promise.allSettled(e),this.records.clear(),this.videoKeys.clear(),this.changeListeners.clear(),await Promise.allSettled(this.pendingWrites)}scheduleSegmentation(e){let i=this.options.segmentation;if(!i||this.destroyed)return;let t=this.matchingVideos();for(let s=t.length-1;s>=0;s-=1){let r=t[s];if(!r||r.readyState<2)continue;let o=V(r,e);if(!o)continue;let a=[Math.round(r.currentTime*30),Math.round(o.x*256),Math.round(o.y*256)].join(":");if(this.segmentationRequestSignatures.get(r)===a)return;this.segmentationRequestSignatures.set(r,a);let l=++this.segmentationGeneration,d=r.currentTime;i.segment(r,d,o).then(c=>{if(!c||this.destroyed||l!==this.segmentationGeneration||!r.isConnected)return;let h=Array.from(this.videoKeys.get(r)??[]).map(u=>this.records.get(u)).filter(u=>!!u).find(u=>{let m=$(u);return m&&Me(m.box,c.box)>=.65});this.clearTransientSubjects(r,h?.key),h||this.addDetectedSubject(r,d,c);for(let u of this.changeListeners)u()}).catch(c=>this.options.onError?.(c,r));return}}addDetectedSubject(e,i,t){let s=this.videoIdentity(e),r=`detected:${C([i.toFixed(3),t.box.left.toFixed(4),t.box.top.toFixed(4),t.box.width.toFixed(4),t.box.height.toFixed(4),this.detectedSequence++].join(":"))}`,o=`${s}:${r}`,a=e.currentTime,l={time:a,box:{...t.box},score:t.score,source:"tracked",outline:t.outline?.map(m=>({...m}))},d=T(this.options.tracking),c=Date.now(),h={key:o,id:r,video:e,label:t.label?.trim()||"object",origin:"detected",keyframes:[l],segments:[{start:a}],anchors:[],presentationKeyframes:[d.smooth(l)],smoother:d,createdAt:c,updatedAt:c,misses:0,hits:0,analyzedThrough:a,backwardSeedTime:a};this.records.set(o,h),this.transientKeys.add(o);let u=this.videoKeys.get(e)??new Set;u.add(o),this.videoKeys.set(e,u)}clearTransientSubjects(e,i){let t=this.videoKeys.get(e);if(t)for(let s of[...t])s===i||!this.transientKeys.delete(s)||(this.records.delete(s),t.delete(s))}async analyze(e){let i=v(e);if(!(!i||this.analyzedSources.get(e)===i))try{if(await ve(e),this.destroyed||v(e)!==i)return;let t=this.videoIdentity(e),s=new URL(i,e.ownerDocument.baseURI).href,r=`${this.id}:${t}`,o=this.options.store?await this.options.store.load(r):null;if(this.destroyed||v(e)!==i)return;this.metadata.set(e,{storeKey:r,source:s,identity:t});let a=!!e.dataset.popmeltMediaId;o&&(o.source===s||a)?this.replaceVideoRecords(e,t,o.tracks):this.videoKeys.has(e)||this.videoKeys.set(e,new Set),this.analyzedSources.set(e,i),this.addVideoListeners(e)}catch(t){this.options.onError?.(t,e)}}addVideoListeners(e){if(this.listeners.has(e))return;let i=()=>{this.clearLiveFrames(e),this.activateMostRecentRecord(e);let o=this.activeRecordFor(e);if(this.options.tracking&&o&&!o.session&&(o.analyzedThrough===void 0||o.analyzedThrough<e.duration-k)){let a=this.startSession(o,!0);e.pause(),a.then(()=>{!this.destroyed&&o.session&&e.play()});return}o&&this.scheduleBackwardAnalysis(o),this.scheduleFrame(e)},t=()=>{this.clearLiveFrames(e);let o=this.activeRecordFor(e);o&&this.scheduleBackwardAnalysis(o),this.flushScheduledPersistence(e)},s=()=>{let o=this.activeRecordFor(e);o?.lastTrackedMediaTime!==void 0&&(o.analyzedThrough=e.duration,o.lastTrackedMediaTime=void 0,o.session?.dispose?.(),o.session=void 0,this.schedulePersistence(e)),t()},r=()=>{let o=this.activeRecordFor(e);if(!o)return;let a=o.lastTrackedMediaTime;if(e.loop&&a!==void 0&&a>=e.duration-.25&&e.currentTime+.25<a&&(o.analyzedThrough??0)>=a-.25){I(o.presentationKeyframes,e.currentTime,o.segments)&&(o.liveFrame=void 0),o.analyzedThrough=Math.max(0,e.currentTime-k*2),o.lastTrackedMediaTime=void 0;let l=o.session;o.session=void 0,Promise.resolve(o.tracking).finally(async()=>{await l?.dispose?.(),!(this.destroyed||this.activeTrackingKey!==o.key)&&(await this.startSession(o),this.scheduleBackwardAnalysis(o))}),this.schedulePersistence(e);return}this.clearLiveFrames(e),o.session&&this.reseed(o)};e.addEventListener("play",i),e.addEventListener("pause",t),e.addEventListener("ended",s),e.addEventListener("seeked",r),this.listeners.set(e,()=>{e.removeEventListener("play",i),e.removeEventListener("pause",t),e.removeEventListener("ended",s),e.removeEventListener("seeked",r)}),e.paused||(this.activateMostRecentRecord(e),this.scheduleFrame(e))}removeVideoListeners(e){this.listeners.get(e)?.(),this.listeners.delete(e);let i=e,t=this.frameHandles.get(e);t!==void 0&&(i.cancelVideoFrameCallback?.(t),cancelAnimationFrame(t)),this.frameHandles.delete(e)}scheduleFrame(e){if(this.destroyed||e.paused||this.frameHandles.has(e))return;let i=e,t=(s,r)=>{this.frameHandles.delete(e),this.trackVideo(e,r.mediaTime),this.scheduleFrame(e)};i.requestVideoFrameCallback?this.frameHandles.set(e,i.requestVideoFrameCallback(t)):this.frameHandles.set(e,requestAnimationFrame(()=>t(performance.now(),{mediaTime:e.currentTime})))}async trackVideo(e,i){let t=this.activeRecordFor(e);if(!t||t.tracking||t.trackingFailed||t.analyzedThrough!==void 0&&i<=t.analyzedThrough+k)return;let s=this.options.tracking?.motion;if(!s)return;let r=s.attempt({state:X(t),time:i,maximumFramesPerSecond:Math.max(1,this.options.maxTrackingFramesPerSecond??J)});t.lastTrackedMediaTime!==void 0&&Math.abs(i-t.lastTrackedMediaTime)<ye/r.framesPerSecond||(t.session||await this.startSession(t),!(!t.session||this.activeTrackingKey!==t.key)&&(t.lastTrackedMediaTime=i,t.tracking=t.session.track(e,i,r.tracking).then(o=>{if(this.destroyed||this.activeTrackingKey!==t.key)return;t.analyzedThrough=Math.max(t.analyzedThrough??i,i);let a=s.observe({state:X(t),time:i,observation:o});we(t,a.state),o&&a.action==="reopen"&&this.openSegment(t,i),o&&(a.action==="accept"||a.action==="reopen")?this.acceptObservation(t,{...o,source:"tracked"}):a.action==="close"&&(t.liveFrame=void 0,this.closeSegment(t,t.keyframes[t.keyframes.length-1]?.time??i)),this.schedulePersistence(e)}).catch(o=>this.failTracking(t,o)).finally(()=>{t.tracking=void 0}),await t.tracking))}async startSession(e,i=!1){if(e.initializing){await e.initializing;return}if(!this.options.tracking||e.session||e.trackingFailed||this.activeTrackingKey!==e.key||e.video.paused&&!i)return;let t=I(e.keyframes,e.video.currentTime,e.segments)??e.liveFrame;!t||e.video.readyState<2||(e.initializing=this.options.tracking.createSession({video:e.video,time:e.video.currentTime,box:t.box,anchors:e.anchors}).then(s=>{this.destroyed||this.activeTrackingKey!==e.key?s.dispose?.():e.session=s}).catch(s=>this.failTracking(e,s)).finally(()=>{e.initializing=void 0}),await e.initializing)}async reseed(e){let i=I(e.keyframes,e.video.currentTime,e.segments);if(!i){e.session?.dispose?.(),e.session=void 0,e.lostAt=e.video.currentTime,e.liveFrame=void 0,e.misses=0,e.hits=0;return}e.lostAt=void 0,e.misses=0,e.hits=0;try{e.session?.reseed&&await e.session.reseed({video:e.video,time:e.video.currentTime,box:i.box,anchors:e.anchors})}catch(t){this.failTracking(e,t)}}failTracking(e,i){e.trackingFailed=!0,e.liveFrame=void 0,e.session?.dispose?.(),e.session=void 0,this.options.onError?.(i,e.video)}activeRecordFor(e){if(!this.activeTrackingKey)return null;let i=this.records.get(this.activeTrackingKey);return i?.video===e?i:null}activateMostRecentRecord(e){if(this.activeRecordFor(e))return;let t=Array.from(this.videoKeys.get(e)??[]).map(s=>this.records.get(s)).filter(s=>!!s).sort((s,r)=>r.updatedAt-s.updatedAt)[0];t&&this.activateTrackingRecord(t)}activateTrackingRecord(e){if(this.activeTrackingKey===e.key)return;let i=this.activeTrackingKey?this.records.get(this.activeTrackingKey):void 0;this.activeTrackingKey=e.key,i&&(this.cancelBackwardAnalysis(i),i.session?.dispose?.(),i.session=void 0,i.lastTrackedMediaTime=void 0,i.liveFrame=void 0),e.liveFrame=void 0,e.trackingFailed=!1,e.lastTrackedMediaTime=void 0,e.misses=0,e.hits=0,e.lostAt=D(e)?e.video.currentTime:void 0}scheduleBackwardAnalysis(e){if(this.destroyed||!this.options.tracking||e.backwardSeedTime===void 0||e.backwardSeedTime<=k||e.backwardAnalysis||e.initializing||this.activeTrackingKey!==e.key)return;let i={cancelled:!1,promise:Promise.resolve()};e.backwardAnalysis=i,i.promise=this.runBackwardAnalysis(e,i).catch(t=>{i.cancelled||this.options.onError?.(t,e.video)}).finally(()=>{e.backwardAnalysis===i&&(e.backwardAnalysis=void 0,!i.cancelled&&e.backwardSeedTime!==void 0&&(e.backwardSeedTime=void 0),i.cancelled&&!this.destroyed&&this.activeTrackingKey===e.key&&queueMicrotask(()=>this.scheduleBackwardAnalysis(e)))})}cancelBackwardAnalysis(e){let i=e.backwardAnalysis;i&&(i.cancelled=!0)}async runBackwardAnalysis(e,i){let t=e.backwardSeedTime;if(t===void 0)return;let s=await this.options.tracking.motion.analyzeBackward({source:e.video,seedTime:t,keyframes:e.keyframes,anchors:e.anchors,maximumFramesPerSecond:this.options.maxTrackingFramesPerSecond??J,cancelled:()=>i.cancelled||this.destroyed,forwardWork:()=>e.initializing??e.tracking});if(i.cancelled||this.destroyed)return;let r=M(e.segments,t);r&&(e.keyframes=s.keyframes,r.start=Math.min(r.start,s.earliestTime),e.updatedAt=Date.now(),this.rebuildPresentationTrack(e),this.schedulePersistence(e.video))}acceptObservation(e,i){let t=[...e.keyframes].reverse().find(r=>r.outline?.length)?.outline,s=this.insertKeyframe(e,{...i,outline:i.outline??t});return e.video.paused||(e.liveFrame={...s,box:{...s.box}}),!0}openSegment(e,i){if(M(e.segments,i))return!1;let t=e.segments[e.segments.length-1];return t&&t.end===void 0&&i>=t.start?!1:(e.segments.push({start:i}),e.segments.sort((s,r)=>s.start-r.start),e.smoother=T(this.options.tracking),!0)}closeSegment(e,i){let t=[...e.segments].reverse().find(s=>s.end===void 0);return t?(t.end=Math.max(t.start,i),e.updatedAt=Date.now(),!0):!1}insertKeyframe(e,i){let t={...i,box:{...i.box}},s=e.keyframes.findIndex(o=>Math.abs(o.time-i.time)<.001),r=!1;if(s>=0)e.keyframes[s]=t;else{let o=e.keyframes[e.keyframes.length-1];if(i.source==="tracked"&&o&&Math.abs(i.time-o.time)<fe)e.keyframes[e.keyframes.length-1]=t;else if(!o||i.time>o.time){e.keyframes.push(t);let a=e.smoother.smooth(t);e.presentationKeyframes.push(a),r=!0}else e.keyframes.push(t)}return r||this.rebuildPresentationTrack(e),e.updatedAt=Date.now(),I(e.presentationKeyframes,i.time)??{...t,box:{...t.box}}}rebuildPresentationTrack(e){e.keyframes.sort((s,r)=>s.time-r.time);let i=T(this.options.tracking),t=null;e.presentationKeyframes=e.keyframes.map(s=>{let r=M(e.segments,s.time);return r&&r!==t&&(i=T(this.options.tracking),t=r),i.smooth(s)}),e.smoother=i}clearLiveFrames(e){for(let i of this.videoKeys.get(e)??[]){let t=this.records.get(i);t&&(t.liveFrame=void 0)}}videoObjectContext(e,i){let{video:t}=e,s=e.keyframes.map(r=>r.time);return{src:v(t),width:t.videoWidth,height:t.videoHeight,duration:t.duration,currentTime:t.currentTime,normalizedBox:{x:i.box.left,y:i.box.top,width:i.box.width,height:i.box.height},box:{x:i.box.left*t.videoWidth,y:i.box.top*t.videoHeight,width:i.box.width*t.videoWidth,height:i.box.height*t.videoHeight},trackStart:Math.min(...s),trackEnd:Math.max(...s)}}replaceVideoRecords(e,i,t){this.removeVideoRecords(e);let s=new Set;for(let r of t){let o=`${i}:${r.id}`,a=r.keyframes.map(u=>({...u,box:{...u.box}})),l=xe(a,r.segments),d=a[0],c=T(this.options.tracking);s.add(o);let h={key:o,id:r.id,video:e,label:r.label,origin:r.origin,keyframes:a,segments:l,anchors:(r.anchors??[]).map(u=>({...u})),presentationKeyframes:[],smoother:c,createdAt:r.createdAt,updatedAt:r.updatedAt,misses:0,hits:0,analyzedThrough:r.analyzedThrough,backwardSeedTime:d?.source==="manual"&&d.time>k&&(l[0]?.start??-1)>=d.time-k?d.time:void 0};D(h)&&(h.lostAt=e.currentTime),this.rebuildPresentationTrack(h),r.presentationKeyframes?.length&&(h.presentationKeyframes=r.presentationKeyframes.map(u=>({...u,box:{...u.box}}))),this.records.set(o,h)}this.videoKeys.set(e,s)}persistVideo(e){let i=this.persistTimers.get(e);i!==void 0&&clearTimeout(i),this.persistTimers.delete(e);let t=this.options.store,s=this.metadata.get(e);if(!t||!s)return Promise.resolve();let r=Array.from(this.videoKeys.get(e)??[]).map(d=>this.records.get(d)).filter(d=>!!d).map(d=>({id:d.id,label:d.label,origin:d.origin,keyframes:d.keyframes.map(c=>({...c,box:{...c.box}})),presentationKeyframes:d.presentationKeyframes.map(c=>({...c,box:{...c.box}})),anchors:d.anchors.map(c=>({...c})),segments:d.segments.map(c=>({...c})),analyzedThrough:d.analyzedThrough,createdAt:d.createdAt,updatedAt:d.updatedAt})),o={schemaVersion:3,source:s.source,duration:Number.isFinite(e.duration)?e.duration:0,tracks:r,updatedAt:Date.now()},l=(this.writeChains.get(e)??Promise.resolve()).catch(()=>{}).then(()=>t.save(s.storeKey,o)).catch(d=>this.options.onError?.(d,e));return this.writeChains.set(e,l),this.pendingWrites.add(l),l.finally(()=>this.pendingWrites.delete(l)),l}schedulePersistence(e){!this.options.store||this.persistTimers.has(e)||this.persistTimers.set(e,setTimeout(()=>{this.persistTimers.delete(e),this.persistVideo(e)},be))}flushScheduledPersistence(e){return this.persistTimers.has(e)?this.persistVideo(e):Promise.resolve()}matchingVideos(){let e=this.options.root??document,i=this.options.selector??ge,t=[];e instanceof HTMLVideoElement&&e.matches(i)&&t.push(e);for(let s of e.querySelectorAll(i))s instanceof HTMLVideoElement&&t.push(s);return t}videoIdentity(e){if(e.dataset.popmeltMediaId)return e.dataset.popmeltMediaId;let i=new URL(v(e),e.ownerDocument.baseURI).href,t=this.matchingVideos().filter(s=>v(s)===v(e));return`${C(i)}:${Math.max(0,t.indexOf(e))}`}newObjectId(){return globalThis.crypto?.randomUUID?.()??C(`${Date.now()}:${this.manualSequence++}:${Math.random()}`)}removeVideoRecords(e){for(let i of this.videoKeys.get(e)??[]){let t=this.records.get(i);t&&this.cancelBackwardAnalysis(t),t?.session?.dispose?.(),this.activeTrackingKey===i&&(this.activeTrackingKey=null),this.transientKeys.delete(i),this.records.delete(i)}this.videoKeys.delete(e)}removeVideo(e){this.removeVideoListeners(e),this.flushScheduledPersistence(e),this.removeVideoRecords(e),this.metadata.delete(e),this.analyzedSources.delete(e)}queueRefresh(){this.refreshQueued||this.destroyed||(this.refreshQueued=!0,queueMicrotask(()=>{this.refreshQueued=!1,this.readyPromise=this.refresh()}))}};function ze(n={}){return new W(n)}var Ie="popmelt:media:video:v1";function te(n){if(!n||typeof n!="object")return!1;let e=n;return["left","top","width","height"].every(i=>typeof e[i]=="number"&&Number.isFinite(e[i]))}function je(n){if(!n||typeof n!="object")return!1;let e=n;return typeof e.start=="number"&&Number.isFinite(e.start)&&(e.end===void 0||typeof e.end=="number"&&Number.isFinite(e.end)&&e.end>=e.start)}function Pe(n){if(!n||typeof n!="object")return!1;let e=n;return(e.schemaVersion===1||e.schemaVersion===2||e.schemaVersion===3)&&typeof e.source=="string"&&typeof e.duration=="number"&&typeof e.updatedAt=="number"&&Array.isArray(e.tracks)&&e.tracks.every(i=>{if(!i||typeof i!="object")return!1;let t=i;return typeof t.id=="string"&&typeof t.label=="string"&&(t.origin==="manual"||t.origin==="detected")&&typeof t.createdAt=="number"&&typeof t.updatedAt=="number"&&(t.analyzedThrough===void 0||typeof t.analyzedThrough=="number"&&Number.isFinite(t.analyzedThrough))&&(t.segments===void 0||Array.isArray(t.segments)&&t.segments.every(je))&&Array.isArray(t.keyframes)&&t.keyframes.every(s=>{if(!s||typeof s!="object")return!1;let r=s;return typeof r.time=="number"&&typeof r.score=="number"&&(r.source==="manual"||r.source==="tracked")&&te(r.box)})&&(t.presentationKeyframes===void 0||Array.isArray(t.presentationKeyframes)&&t.presentationKeyframes.every(s=>{if(!s||typeof s!="object")return!1;let r=s;return typeof r.time=="number"&&typeof r.score=="number"&&(r.source==="manual"||r.source==="tracked")&&te(r.box)}))})}function $e(n={}){let e=n.namespace??Ie,i=()=>n.storage??window.localStorage,t=s=>`${e}:${s}`;return{load(s){try{let r=i().getItem(t(s));if(!r)return null;let o=JSON.parse(r);return Pe(o)?o:null}catch{return null}},save(s,r){i().setItem(t(s),JSON.stringify(r))},remove(s){i().removeItem(t(s))}}}function De(){let n=new Map;return{load:e=>n.get(e)??null,save:(e,i)=>{n.set(e,i)},remove:e=>{n.delete(e)}}}export{H as a,q as b,K as c,Ae as d,Le as e,F as f,Re as g,V as h,Y as i,G as j,W as k,ze as l,$e as m,De as n};
2
+ var v=(e,t=0,i=1)=>Math.min(i,Math.max(t,e));function te(e){let{width:t,height:i}=e.rect,s=Math.max(1,e.naturalWidth),r=Math.max(1,e.naturalHeight),a=Math.min(t/s,i/r),o=Math.max(t/s,i/r);switch(e.objectFit){case"contain":return{width:s*a,height:r*a};case"cover":return{width:s*o,height:r*o};case"none":return{width:s,height:r};case"scale-down":{let n=Math.min(1,a);return{width:s*n,height:r*n}}default:return{width:t,height:i}}}function C(e,t){let i=e.trim().toLowerCase();if(i.endsWith("%")){let s=Number.parseFloat(i);return Number.isFinite(s)?t*(s/100):0}if(i.endsWith("px")){let s=Number.parseFloat(i);return Number.isFinite(s)?s:0}return i==="center"?t/2:i==="right"||i==="bottom"?t:0}function ie(e,t,i){let s=e.objectPosition.trim().split(/\s+/),r=s[0]||"50%",a=s[1]||"50%";return{x:C(r,e.rect.width-t),y:C(a,e.rect.height-i)}}function F(e){let t=e.getBoundingClientRect();if(t.width<=0||t.height<=0||e.naturalWidth<=0||e.naturalHeight<=0)return null;let i=e.ownerDocument.defaultView?.getComputedStyle(e)??getComputedStyle(e),s={rect:t,naturalWidth:e.naturalWidth,naturalHeight:e.naturalHeight,objectFit:i.objectFit||"fill",objectPosition:i.objectPosition||"50% 50%"},r=te(s);return{layout:s,rendered:r,position:ie(s,r.width,r.height)}}function L(e,t){let i=F(e);if(!i)return null;let{layout:s,rendered:r,position:a}=i;if(t.x<s.rect.left||t.x>s.rect.left+s.rect.width||t.y<s.rect.top||t.y>s.rect.top+s.rect.height)return null;let o=(t.x-s.rect.left-a.x)/r.width,n=(t.y-s.rect.top-a.y)/r.height;return o>=0&&o<=1&&n>=0&&n<=1?{x:o,y:n}:null}function O(e,t){let i=F(e);if(!i)return null;let{layout:s,rendered:r,position:a}=i,o=(t.left-s.rect.left-a.x)/r.width,n=(t.top-s.rect.top-a.y)/r.height,h=(t.left+t.width-s.rect.left-a.x)/r.width,d=(t.top+t.height-s.rect.top-a.y)/r.height,c=v(Math.min(o,h)),l=v(Math.min(n,d)),u=v(Math.max(o,h)),m=v(Math.max(n,d));return u<=c||m<=l?null:{left:c,top:l,width:u-c,height:m-l}}function z(e,t){if(![t.left,t.top,t.width,t.height].every(Number.isFinite))return null;let i=F(e);if(!i)return null;let{layout:s,rendered:r,position:a}=i,{rect:o}=s,n=o.left+a.x+v(t.left)*r.width,h=o.top+a.y+v(t.top)*r.height,d=o.left+a.x+v(t.left+Math.max(0,t.width))*r.width,c=o.top+a.y+v(t.top+Math.max(0,t.height))*r.height,l=Math.max(o.left,n),u=Math.max(o.top,h),m=Math.min(o.left+o.width,d),g=Math.min(o.top+o.height,c);return m<=l||g<=u?null:{left:l,top:u,width:m-l,height:g-u}}var se="popmelt:see:v1";function P(e){if(!e||typeof e!="object")return!1;let t=e;return["left","top","width","height"].every(i=>typeof t[i]=="number"&&Number.isFinite(t[i]))}function re(e){if(!e||typeof e!="object")return!1;let t=e;return typeof t.id=="string"&&typeof t.label=="string"&&typeof t.score=="number"&&(t.origin==="detected"||t.origin==="manual")&&P(t.box)&&(t.detectedBox===void 0||P(t.detectedBox))}function ae(e){if(!e||typeof e!="object")return!1;let t=e;return typeof t.detectedLabel=="string"&&P(t.detectedBox)}function N(e){if(!e||typeof e!="object")return!1;let t=e;return t.schemaVersion===1&&typeof t.source=="string"&&typeof t.imageHash=="string"&&typeof t.inferenceKey=="string"&&typeof t.dedupeKey=="string"&&typeof t.updatedAt=="number"&&Array.isArray(t.subjects)&&t.subjects.every(re)&&(t.suppressions===void 0||Array.isArray(t.suppressions)&&t.suppressions.every(ae))}function oe(e={}){let t=e.namespace??se,i=()=>e.storage??window.localStorage,s=n=>`${t}:${n}`,r=n=>`${s(n)}:history`,a=n=>{try{let h=i().getItem(s(n));if(!h)return null;let d=JSON.parse(h);return N(d)?d:null}catch{return null}},o=n=>{try{let h=i().getItem(r(n));if(!h)return[];let d=JSON.parse(h);return Array.isArray(d)?d.filter(N).slice(0,10):[]}catch{return[]}};return{load:a,save(n,h){let d=a(n);if(d&&d.imageHash!==h.imageHash){let c=o(n).filter(l=>l.imageHash!==d.imageHash||l.updatedAt!==d.updatedAt);i().setItem(r(n),JSON.stringify([d,...c].slice(0,10)))}i().setItem(s(n),JSON.stringify(h))},remove(n){i().removeItem(s(n)),i().removeItem(r(n))},loadHistory:o}}function ne(){let e=new Map,t=new Map;return{load:i=>e.get(i)??null,save:(i,s)=>{let r=e.get(i);if(r&&r.imageHash!==s.imageHash){let a=t.get(i)??[];t.set(i,[r,...a.filter(o=>o.imageHash!==r.imageHash||o.updatedAt!==r.updatedAt)].slice(0,10))}e.set(i,s)},remove:i=>{e.delete(i),t.delete(i)},loadHistory:i=>t.get(i)??[]}}function de(e){return{label:e.label,score:e.score,box:{...e.box}}}var H="img";function A(e){let t=2166136261;for(let i=0;i<e.length;i+=1)t^=e.charCodeAt(i),t=Math.imul(t,16777619);return(t>>>0).toString(36)}function R(e){return new URL(p(e),e.ownerDocument.baseURI).href}async function he(e){let t=R(e);try{let i=await fetch(t,{cache:"force-cache",credentials:"same-origin"});if(!i.ok)throw new Error(`Unable to hash image (${i.status})`);let s=await i.arrayBuffer();if(!globalThis.crypto?.subtle)throw new Error("SubtleCrypto unavailable");let r=await globalThis.crypto.subtle.digest("SHA-256",s);return Array.from(new Uint8Array(r),a=>a.toString(16).padStart(2,"0")).join("")}catch{return`source:${A(t)}:${e.naturalWidth}x${e.naturalHeight}`}}function p(e){return e.currentSrc||e.src||e.getAttribute("src")||""}function le(e){return e.complete&&e.naturalWidth>0&&e.naturalHeight>0?Promise.resolve():new Promise((t,i)=>{let s=()=>{a(),t()},r=()=>{a(),i(new Error(`Unable to load image: ${p(e)}`))},a=()=>{e.removeEventListener("load",s),e.removeEventListener("error",r)};e.addEventListener("load",s,{once:!0}),e.addEventListener("error",r,{once:!0})})}function ce(e,t){return{id:t.id,image:e,detection:de(t),detectedLabel:t.detectedLabel,detectedBox:t.detectedBox?{...t.detectedBox}:void 0,boundsOverridden:t.boundsOverridden,manual:t.origin==="manual"}}function ue(e){return{id:e.id,label:e.detection.label,detectedLabel:e.detectedLabel,score:e.detection.score,box:{...e.detection.box},detectedBox:e.detectedBox?{...e.detectedBox}:void 0,origin:e.manual?"manual":"detected",boundsOverridden:e.boundsOverridden}}function me(e){return e.origin==="manual"||e.boundsOverridden===!0||!!(e.detectedLabel&&e.label!==e.detectedLabel)}function ge(e,t){return t.x>=e.left&&t.x<=e.left+e.width&&t.y>=e.top&&t.y<=e.top+e.height}var q=class{constructor(e={}){this.options=e,this.surfaceKind="image",this.records=new Map,this.imageKeys=new Map,this.analyzedSources=new WeakMap,this.pending=new WeakMap,this.analysisMetadata=new WeakMap,this.suppressions=new WeakMap,this.writeChains=new WeakMap,this.pendingWrites=new Set,this.refreshQueued=!1,this.destroyed=!1,this.manualSequence=0,this.id=e.id??"see:image",this.readyPromise=this.refresh();let t=e.root??document;this.observer=e.observe!==!1&&typeof MutationObserver<"u"?new MutationObserver(()=>this.queueRefresh()):null,this.observer?.observe(t,{childList:!0,subtree:!0,attributes:!0,attributeFilter:["src","srcset","sizes"]})}whenReady(){return this.readyPromise}listSubjects(){let e=[];for(let t of this.records.keys()){let i=this.resolve(t);i&&e.push(i)}return e}async refresh(){if(this.destroyed)return;let e=this.options.root??document,t=this.options.selector??H,i=new Set;e instanceof HTMLImageElement&&e.matches(t)&&i.add(e);for(let s of e.querySelectorAll(t))s instanceof HTMLImageElement&&i.add(s);for(let s of this.imageKeys.keys())(!i.has(s)||!s.isConnected)&&this.removeImage(s);if(this.options.recognition)for(let s of i)await this.analyze(s);else await Promise.all(Array.from(i,s=>this.analyze(s)))}hitTest(e){let t=null;for(let i of this.records.keys()){let s=this.resolve(i),r=this.records.get(i);if(!s||!r||!ge(s.bounds,e))continue;let a=s.bounds.width*s.bounds.height;(!t||a<t.area||a===t.area&&r.detection.score>t.score)&&(t={subject:s,area:a,score:r.detection.score})}return t?.subject??null}resolve(e){let t=this.records.get(e);if(!t||!t.image.isConnected)return null;let i=z(t.image,t.detection.box);if(!i)return null;let s=t.image.getBoundingClientRect(),r=Math.round(t.detection.score*1e3)/1e3;return{key:e,label:t.detection.label,sourceElement:t.image,imageObject:this.imageObjectContext(t),bounds:i,surfaceBounds:{left:s.left,top:s.top,width:s.width,height:s.height},context:`${t.detection.label} ${t.manual?"labelled":"detected"} in ${t.image.alt||"image"}`,data:{kind:"image-object",label:t.detection.label,origin:t.manual?"manual":"detected",...t.detectedLabel?{detectedLabel:t.detectedLabel}:{},score:String(r),imageSrc:p(t.image)}}}restoreSubject(e,t){if(this.records.has(e))return this.resolve(e);let i=t.imageObject;if(!i)return null;let s=t.sourceElement?.dataAttributes,r=s?.["data-popmelt-media-id"]??s?.["data-popmelt-see-id"],a=this.matchingImages().find(g=>{let f=p(g),y=this.imageIdentity(g,f);return!(!e.startsWith(`${y}:`)||r&&y!==r)});if(!a)return null;let o=this.imageIdentity(a,p(a)),n=e.slice(o.length+1),h={left:i.normalizedBox.x,top:i.normalizedBox.y,width:i.normalizedBox.width,height:i.normalizedBox.height};if(!n||!Object.values(h).every(g=>Number.isFinite(g)&&g>=0&&g<=1))return null;let d=t.dataAttributes,c=t.subjectLabel??d?.label??t.textContent;if(!c)return null;let l=Number(d?.score),u=d?.origin==="manual";this.records.set(e,{id:n,image:a,detection:{label:c,score:Number.isFinite(l)?l:1,box:h},detectedLabel:d?.detectedLabel,detectedBox:u?void 0:{...h},boundsOverridden:!0,manual:u});let m=this.imageKeys.get(a)??new Set;if(m.add(e),this.imageKeys.set(a,m),!this.analysisMetadata.has(a)){let g=R(a);this.analysisMetadata.set(a,{storeKey:`${this.id}:${o}`,source:g,imageHash:`recovered:${A(g)}`,inferenceKey:"",dedupeKey:""}),this.suppressions.set(a,[])}return this.persistImage(a),this.resolve(e)}imageObjectContext(e){let{image:t,detection:{box:i}}=e;return{src:p(t),alt:t.alt,width:t.naturalWidth,height:t.naturalHeight,normalizedBox:{x:i.left,y:i.top,width:i.width,height:i.height},box:{x:i.left*t.naturalWidth,y:i.top*t.naturalHeight,width:i.width*t.naturalWidth,height:i.height*t.naturalHeight}}}async captureSubject(e){let t=this.records.get(e);if(!t?.image.isConnected||!t.image.complete)return null;let{box:i}=this.imageObjectContext(t);if(i.width<=0||i.height<=0)return null;let s=Math.min(1,1024/Math.max(i.width,i.height)),r=document.createElement("canvas");r.width=Math.max(1,Math.round(i.width*s)),r.height=Math.max(1,Math.round(i.height*s));let a=r.getContext("2d");return a?(a.drawImage(t.image,i.x,i.y,i.width,i.height,0,0,r.width,r.height),new Promise((o,n)=>{try{r.toBlob(o,"image/webp",.95)}catch(h){n(h)}})):null}beginCreate(e){let t=this.matchingImages();for(let i=t.length-1;i>=0;i-=1){let s=t[i];if(!s)continue;let r=L(s,e);if(!r)continue;let a=p(s),o=this.imageIdentity(s,a),n=`manual:${this.newObjectId()}`,h=`${o}:${n}`,d={label:"object",score:1,box:{left:r.x,top:r.y,width:0,height:0}},c=!1,l=!1,u=()=>{if(l)return;l=!0,this.records.set(h,{id:n,image:s,detection:d,manual:!0});let m=this.imageKeys.get(s)??new Set;m.add(h),this.imageKeys.set(s,m)};return{key:h,update:m=>{if(c)return null;u();let g=this.clampedImagePoint(s,m);return g?(d.box={left:Math.min(r.x,g.x),top:Math.min(r.y,g.y),width:Math.abs(g.x-r.x),height:Math.abs(g.y-r.y)},this.resolve(h)):this.resolve(h)},commit:()=>c?null:(u(),this.persistImage(s),this.resolve(h)),cancel:()=>{c||(c=!0,l&&this.removeSubject(h))}}}return null}renameSubject(e,t){let i=this.records.get(e),s=t.trim();return!i||!s?null:(!i.manual&&!i.detectedLabel&&(i.detectedLabel=i.detection.label),i.detection.label=s,this.persistImage(i.image),this.resolve(e))}updateSubjectBounds(e,t){let i=this.records.get(e);if(!i)return null;let s=O(i.image,t);return s?(i.detection.box=s,i.boundsOverridden=!0,this.persistImage(i.image),this.resolve(e)):null}removeSubject(e){let t=this.records.get(e);if(!t)return;if(!t.manual){let s=this.suppressions.get(t.image)??[];s.push({detectedLabel:t.detectedLabel??t.detection.label,detectedBox:{...t.detectedBox??t.detection.box}}),this.suppressions.set(t.image,s)}this.records.delete(e);let i=this.imageKeys.get(t.image);i?.delete(e),i?.size===0&&this.imageKeys.delete(t.image),this.persistImage(t.image)}async destroy(){this.destroyed||(this.destroyed=!0,this.observer?.disconnect(),this.records.clear(),this.imageKeys.clear(),await Promise.allSettled(this.pendingWrites),await this.options.recognition?.dispose?.())}queueRefresh(){this.refreshQueued||this.destroyed||(this.refreshQueued=!0,queueMicrotask(()=>{this.refreshQueued=!1,this.readyPromise=this.refresh()}))}async analyze(e){let t=p(e);if(!t||this.analyzedSources.get(e)===t)return;let i=this.pending.get(e);if(i)return i.source===t?i.promise:(await i.promise,this.analyze(e));this.analyzedSources.has(e)&&this.removeImage(e);let s={source:t,promise:Promise.resolve()},r=(async()=>{try{if(await le(e),this.destroyed)return;let a=R(e),o=this.imageIdentity(e,t),n=`${this.id}:${o}`,h=this.options.recognition,d=this.options.store?await this.options.store.load(n):null;if(this.destroyed||p(e)!==t)return;let c=h?.cacheKey??d?.inferenceKey??"",l=h?.configurationKey??d?.dedupeKey??"",u=d?.source===a,m=!!(e.dataset.popmeltMediaId||e.dataset.popmeltSeeId),g=u||m;if(d&&g){let K=new Map(d.subjects.map(x=>[x.id,x]));for(let x of this.imageSubjects(e))K.set(x.id,x);this.replaceImageRecords(e,o,[...K.values()]),this.suppressions.set(e,[...d.suppressions??[]]),this.analysisMetadata.set(e,{storeKey:n,source:a,imageHash:d.imageHash,inferenceKey:d.inferenceKey,dedupeKey:d.dedupeKey})}if(this.options.hydrateOnly){this.analyzedSources.set(e,t);return}let f=this.options.store?await(this.options.imageHasher??he)(e):"ephemeral";if(this.destroyed||p(e)!==t)return;if(d&&g&&d.imageHash===f&&(!h||d.inferenceKey===c&&d.dedupeKey===l)){this.analysisMetadata.set(e,{storeKey:n,source:a,imageHash:f,inferenceKey:c,dedupeKey:l}),this.analyzedSources.set(e,t),await this.saveImage(e);return}let y=g&&d?.imageHash===f;if(d&&!y){let K=new Set(d.subjects.map(I=>I.id)),x=d.subjects.filter(me);this.replaceImageRecords(e,o,[...x,...this.imageSubjects(e).filter(I=>!K.has(I.id))]),this.suppressions.set(e,[])}if(this.analysisMetadata.set(e,{storeKey:n,source:a,imageHash:f,inferenceKey:y?d.inferenceKey:"",dedupeKey:y?d.dedupeKey:""}),!h){this.analyzedSources.set(e,t),await this.saveImage(e);return}let Z=await h.detect(e);if(this.destroyed||p(e)!==t)return;let E=this.suppressions.get(e)??[],ee=h.reconcile(Z,this.imageSubjects(e),E);this.replaceImageRecords(e,o,ee),this.suppressions.set(e,[...E]),this.analysisMetadata.set(e,{storeKey:n,source:a,imageHash:f,inferenceKey:c,dedupeKey:l}),this.analyzedSources.set(e,t),await this.saveImage(e)}catch(a){this.options.onError?.(a,e)}finally{this.pending.get(e)===s&&this.pending.delete(e)}})();return s.promise=r,this.pending.set(e,s),r}replaceImageRecords(e,t,i){this.removeImage(e);let s=new Set;for(let r of i){let a=`${t}:${r.id}`;s.add(a),this.records.set(a,ce(e,r))}this.imageKeys.set(e,s)}imageIdentity(e,t){if(e.dataset.popmeltMediaId)return e.dataset.popmeltMediaId;if(e.dataset.popmeltSeeId)return e.dataset.popmeltSeeId;let i=new URL(t,e.ownerDocument.baseURI).href,s=this.options.root??e.ownerDocument,r=this.options.selector??H,a=Array.from(s.querySelectorAll(r)).filter(n=>p(n)===t),o=Math.max(0,a.indexOf(e));return`${A(i)}:${o}`}matchingImages(){let e=this.options.root??document,t=this.options.selector??H,i=[];e instanceof HTMLImageElement&&e.matches(t)&&i.push(e);for(let s of e.querySelectorAll(t))s instanceof HTMLImageElement&&i.push(s);return i}clampedImagePoint(e,t){let i=z(e,{left:0,top:0,width:1,height:1});return i?L(e,{x:Math.max(i.left,Math.min(i.left+i.width,t.x)),y:Math.max(i.top,Math.min(i.top+i.height,t.y))}):null}newObjectId(){return globalThis.crypto?.randomUUID?.()||A(`${Date.now()}:${this.manualSequence++}:${Math.random().toString(36)}`)}persistImage(e){let t=this.persistencePayload(e);if(!t)return Promise.resolve();let i=(this.writeChains.get(e)??Promise.resolve()).catch(()=>{}).then(()=>t.store.save(t.key,t.analysis)).catch(s=>{this.options.onError?.(s,e)});return this.writeChains.set(e,i),this.pendingWrites.add(i),i.finally(()=>this.pendingWrites.delete(i)),i}async saveImage(e){await this.persistImage(e)}imageSubjects(e){return Array.from(this.imageKeys.get(e)??[]).map(t=>this.records.get(t)).filter(t=>!!t).map(ue)}persistencePayload(e){let t=this.options.store,i=this.analysisMetadata.get(e);if(!t||!i)return null;let s=this.imageSubjects(e),r={schemaVersion:1,source:i.source,imageHash:i.imageHash,inferenceKey:i.inferenceKey,dedupeKey:i.dedupeKey,subjects:s,suppressions:this.suppressions.get(e)??[],updatedAt:Date.now()};return{store:t,key:i.storeKey,analysis:r}}removeImage(e){for(let t of this.imageKeys.get(e)??[])this.records.delete(t);this.imageKeys.delete(e),this.analyzedSources.delete(e),this.analysisMetadata.delete(e),this.suppressions.delete(e)}};function fe(e={}){return new q(e)}var w=(e,t=0,i=1)=>Math.min(i,Math.max(t,e));function B(e){let t=e.getBoundingClientRect();if(t.width<=0||t.height<=0||e.videoWidth<=0||e.videoHeight<=0)return null;let i=e.ownerDocument.defaultView?.getComputedStyle(e)??getComputedStyle(e),s=i.objectFit||"fill",r=Math.min(t.width/e.videoWidth,t.height/e.videoHeight),a=Math.max(t.width/e.videoWidth,t.height/e.videoHeight),o=s==="contain"?r:s==="cover"?a:s==="none"?1:s==="scale-down"?Math.min(1,r):null,n=o?{width:e.videoWidth*o,height:e.videoHeight*o}:{width:t.width,height:t.height},h=(i.objectPosition||"50% 50%").split(/\s+/),d=(c,l)=>c.endsWith("%")?l*(Number.parseFloat(c)/100):c.endsWith("px")?Number.parseFloat(c):c==="center"?l/2:c==="right"||c==="bottom"?l:0;return{rect:t,rendered:n,position:{x:d(h[0]||"50%",t.width-n.width),y:d(h[1]||"50%",t.height-n.height)}}}function j(e,t){let i=B(e);if(!i)return null;let{rect:s,rendered:r,position:a}=i;if(t.x<s.left||t.x>s.right||t.y<s.top||t.y>s.bottom)return null;let o=(t.x-s.left-a.x)/r.width,n=(t.y-s.top-a.y)/r.height;return o>=0&&o<=1&&n>=0&&n<=1?{x:o,y:n}:null}function D(e,t){let i=B(e);if(!i)return null;let{rect:s,rendered:r,position:a}=i,o=s.left+a.x+w(t.left)*r.width,n=s.top+a.y+w(t.top)*r.height,h=s.left+a.x+w(t.left+Math.max(0,t.width))*r.width,d=s.top+a.y+w(t.top+Math.max(0,t.height))*r.height,c=Math.max(s.left,o),l=Math.max(s.top,n),u=Math.min(s.right,h),m=Math.min(s.bottom,d);return u<=c||m<=l?null:{left:c,top:l,width:u-c,height:m-l}}function U(e,t){let i=B(e);if(!i)return null;let{rect:s,rendered:r,position:a}=i,o=(t.left-s.left-a.x)/r.width,n=(t.top-s.top-a.y)/r.height,h=(t.left+t.width-s.left-a.x)/r.width,d=(t.top+t.height-s.top-a.y)/r.height,c=w(Math.min(o,h)),l=w(Math.min(n,d)),u=w(Math.max(o,h)),m=w(Math.max(n,d));return u<=c||m<=l?null:{left:c,top:l,width:u-c,height:m-l}}var ye="video",pe=1/60,Q=30,be=.9,ve=250,M=.001;function $(e){let t=2166136261;for(let i=0;i<e.length;i+=1)t^=e.charCodeAt(i),t=Math.imul(t,16777619);return(t>>>0).toString(36)}function b(e){return e.currentSrc||e.src||e.querySelector("source")?.src||e.getAttribute("src")||""}function we(e){return e.readyState>=1&&e.videoWidth>0&&e.videoHeight>0?Promise.resolve():new Promise((t,i)=>{let s=()=>{a(),t()},r=()=>{a(),i(new Error(`Unable to load video: ${b(e)}`))},a=()=>{e.removeEventListener("loadedmetadata",s),e.removeEventListener("error",r)};e.addEventListener("loadedmetadata",s,{once:!0}),e.addEventListener("error",r,{once:!0})})}function xe(e,t,i){let s=(r,a)=>r+(a-r)*i;return{left:s(e.left,t.left),top:s(e.top,t.top),width:s(e.width,t.width),height:s(e.height,t.height)}}function T(e,t){return e.find(i=>t>=i.start-.001&&(i.end===void 0||t<=i.end+.001))??null}function V(e){return!T(e.segments,e.video.currentTime)}function k(e){return e?.motion.createSmoother()??{smooth(t){return{...t,box:{...t.box}}}}}function J(e){return{visible:!V(e),misses:e.misses,hits:e.hits,lostAt:e.lostAt}}function ke(e,t){e.misses=t.misses,e.hits=t.hits,e.lostAt=t.lostAt}function Me(e,t){if(t?.length)return t.map(s=>({...s})).sort((s,r)=>s.start-r.start);let i=e.reduce((s,r)=>Math.min(s,r.time),Number.POSITIVE_INFINITY);return Number.isFinite(i)?[{start:i}]:[]}function S(e,t,i){if(e.length===0||i&&!T(i,t))return null;let s=[...e].sort((d,c)=>d.time-c.time),r=s.findIndex(d=>d.time>=t);if(r<=0)return{...s[0],box:{...s[0].box}};if(r<0){let d=s[s.length-1];return{...d,box:{...d.box}}}let a=s[r-1],o=s[r],n=Math.max(Number.EPSILON,o.time-a.time),h=Math.max(0,Math.min(1,(t-a.time)/n));return{time:t,box:xe(a.box,o.box,h),score:a.score+(o.score-a.score)*h,source:a.source==="manual"||o.source==="manual"?"manual":"tracked"}}function W(e){return!e.video.paused&&e.liveFrame?{...e.liveFrame,box:{...e.liveFrame.box}}:S(e.presentationKeyframes,e.video.currentTime,e.segments)}function Te(e,t){return t.x>=e.left&&t.x<=e.left+e.width&&t.y>=e.top&&t.y<=e.top+e.height}function G(e,t){if(!Te(e.bounds,t))return!1;let i=e.outline;if(!i||i.length<3)return!0;let s=(t.x-e.bounds.left)/e.bounds.width,r=(t.y-e.bounds.top)/e.bounds.height,a=!1;for(let o=0,n=i.length-1;o<i.length;n=o++){let h=i[o],d=i[n];h.y>r!=d.y>r&&s<(d.x-h.x)*(r-h.y)/(d.y-h.y)+h.x&&(a=!a)}return a}function Se(e){let t=e.outline;if(!t||t.length<3)return e.bounds.width*e.bounds.height;let i=0;for(let s=0;s<t.length;s+=1){let r=t[s],a=t[(s+1)%t.length];i+=r.x*a.y-a.x*r.y}return Math.abs(i)/2*e.bounds.width*e.bounds.height}function Y(e,t){return(t.outline?.length?t.outline.map(i=>({x:t.bounds.left+i.x*t.bounds.width,y:t.bounds.top+i.y*t.bounds.height})):[{x:t.bounds.left,y:t.bounds.top},{x:t.bounds.left+t.bounds.width,y:t.bounds.top},{x:t.bounds.left+t.bounds.width,y:t.bounds.top+t.bounds.height},{x:t.bounds.left,y:t.bounds.top+t.bounds.height}]).every(i=>G(e,i))}function Ke(e,t){let i=Math.max(e.left,t.left),s=Math.max(e.top,t.top),r=Math.min(e.left+e.width,t.left+t.width),a=Math.min(e.top+e.height,t.top+t.height),o=Math.max(0,r-i)*Math.max(0,a-s),n=e.width*e.height+t.width*t.height-o;return n>0?o/n:0}var _=class{constructor(e={}){this.options=e,this.surfaceKind="video",this.records=new Map,this.videoKeys=new Map,this.metadata=new WeakMap,this.analyzedSources=new WeakMap,this.listeners=new Map,this.frameHandles=new Map,this.persistTimers=new Map,this.writeChains=new WeakMap,this.pendingWrites=new Set,this.refreshQueued=!1,this.destroyed=!1,this.manualSequence=0,this.detectedSequence=0,this.activeTrackingKey=null,this.segmentationGeneration=0,this.transientKeys=new Set,this.segmentationRequestSignatures=new WeakMap,this.changeListeners=new Set,this.id=e.id??"see:video",this.readyPromise=this.refresh();let t=e.root??document;this.observer=e.observe!==!1&&typeof MutationObserver<"u"?new MutationObserver(()=>this.queueRefresh()):null,this.observer?.observe(t,{childList:!0,subtree:!0,attributes:!0,attributeFilter:["src"]})}whenReady(){return this.readyPromise}subscribe(e){return this.changeListeners.add(e),()=>this.changeListeners.delete(e)}listSubjects(){return Array.from(this.records.keys(),e=>this.transientKeys.has(e)?null:this.resolve(e)).filter(e=>!!e)}async refresh(){if(this.destroyed)return;let e=new Set(this.matchingVideos());for(let t of this.videoKeys.keys())(!e.has(t)||!t.isConnected)&&this.removeVideo(t);await Promise.all(Array.from(e,t=>this.analyze(t)))}hitTest(e){return this.hitTestAll(e)[0]??null}hitTestAll(e){let t=[];for(let i of this.records.keys()){let s=this.resolve(i);!s||!G(s,e)||t.push({subject:s,area:Se(s)})}return this.options.segmentation&&this.scheduleSegmentation(e),t.sort((i,s)=>Y(i.subject,s.subject)?1:Y(s.subject,i.subject)?-1:i.area-s.area).map(({subject:i})=>i)}promoteSubject(e){let t=this.records.get(e);return t?this.transientKeys.delete(e)?(this.activateTrackingRecord(t),this.persistVideo(t.video),this.startSession(t,!0).then(()=>this.scheduleBackwardAnalysis(t)),this.resolve(e)):this.resolve(e):null}resolve(e){let t=this.records.get(e);if(!t?.video.isConnected)return null;let i=W(t);if(!i)return null;let s=D(t.video,i.box);if(!s)return null;let r=t.video.getBoundingClientRect();return{key:e,label:t.label,sourceElement:t.video,videoObject:this.videoObjectContext(t,i),trackingAnchors:t.anchors.map(a=>({...a})),outline:i.outline?.map(a=>({...a})),bounds:s,surfaceBounds:{left:r.left,top:r.top,width:r.width,height:r.height},context:`${t.label} tracked in video at ${t.video.currentTime.toFixed(2)}s`,data:{kind:"video-object",label:t.label,origin:t.origin,score:String(Math.round(i.score*1e3)/1e3),videoSrc:b(t.video),currentTime:String(t.video.currentTime)}}}async captureSubject(e){let t=this.records.get(e);if(!t||t.video.readyState<2)return null;let i=W(t);if(!i)return null;let{video:s}=t,r={x:i.box.left*s.videoWidth,y:i.box.top*s.videoHeight,width:i.box.width*s.videoWidth,height:i.box.height*s.videoHeight},a=Math.min(1,1024/Math.max(r.width,r.height)),o=document.createElement("canvas");o.width=Math.max(1,Math.round(r.width*a)),o.height=Math.max(1,Math.round(r.height*a));let n=o.getContext("2d");return n?(n.drawImage(s,r.x,r.y,r.width,r.height,0,0,o.width,o.height),new Promise((h,d)=>{try{o.toBlob(h,"image/webp",.95)}catch(c){d(c)}})):null}beginCreate(e){let t=this.matchingVideos();for(let i=t.length-1;i>=0;i-=1){let s=t[i];if(!s)continue;let r=j(s,e);if(!r)continue;let a=this.videoIdentity(s),o=`manual:${this.newObjectId()}`,n=`${a}:${o}`,h=Date.now(),d={time:s.currentTime,box:{left:r.x,top:r.y,width:0,height:0},score:1,source:"manual"},c=k(this.options.tracking),l={key:n,id:o,video:s,label:"object",origin:"manual",keyframes:[d],segments:[{start:s.currentTime}],anchors:[],presentationKeyframes:[c.smooth(d)],smoother:c,createdAt:h,updatedAt:h,misses:0,hits:0,analyzedThrough:d.time},u=!1,m=!1,g=()=>{if(m)return;m=!0,this.records.set(n,l);let f=this.videoKeys.get(s)??new Set;f.add(n),this.videoKeys.set(s,f)};return{key:n,update:f=>{if(u)return null;g();let y=j(s,f);return y&&(d.box={left:Math.min(r.x,y.x),top:Math.min(r.y,y.y),width:Math.abs(y.x-r.x),height:Math.abs(y.y-r.y)},l.smoother=k(this.options.tracking),l.presentationKeyframes=[l.smoother.smooth(d)]),this.resolve(n)},commit:()=>u?null:(g(),l.backwardSeedTime=d.time,this.activateTrackingRecord(l),this.persistVideo(s),this.startSession(l,!0).then(()=>this.scheduleBackwardAnalysis(l)),this.resolve(n)),cancel:()=>{u||(u=!0,m&&this.removeSubject(n))}}}return null}renameSubject(e,t){let i=this.records.get(e),s=t.trim();return!i||!s?null:(i.label=s,i.updatedAt=Date.now(),this.activateTrackingRecord(i),this.persistVideo(i.video),this.resolve(e))}updateSubjectBounds(e,t){let i=this.records.get(e);if(!i)return null;let s=U(i.video,t);if(!s)return null;this.openSegment(i,i.video.currentTime),this.insertKeyframe(i,{time:i.video.currentTime,box:s,score:1,source:"manual"}),i.liveFrame=void 0,i.trackingFailed=!1,i.misses=0,i.hits=0,i.lostAt=void 0,i.analyzedThrough=i.video.currentTime;let r=T(i.segments,i.video.currentTime);return r&&Math.abs(r.start-i.video.currentTime)<=.05&&(i.backwardSeedTime=i.video.currentTime,this.cancelBackwardAnalysis(i)),this.activateTrackingRecord(i),this.persistVideo(i.video),this.startSession(i,!0).then(()=>this.reseed(i)).then(()=>this.scheduleBackwardAnalysis(i)),this.resolve(e)}updateSubjectTrackingAnchors(e,t){let i=this.records.get(e);return i?(i.anchors=t.slice(0,3).map(s=>({x:Math.max(0,Math.min(1,s.x)),y:Math.max(0,Math.min(1,s.y))})),i.updatedAt=Date.now(),i.trackingFailed=!1,i.analyzedThrough=i.video.currentTime,i.backwardSeedTime!==void 0&&this.cancelBackwardAnalysis(i),this.activateTrackingRecord(i),this.persistVideo(i.video),this.startSession(i,!0).then(()=>this.reseed(i)).then(()=>this.scheduleBackwardAnalysis(i)),this.resolve(e)):null}removeSubject(e){let t=this.records.get(e);if(!t)return;this.cancelBackwardAnalysis(t),t.session?.dispose?.(),this.activeTrackingKey===e&&(this.activeTrackingKey=null),this.transientKeys.delete(e),this.records.delete(e);let i=this.videoKeys.get(t.video);i?.delete(e),i?.size===0&&this.videoKeys.delete(t.video),this.persistVideo(t.video)}async destroy(){if(this.destroyed)return;this.destroyed=!0,this.observer?.disconnect();for(let t of this.listeners.keys())this.removeVideoListeners(t);await Promise.all(Array.from(this.persistTimers.keys(),t=>this.flushScheduledPersistence(t)));let e=Array.from(this.records.values(),t=>t.backwardAnalysis?.promise).filter(t=>!!t);await Promise.allSettled(Array.from(this.records.values(),t=>(this.cancelBackwardAnalysis(t),t.session?.dispose?.()))),await Promise.allSettled(e),this.records.clear(),this.videoKeys.clear(),this.changeListeners.clear(),await Promise.allSettled(this.pendingWrites)}scheduleSegmentation(e){let t=this.options.segmentation;if(!t||this.destroyed)return;let i=this.matchingVideos();for(let s=i.length-1;s>=0;s-=1){let r=i[s];if(!r||r.readyState<2)continue;let a=j(r,e);if(!a)continue;let o=[Math.round(r.currentTime*30),Math.round(a.x*256),Math.round(a.y*256)].join(":");if(this.segmentationRequestSignatures.get(r)===o)return;this.segmentationRequestSignatures.set(r,o);let n=++this.segmentationGeneration,h=r.currentTime;t.segment(r,h,a).then(d=>{if(!d||this.destroyed||n!==this.segmentationGeneration||!r.isConnected)return;let c=Array.from(this.videoKeys.get(r)??[]).map(l=>this.records.get(l)).filter(l=>!!l).find(l=>{let u=W(l);return u&&Ke(u.box,d.box)>=.65});this.clearTransientSubjects(r,c?.key),c||this.addDetectedSubject(r,h,d);for(let l of this.changeListeners)l()}).catch(d=>this.options.onError?.(d,r));return}}addDetectedSubject(e,t,i){let s=this.videoIdentity(e),r=`detected:${$([t.toFixed(3),i.box.left.toFixed(4),i.box.top.toFixed(4),i.box.width.toFixed(4),i.box.height.toFixed(4),this.detectedSequence++].join(":"))}`,a=`${s}:${r}`,o=e.currentTime,n={time:o,box:{...i.box},score:i.score,source:"tracked",outline:i.outline?.map(u=>({...u}))},h=k(this.options.tracking),d=Date.now(),c={key:a,id:r,video:e,label:i.label?.trim()||"object",origin:"detected",keyframes:[n],segments:[{start:o}],anchors:[],presentationKeyframes:[h.smooth(n)],smoother:h,createdAt:d,updatedAt:d,misses:0,hits:0,analyzedThrough:o,backwardSeedTime:o};this.records.set(a,c),this.transientKeys.add(a);let l=this.videoKeys.get(e)??new Set;l.add(a),this.videoKeys.set(e,l)}clearTransientSubjects(e,t){let i=this.videoKeys.get(e);if(i)for(let s of[...i])s===t||!this.transientKeys.delete(s)||(this.records.delete(s),i.delete(s))}async analyze(e){let t=b(e);if(!(!t||this.analyzedSources.get(e)===t))try{if(await we(e),this.destroyed||b(e)!==t)return;let i=this.videoIdentity(e),s=new URL(t,e.ownerDocument.baseURI).href,r=`${this.id}:${i}`,a=this.options.store?await this.options.store.load(r):null;if(this.destroyed||b(e)!==t)return;this.metadata.set(e,{storeKey:r,source:s,identity:i});let o=!!e.dataset.popmeltMediaId;a&&(a.source===s||o)?this.replaceVideoRecords(e,i,a.tracks):this.videoKeys.has(e)||this.videoKeys.set(e,new Set),this.analyzedSources.set(e,t),this.addVideoListeners(e)}catch(i){this.options.onError?.(i,e)}}addVideoListeners(e){if(this.listeners.has(e))return;let t=()=>{this.clearLiveFrames(e),this.activateMostRecentRecord(e);let a=this.activeRecordFor(e);if(this.options.tracking&&a&&!a.session&&(a.analyzedThrough===void 0||a.analyzedThrough<e.duration-M)){let o=this.startSession(a,!0);e.pause(),o.then(()=>{!this.destroyed&&a.session&&e.play()});return}a&&this.scheduleBackwardAnalysis(a),this.scheduleFrame(e)},i=()=>{this.clearLiveFrames(e);let a=this.activeRecordFor(e);a&&this.scheduleBackwardAnalysis(a),this.flushScheduledPersistence(e)},s=()=>{let a=this.activeRecordFor(e);a?.lastTrackedMediaTime!==void 0&&(a.analyzedThrough=e.duration,a.lastTrackedMediaTime=void 0,a.session?.dispose?.(),a.session=void 0,this.schedulePersistence(e)),i()},r=()=>{let a=this.activeRecordFor(e);if(!a)return;let o=a.lastTrackedMediaTime;if(e.loop&&o!==void 0&&o>=e.duration-.25&&e.currentTime+.25<o&&(a.analyzedThrough??0)>=o-.25){S(a.presentationKeyframes,e.currentTime,a.segments)&&(a.liveFrame=void 0),a.analyzedThrough=Math.max(0,e.currentTime-M*2),a.lastTrackedMediaTime=void 0;let n=a.session;a.session=void 0,Promise.resolve(a.tracking).finally(async()=>{await n?.dispose?.(),!(this.destroyed||this.activeTrackingKey!==a.key)&&(await this.startSession(a),this.scheduleBackwardAnalysis(a))}),this.schedulePersistence(e);return}this.clearLiveFrames(e),a.session&&this.reseed(a)};e.addEventListener("play",t),e.addEventListener("pause",i),e.addEventListener("ended",s),e.addEventListener("seeked",r),this.listeners.set(e,()=>{e.removeEventListener("play",t),e.removeEventListener("pause",i),e.removeEventListener("ended",s),e.removeEventListener("seeked",r)}),e.paused||(this.activateMostRecentRecord(e),this.scheduleFrame(e))}removeVideoListeners(e){this.listeners.get(e)?.(),this.listeners.delete(e);let t=e,i=this.frameHandles.get(e);i!==void 0&&(t.cancelVideoFrameCallback?.(i),cancelAnimationFrame(i)),this.frameHandles.delete(e)}scheduleFrame(e){if(this.destroyed||e.paused||this.frameHandles.has(e))return;let t=e,i=(s,r)=>{this.frameHandles.delete(e),this.trackVideo(e,r.mediaTime),this.scheduleFrame(e)};t.requestVideoFrameCallback?this.frameHandles.set(e,t.requestVideoFrameCallback(i)):this.frameHandles.set(e,requestAnimationFrame(()=>i(performance.now(),{mediaTime:e.currentTime})))}async trackVideo(e,t){let i=this.activeRecordFor(e);if(!i||i.tracking||i.trackingFailed||i.analyzedThrough!==void 0&&t<=i.analyzedThrough+M)return;let s=this.options.tracking?.motion;if(!s)return;let r=s.attempt({state:J(i),time:t,maximumFramesPerSecond:Math.max(1,this.options.maxTrackingFramesPerSecond??Q)});i.lastTrackedMediaTime!==void 0&&Math.abs(t-i.lastTrackedMediaTime)<be/r.framesPerSecond||(i.session||await this.startSession(i),!(!i.session||this.activeTrackingKey!==i.key)&&(i.lastTrackedMediaTime=t,i.tracking=i.session.track(e,t,r.tracking).then(a=>{if(this.destroyed||this.activeTrackingKey!==i.key)return;i.analyzedThrough=Math.max(i.analyzedThrough??t,t);let o=s.observe({state:J(i),time:t,observation:a});ke(i,o.state),a&&o.action==="reopen"&&this.openSegment(i,t),a&&(o.action==="accept"||o.action==="reopen")?this.acceptObservation(i,{...a,source:"tracked"}):o.action==="close"&&(i.liveFrame=void 0,this.closeSegment(i,i.keyframes[i.keyframes.length-1]?.time??t)),this.schedulePersistence(e)}).catch(a=>this.failTracking(i,a)).finally(()=>{i.tracking=void 0}),await i.tracking))}async startSession(e,t=!1){if(e.initializing){await e.initializing;return}if(!this.options.tracking||e.session||e.trackingFailed||this.activeTrackingKey!==e.key||e.video.paused&&!t)return;let i=S(e.keyframes,e.video.currentTime,e.segments)??e.liveFrame;!i||e.video.readyState<2||(e.initializing=this.options.tracking.createSession({video:e.video,time:e.video.currentTime,box:i.box,anchors:e.anchors}).then(s=>{this.destroyed||this.activeTrackingKey!==e.key?s.dispose?.():e.session=s}).catch(s=>this.failTracking(e,s)).finally(()=>{e.initializing=void 0}),await e.initializing)}async reseed(e){let t=S(e.keyframes,e.video.currentTime,e.segments);if(!t){e.session?.dispose?.(),e.session=void 0,e.lostAt=e.video.currentTime,e.liveFrame=void 0,e.misses=0,e.hits=0;return}e.lostAt=void 0,e.misses=0,e.hits=0;try{e.session?.reseed&&await e.session.reseed({video:e.video,time:e.video.currentTime,box:t.box,anchors:e.anchors})}catch(i){this.failTracking(e,i)}}failTracking(e,t){e.trackingFailed=!0,e.liveFrame=void 0,e.session?.dispose?.(),e.session=void 0,this.options.onError?.(t,e.video)}activeRecordFor(e){if(!this.activeTrackingKey)return null;let t=this.records.get(this.activeTrackingKey);return t?.video===e?t:null}activateMostRecentRecord(e){if(this.activeRecordFor(e))return;let t=Array.from(this.videoKeys.get(e)??[]).map(i=>this.records.get(i)).filter(i=>!!i).sort((i,s)=>s.updatedAt-i.updatedAt)[0];t&&this.activateTrackingRecord(t)}activateTrackingRecord(e){if(this.activeTrackingKey===e.key)return;let t=this.activeTrackingKey?this.records.get(this.activeTrackingKey):void 0;this.activeTrackingKey=e.key,t&&(this.cancelBackwardAnalysis(t),t.session?.dispose?.(),t.session=void 0,t.lastTrackedMediaTime=void 0,t.liveFrame=void 0),e.liveFrame=void 0,e.trackingFailed=!1,e.lastTrackedMediaTime=void 0,e.misses=0,e.hits=0,e.lostAt=V(e)?e.video.currentTime:void 0}scheduleBackwardAnalysis(e){if(this.destroyed||!this.options.tracking||e.backwardSeedTime===void 0||e.backwardSeedTime<=M||e.backwardAnalysis||e.initializing||this.activeTrackingKey!==e.key)return;let t={cancelled:!1,promise:Promise.resolve()};e.backwardAnalysis=t,t.promise=this.runBackwardAnalysis(e,t).catch(i=>{t.cancelled||this.options.onError?.(i,e.video)}).finally(()=>{e.backwardAnalysis===t&&(e.backwardAnalysis=void 0,!t.cancelled&&e.backwardSeedTime!==void 0&&(e.backwardSeedTime=void 0),t.cancelled&&!this.destroyed&&this.activeTrackingKey===e.key&&queueMicrotask(()=>this.scheduleBackwardAnalysis(e)))})}cancelBackwardAnalysis(e){let t=e.backwardAnalysis;t&&(t.cancelled=!0)}async runBackwardAnalysis(e,t){let i=e.backwardSeedTime;if(i===void 0)return;let s=await this.options.tracking.motion.analyzeBackward({source:e.video,seedTime:i,keyframes:e.keyframes,anchors:e.anchors,maximumFramesPerSecond:this.options.maxTrackingFramesPerSecond??Q,cancelled:()=>t.cancelled||this.destroyed,forwardWork:()=>e.initializing??e.tracking});if(t.cancelled||this.destroyed)return;let r=T(e.segments,i);r&&(e.keyframes=s.keyframes,r.start=Math.min(r.start,s.earliestTime),e.updatedAt=Date.now(),this.rebuildPresentationTrack(e),this.schedulePersistence(e.video))}acceptObservation(e,t){let i=[...e.keyframes].reverse().find(r=>r.outline?.length)?.outline,s=this.insertKeyframe(e,{...t,outline:t.outline??i});return e.video.paused||(e.liveFrame={...s,box:{...s.box}}),!0}openSegment(e,t){if(T(e.segments,t))return!1;let i=e.segments[e.segments.length-1];return i&&i.end===void 0&&t>=i.start?!1:(e.segments.push({start:t}),e.segments.sort((s,r)=>s.start-r.start),e.smoother=k(this.options.tracking),!0)}closeSegment(e,t){let i=[...e.segments].reverse().find(s=>s.end===void 0);return i?(i.end=Math.max(i.start,t),e.updatedAt=Date.now(),!0):!1}insertKeyframe(e,t){let i={...t,box:{...t.box}},s=e.keyframes.findIndex(a=>Math.abs(a.time-t.time)<.001),r=!1;if(s>=0)e.keyframes[s]=i;else{let a=e.keyframes[e.keyframes.length-1];if(t.source==="tracked"&&a&&Math.abs(t.time-a.time)<pe)e.keyframes[e.keyframes.length-1]=i;else if(!a||t.time>a.time){e.keyframes.push(i);let o=e.smoother.smooth(i);e.presentationKeyframes.push(o),r=!0}else e.keyframes.push(i)}return r||this.rebuildPresentationTrack(e),e.updatedAt=Date.now(),S(e.presentationKeyframes,t.time)??{...i,box:{...i.box}}}rebuildPresentationTrack(e){e.keyframes.sort((s,r)=>s.time-r.time);let t=k(this.options.tracking),i=null;e.presentationKeyframes=e.keyframes.map(s=>{let r=T(e.segments,s.time);return r&&r!==i&&(t=k(this.options.tracking),i=r),t.smooth(s)}),e.smoother=t}clearLiveFrames(e){for(let t of this.videoKeys.get(e)??[]){let i=this.records.get(t);i&&(i.liveFrame=void 0)}}videoObjectContext(e,t){let{video:i}=e,s=e.keyframes.map(r=>r.time);return{src:b(i),width:i.videoWidth,height:i.videoHeight,duration:i.duration,currentTime:i.currentTime,normalizedBox:{x:t.box.left,y:t.box.top,width:t.box.width,height:t.box.height},box:{x:t.box.left*i.videoWidth,y:t.box.top*i.videoHeight,width:t.box.width*i.videoWidth,height:t.box.height*i.videoHeight},trackStart:Math.min(...s),trackEnd:Math.max(...s)}}replaceVideoRecords(e,t,i){this.removeVideoRecords(e);let s=new Set;for(let r of i){let a=`${t}:${r.id}`,o=r.keyframes.map(l=>({...l,box:{...l.box}})),n=Me(o,r.segments),h=o[0],d=k(this.options.tracking);s.add(a);let c={key:a,id:r.id,video:e,label:r.label,origin:r.origin,keyframes:o,segments:n,anchors:(r.anchors??[]).map(l=>({...l})),presentationKeyframes:[],smoother:d,createdAt:r.createdAt,updatedAt:r.updatedAt,misses:0,hits:0,analyzedThrough:r.analyzedThrough,backwardSeedTime:h?.source==="manual"&&h.time>M&&(n[0]?.start??-1)>=h.time-M?h.time:void 0};V(c)&&(c.lostAt=e.currentTime),this.rebuildPresentationTrack(c),r.presentationKeyframes?.length&&(c.presentationKeyframes=r.presentationKeyframes.map(l=>({...l,box:{...l.box}}))),this.records.set(a,c)}this.videoKeys.set(e,s)}persistVideo(e){let t=this.persistTimers.get(e);t!==void 0&&clearTimeout(t),this.persistTimers.delete(e);let i=this.options.store,s=this.metadata.get(e);if(!i||!s)return Promise.resolve();let r=Array.from(this.videoKeys.get(e)??[]).map(n=>this.records.get(n)).filter(n=>!!n).map(n=>({id:n.id,label:n.label,origin:n.origin,keyframes:n.keyframes.map(h=>({...h,box:{...h.box}})),presentationKeyframes:n.presentationKeyframes.map(h=>({...h,box:{...h.box}})),anchors:n.anchors.map(h=>({...h})),segments:n.segments.map(h=>({...h})),analyzedThrough:n.analyzedThrough,createdAt:n.createdAt,updatedAt:n.updatedAt})),a={schemaVersion:3,source:s.source,duration:Number.isFinite(e.duration)?e.duration:0,tracks:r,updatedAt:Date.now()},o=(this.writeChains.get(e)??Promise.resolve()).catch(()=>{}).then(()=>i.save(s.storeKey,a)).catch(n=>this.options.onError?.(n,e));return this.writeChains.set(e,o),this.pendingWrites.add(o),o.finally(()=>this.pendingWrites.delete(o)),o}schedulePersistence(e){!this.options.store||this.persistTimers.has(e)||this.persistTimers.set(e,setTimeout(()=>{this.persistTimers.delete(e),this.persistVideo(e)},ve))}flushScheduledPersistence(e){return this.persistTimers.has(e)?this.persistVideo(e):Promise.resolve()}matchingVideos(){let e=this.options.root??document,t=this.options.selector??ye,i=[];e instanceof HTMLVideoElement&&e.matches(t)&&i.push(e);for(let s of e.querySelectorAll(t))s instanceof HTMLVideoElement&&i.push(s);return i}videoIdentity(e){if(e.dataset.popmeltMediaId)return e.dataset.popmeltMediaId;let t=new URL(b(e),e.ownerDocument.baseURI).href,i=this.matchingVideos().filter(s=>b(s)===b(e));return`${$(t)}:${Math.max(0,i.indexOf(e))}`}newObjectId(){return globalThis.crypto?.randomUUID?.()??$(`${Date.now()}:${this.manualSequence++}:${Math.random()}`)}removeVideoRecords(e){for(let t of this.videoKeys.get(e)??[]){let i=this.records.get(t);i&&this.cancelBackwardAnalysis(i),i?.session?.dispose?.(),this.activeTrackingKey===t&&(this.activeTrackingKey=null),this.transientKeys.delete(t),this.records.delete(t)}this.videoKeys.delete(e)}removeVideo(e){this.removeVideoListeners(e),this.flushScheduledPersistence(e),this.removeVideoRecords(e),this.metadata.delete(e),this.analyzedSources.delete(e)}queueRefresh(){this.refreshQueued||this.destroyed||(this.refreshQueued=!0,queueMicrotask(()=>{this.refreshQueued=!1,this.readyPromise=this.refresh()}))}};function Ae(e={}){return new _(e)}var je="popmelt:media:video:v1";function X(e){if(!e||typeof e!="object")return!1;let t=e;return["left","top","width","height"].every(i=>typeof t[i]=="number"&&Number.isFinite(t[i]))}function Ie(e){if(!e||typeof e!="object")return!1;let t=e;return typeof t.start=="number"&&Number.isFinite(t.start)&&(t.end===void 0||typeof t.end=="number"&&Number.isFinite(t.end)&&t.end>=t.start)}function Fe(e){if(!e||typeof e!="object")return!1;let t=e;return(t.schemaVersion===1||t.schemaVersion===2||t.schemaVersion===3)&&typeof t.source=="string"&&typeof t.duration=="number"&&typeof t.updatedAt=="number"&&Array.isArray(t.tracks)&&t.tracks.every(i=>{if(!i||typeof i!="object")return!1;let s=i;return typeof s.id=="string"&&typeof s.label=="string"&&(s.origin==="manual"||s.origin==="detected")&&typeof s.createdAt=="number"&&typeof s.updatedAt=="number"&&(s.analyzedThrough===void 0||typeof s.analyzedThrough=="number"&&Number.isFinite(s.analyzedThrough))&&(s.segments===void 0||Array.isArray(s.segments)&&s.segments.every(Ie))&&Array.isArray(s.keyframes)&&s.keyframes.every(r=>{if(!r||typeof r!="object")return!1;let a=r;return typeof a.time=="number"&&typeof a.score=="number"&&(a.source==="manual"||a.source==="tracked")&&X(a.box)})&&(s.presentationKeyframes===void 0||Array.isArray(s.presentationKeyframes)&&s.presentationKeyframes.every(r=>{if(!r||typeof r!="object")return!1;let a=r;return typeof a.time=="number"&&typeof a.score=="number"&&(a.source==="manual"||a.source==="tracked")&&X(a.box)}))})}function Le(e={}){let t=e.namespace??je,i=()=>e.storage??window.localStorage,s=r=>`${t}:${r}`;return{load(r){try{let a=i().getItem(s(r));if(!a)return null;let o=JSON.parse(a);return Fe(o)?o:null}catch{return null}},save(r,a){i().setItem(s(r),JSON.stringify(a))},remove(r){i().removeItem(s(r))}}}function ze(){let e=new Map;return{load:t=>e.get(t)??null,save:(t,i)=>{e.set(t,i)},remove:t=>{e.delete(t)}}}export{L as a,O as b,z as c,oe as d,ne as e,q as f,fe as g,j as h,D as i,U as j,_ as k,Ae as l,Le as m,ze as n};