1import{D as e}from"./default-renderer-BZKN5ad1.js";import{b as t,B as s}from"./HeaderLogoLetters-DJI_FB9w.js";import{r as i,a as r,g as o,c as a,b as n,d,e as l}from"./videoPosterMediabunny-CXcmZmdN.js";import"./app-Cu6dTb9L.js";import"./lazyDialog-D7tW-HM0.js";import"./SplitText-VLUCmDhw.js";import"./distributeProjectAuthorCard-USTmGEds.js";import"./SocialPosts-rgMf2ipp.js";import"./patchCommentsProtect-C8m96Vr7.js";function c(e){return String(null!=e?e:"").replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")}function p(){const e={Accept:"application/json"},t=document.querySelector('meta[name="csrf-token"]'),s=window.csrfToken||(null==t?void 0:t.getAttribute("content"))||"";return s&&(e["X-CSRF-Token"]=s),e}class u{constructor(){var e;this.root=document.querySelector("[data-video-posters-audit]"),this.root&&(t(this,["handlePresetsClick","handleSaveClick","handleSkipClick","handlePosterVideoSeeked","handlePosterVideoPause"]),this.workspaceEl=this.root.querySelector("[data-audit-workspace]"),this.remainingEl=this.root.querySelector("[data-audit-remaining]"),this.skippedNoteEl=this.root.querySelector("[data-audit-skipped-note]"),this.state={loadToken:0,posterOptions:[],posterSelection:null,posterPreviewUrls:[],posterVideoPlayerEl:null,posterVideoObjectUrl:null,posterSyncFromPreset:!1,pendingVideo:null,isSaving:!1},this.bindWorkspaceEvents(),"verify"!==(null==(e=this.getProjectEl())?void 0:e.dataset.auditMode)&&this.initCurrentProject())}bindWorkspaceEvents(){this.root.addEventListener("click",this.handlePresetsClick),this.root.addEventListener("click",(e=>{e.target.closest("[data-audit-save]")&&this.handleSaveClick(e)})),this.root.addEventListener("click",(e=>{e.target.closest("[data-audit-skip]")&&this.handleSkipClick(e)}))}getProjectEl(){return this.root.querySelector("[data-audit-project]")}getPosterPickerEl(){return this.root.querySelector("[data-audit-poster-picker]")}getPosterLoadingEl(){return this.root.querySelector("[data-audit-poster-loading]")}getPosterBodyEl(){return this.root.querySelector("[data-audit-poster-body]")}getPosterErrorEl(){return this.root.querySelector("[data-audit-poster-error]")}getPosterPresetsEl(){return this.root.querySelector("[data-audit-poster-presets]")}getPosterPreviewEl(){return this.root.querySelector("[data-audit-poster-preview]")}getSaveButtonEl(){return this.root.querySelector("[data-audit-save]")}getFeedbackEl(){return this.root.querySelector("[data-audit-feedback]")}getPosterVideo(){var e,t;return null!=(t=null==(e=this.state.posterVideoPlayerEl)?void 0:e.querySelector("video"))?t:null}getPosterCanvasForSave(){var e,t;return i(this.getPosterVideo(),null!=(t=null==(e=this.state.posterSelection)?void 0:e.canvas)?t:null)}getPosterVideoPlayer(){var e,t;const i=this.getPosterPreviewEl();if(!i)return null;const r=s(i);return null!=(t=null==(e=null==r?void 0:r.players)?void 0:e.get(this.state.posterVideoPlayerEl))?t:null}setFeedback(e,t=!1){const s=this.getFeedbackEl();if(s){if(!e)return s.hidden=!0,s.textContent="",void s.classList.remove("is-error");s.hidden=!1,s.textContent=e,s.classList.toggle("is-error",t)}}updateHeader(e){var t,s;const i=null!=(t=null==e?void 0:e.remaining)?t:0,r=null!=(s=null==e?void 0:e.skippedCount)?s:0;this.remainingEl&&(this.remainingEl.textContent=1===i?"1 project remaining":`${i} projects remaining`),this.skippedNoteEl&&(r>0?(this.skippedNoteEl.hidden=!1,this.skippedNoteEl.textContent=`${r} skipped this session`):(this.skippedNoteEl.hidden=!0,this.skippedNoteEl.textContent=""))}renderWorkspace(e){var t,s,i;if(!this.workspaceEl)return;if(!(null==(t=null==e?void 0:e.featuredVideo)?void 0:t.url))return void(this.workspaceEl.innerHTML='\n <div class="video-posters-audit-done" data-audit-done>\n <h2 class="h2">All caught up</h2>\n <p>No portfolio projects with a video hero are missing a poster.</p>\n </div>\n ');const r=(null==(s=e.author)?void 0:s.fullName)?`<span>${c(e.author.fullName)}</span>`:"",o=e.publicUrl?`<a href="${c(e.publicUrl)}" target="_blank" rel="noopener noreferrer">View project</a>`:"",a=e.editUrl?`<a href="${c(e.editUrl)}" target="_blank" rel="noopener noreferrer">Edit project</a>`:"",n=e.featuredVideo.streamUrl||e.featuredVideo.url;this.workspaceEl.innerHTML=`\n <article\n class="video-posters-audit-project"\n data-audit-project\n data-entry-id="${c(e.id)}"\n data-video-url="${c(e.featuredVideo.url)}"\n data-video-stream-url="${c(n)}"\n data-video-filename="${c(e.featuredVideo.filename)}"\n >\n <div class="portfolio-group video-posters-audit-project-group">\n <label>Project</label>\n <div class="portfolio-group-content video-posters-audit-project-meta">\n <div class="video-posters-audit-project-copy">\n <h2 class="video-posters-audit-project-title">${c(e.title)}</h2>\n <p class="video-posters-audit-project-details">\n ${r}
1\n <span>@${c((null==(i=e.author)?void 0:i.username)||"")}</span>\n <span>Created ${c(e.dateCreated||"")}</span>\n </p>\n <div class="video-posters-audit-project-links">\n ${o}\n ${a}\n </div>\n </div>\n </div>\n </div>\n\n <div class="portfolio-group video-posters-audit-picker-group">\n <label>Video poster</label>\n <div class="portfolio-group-content">\n <div class="video-posters-audit-picker media-library-poster-step" data-audit-poster-picker>\n <div class="media-library-poster-loading" data-audit-poster-loading role="status" aria-live="polite">\n <span class="media-library-loading-spinner" aria-hidden="true"></span>\n <span class="media-library-poster-loading-text">Generating poster options...</span>\n </div>\n\n <div class="media-library-poster-error" data-audit-poster-error hidden></div>\n\n <div class="media-library-poster-body" data-audit-poster-body hidden>\n <div class="media-library-poster-presets-section">\n <span class="project-media-thumbn
1ails-title media-library-poster-section-label">Pick a frame:</span>\n <div class="media-library-poster-presets" data-audit-poster-presets role="listbox" aria-label="Suggested poster frames"></div>\n </div>\n\n <div class="media-library-poster-custom-section">\n <span class="project-media-thumbnails-title media-library-poster-section-label">Pick a custom frame:</span>\n <div class="media-library-poster-preview-wrap">\n <div class="media-library-poster-preview" data-audit-poster-preview aria-live="polite"></div>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <div class="video-posters-audit-actions dialog-actions dialog-actions-split">\n <div class="dialog-actions-left">\n <button type="button" class="button" data-audit-skip>Skip</button>\n </div>\n <div class="dialog-actions-right">\n <button type="button" class="button media-library-poster-confirm" data-audit-save disabled>Save Poster</button>\n </div>\n </div>\n\n <p class="video-posters-audit-feedback" data-audit-feedback hidden role="status" aria-live="polite"></p>\n </article>\n `}resetPosterState(){r(this.state.posterPreviewUrls),this.state.posterPreviewUrls=[];const e=this.getPosterVideo();e&&this.handlePosterVideoSeeked&&e.removeEventListener("seeked",this.handlePosterVideoSeeked),e&&this.handlePosterVideoPause&&e.removeEventListener("pause",this.handlePosterVideoPause),this.state.posterVideoObjectUrl&&(URL.revokeObjectURL(this.state.posterVideoObjectUrl),this.state.posterVideoObjectUrl=null),this.state.posterOptions=[],this.state.posterSelection=null,this.state.posterVideoPlayerEl=null,this.state.posterSyncFromPreset=!1,this.state.pendingVideo=null}async initCurrentProject(){const e=this.getProjectEl();if(!e)return;const t=e.dataset.videoUrl||"",s=e.dataset.videoStreamUrl||t,i=e.dataset.videoFilename||"video.mp4";await this.loadPosterPicker({url:t,streamUrl:s,filename:i})}async loadPosterPicker(e){var t;this.resetPosterState(),this.setFeedback("");const s=this.getPosterLoadingEl(),i=this.getPosterBodyEl(),r=this.getPosterErrorEl(),n=this.getSaveButtonEl();s&&(s.hidden=!1),i&&(i.hidden=!0),r&&(r.hidden=!0,r.textContent=""),n&&(n.disabled=!0);const d=++this.state.loadToken;this.state.pendingVideo={url:e.url,streamUrl:e.streamUrl||e.url,filename:e.filename};try{const{options:r}=await o({streamUrl:e.streamUrl||e.url,url:e.url,filename:e.filename});if(d!==this.state.loadToken)return;this.state.posterOptions=r;const n=this.getPosterPresetsEl();if(n){n.innerHTML="";for(let e=0;e<r.length;e+=1){const t=r[e],s=document.createElement("button");s.type="button",s.className="media-library-poster-preset",s.dataset.posterIndex=String(e),s.setAttribute("role","option"),s.setAttribute("aria-label",`Suggested frame ${e+1}`);try{const{img:e,objectUrl:i}=await a(t.canvas,.85);this.state.posterPreviewUrls.push(i),s.appendChild(e)}catch(l){t.canvas instanceof HTMLCanvasElement&&s.appendChild(t.canvas)}n.appendChild(s)}}if(s&&(s.hidden=!0),i&&(i.hidden=!1),await this.mountPosterVideo(this.state.pendingVideo),d!==this.state.loadToken)return;if(r[0]){const e=(null==(t=this.getPosterPresetsEl())?void 0:t.querySelector(".media-library-poster-preset"))||null;await this.selectPosterFrame(r[0].canvas,r[0].timestamp,{presetButton:e})}}catch(c){if(d!==this.state.loadToken)return;s&&(s.hidden=!0),r&&(r.hidden=!1,r.textContent=(null==c?void 0:c.message)||"Unable to generate poster options.")}}async mountPosterVideo(e){const t=this.getPosterPreviewEl(),i=(null==e?void 0:e.streamUrl)||(null==e?void 0:e.url)||"";if(!t||!i)return;t.innerHTML="";const r=document.getElementById("custom-video-player-chrome"),o=document.createElement("div");
1o.className="custom-video-player media-library-poster-video-player",o.setAttribute("data-custom-video-player",""),o.setAttribute("data-custom-video-mode","poster-picker");const a=document.createElement("video");a.src=i,a.preload="auto",a.playsInline=!0,a.muted=!0,a.pause(),o.appendChild(a),(null==r?void 0:r.content)&&o.appendChild(r.content.cloneNode(!0)),t.appendChild(o),this.state.posterVideoPlayerEl=o,s(t),a.addEventListener("seeked",this.handlePosterVideoSeeked),a.addEventListener("pause",this.handlePosterVideoPause),await new Promise((e=>{a.readyState>=2?e():(a.addEventListener("loadeddata",(()=>e()),{once:!0}),a.addEventListener("error",(()=>e()),{once:!0}))}))}syncPosterVideoProgress(e){const t=this.getPosterVideoPlayer();if(t){if(t.setProgressSmooth(!1),Number.isFinite(e)){const s=t.getDuration();if(s>0)return void t.updateProgressUi(e/s)}t.syncProgressFromVideo()}}async seekPosterVideo(e){const t=this.getPosterVideo();t&&Number.isFinite(e)&&(await new Promise((e=>{t.readyState>=2?e():(t.addEventListener("loadeddata",(()=>e()),{once:!0}),t.addEventListener("error",(()=>e()),{once:!0}))})),await new Promise((s=>{let i=!1;const r=()=>{i||(i=!0,s())},o=()=>{this.state.posterSyncFromPreset=!1,this.syncPosterVideoProgress(t.currentTime),r()};this.state.posterSyncFromPreset=!0,t.addEventListener("seeked",o,{once:!0});const a=this.getPosterVideoPlayer();if(a)a.seekToTimestamp(e);else try{const s=t.duration,i=Number.isFinite(s)&&s>0?Math.min(Math.max(e,0),Math.max(s-.05,0)):Math.max(e,0);t.currentTime=i}catch(n){this.state.posterSyncFromPreset=!1,r()}window.setTimeout((()=>{i||(t.removeEventListener("seeked",o),this.state.posterSyncFromPreset=!1,this.syncPosterVideoProgress(t.currentTime),r())}),250)})))}handlePosterVideoSeeked(){const e=this.getPosterVideo();if(!e)return;if(this.syncPosterVideoProgress(e.currentTime),this.state.posterSyncFromPreset)return void(this.state.posterSyncFromPreset=!1);if(!e.videoWidth)return;const t=n(e);this.selectPosterFrame(t,e.currentTime,{presetButton:null,skipVideoSync:!0})}handlePosterVideoPause(){const e=this.getPosterVideo();if(!(null==e?void 0:e.videoWidth)||this.state.posterSyncFromPreset)return;const t=n(e);this.selectPosterFrame(t,e.currentTime,{presetButton:null,skipVideoSync:!0})}async selectPosterFrame(e,t,{presetButton:s=null,skipVideoSync:i=!1}={}){if(!e)return;this.state.posterSelection={canvas:e,timestamp:t},!i&&Number.isFinite(t)&&await this.seekPosterVideo(t);const r=this.getPosterPresetsEl();r&&r.querySelectorAll(".media-library-poster-preset").forEach((e=>{e.classList.toggle("is-active",e===s)}));const o=this.getSaveButtonEl();o&&(o.disabled=!1)}handlePresetsClick(e){var t,s;const i=null==(s=null==(t=null==e?void 0:e.target)?void 0:t.closest)?void 0:s.call(t,".media-library-poster-preset"),r=this.getPosterPresetsEl();if(!i||!(null==r?void 0:r.contains(i)))return;const o=parseInt(i.dataset.posterIndex||"",10),a=this.state.posterOptions[o];(null==a?void 0:a.canvas)&&this.selectPosterFrame(a.canvas,a.timestamp,{presetButton:i})}async handleSaveClick(e){var t,s;if(null==(t=null==e?void 0:e.preventDefault)||t.call(e),this.state.isSaving)return;const i=this.getPosterCanvasForSave();if(!i)return;const r=this.getProjectEl(),o=parseInt((null==r?void 0:r.dataset.entryId)||"",10);if(!o)return;this.state.isSaving=!0,this.setFeedback("Saving poster...");const a=this.getSaveButtonEl();a&&(a.disabled=!0);try{const e=await d(i),t=l(e,(null==(s=this.state.pendingVideo)?void 0:s.filename)||"video.mp4"),r=new FormData;r.append("entryId",String(o)),r.append("file",t);const a=await fetch("/api/video-posters-audit/save-poster",{method:"POST",headers:p(),credentials:"same-origin",body:r}),n=await a.json();if(!(null==n?void 0:n.success))throw new Error((null==n?void 0:n.message)||"Unable to save poster.");if(n.redirect)return void window.location.assign(n.redirect);this.applyPayload(n)}catch(n){this.setFeedback((null==n?void 0:n.message)||"Unable to save poster.",!0),a&&(a.disabled=!1)}finally{this.state.isSaving=!1}}async handleSkipClick(e){var t;if(null==(t=null==e?void 0:e.preventDefault)||t.call(e),this.state.isSaving)return;const s=this.getProjectEl(),i=parseInt((null==s?void 0:s.dataset.entryId)||"",10);if(i){this.state.isSaving=!0,this.setFeedback("Skipping...");try{const e=new FormData;e.append("entryId",String(i));const t=await fetch("/api/video-posters-audit/skip",{method:"POST",headers:p(),credentials:"same-origin",body:e}),s=await t.json();if(!(null==s?void 0:s.success))throw new Error((null==s?void 0:s.message)||"Unable to skip project.");this.applyPayload(s)}catch(r){this.setFeedback((null==r?void 0:r.message)||"Unable to skip project.",!0)}finally{this.state.isSaving=!1}}}applyPayload(e){this.updateHeader(e),this.renderWorkspace(e.project),this.initCurrentProject()}async stopPage(){this.resetPosterState()}}let h;class v extends e{async onLeave(){if(super.onLeave(),h)try{await h.stopPage()}finally{h=null}}onEnterCompleted(){super.onEnterCompleted(),h=new u}}export{v as default};
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.