PageSourceSearch

https://toolbreezy.com/_next/static/chunks/29768-0442b6b14ac8db3a.js

js toolbreezy.com collected 2026-09-24 14:58:49 UTC 31,385 bytes, 1 lines download raw bytes

1"use strict";(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[29768],{29768:(e,t,a)=>{a.r(t),a.d(t,{SETTING_DEFAULTS:()=>P,addressCarriesOwnState:()=>W,buildShareParams:()=>E,default:()=>B,settingsFromLink:()=>G});var r=a(95155),s=a(52619),n=a.n(s),l=a(12115),i=a(21786),o=a(76907),d=a(35299),c=a(65229),u=a(52056),h=a(48314),m=a(27209),f=a(85921),p=a(39867),g=a(71155),x=a(18154),b=a(97003),w=a(33534),y=a(70134),j=a(25016),N=a(31258),v=a(14827),k=a(16110),M=a(68206),$=a(51974),C=a(2042);let T=[100,75,50,33,25],F=[1,2,3,5,10],R=["played","stored"],S=["mp4","webm"],I=["high","medium","low"],z=["timing","format","quality","scale","repeat","bg"];function W(e){let t=new URLSearchParams(e.replace(/^\?/,""));return z.some(e=>t.has(e))}let P={timing:"played",format:"mp4",quality:"high",scale:100,repeat:1,background:"#ffffff"};function E(e){let t={timing:e.timing,format:e.format,quality:e.quality,scale:String(e.scale),repeat:String(e.repeat),bg:e.background.replace("#","")},a=new URLSearchParams;for(let e of z)a.set(e,t[e]);return a}function G(e){let t=new URLSearchParams(e.replace(/^\?/,"")),a=(e,a,r)=>{let s=t.get(e);return null!==s&&a.includes(s)?s:r},r=(e,a,r)=>{let s=t.get(e);if(null===s||""===s.trim())return r;let n=Number(s);return a.includes(n)?n:r},s=t.get("bg");return{timing:a("timing",R,P.timing),format:a("format",S,P.format),quality:a("quality",I,P.quality),scale:r("scale",T,P.scale),repeat:r("repeat",F,P.repeat),background:(null===s?null:(0,M.n9)(s))??P.background}}function D(e){return`${(e/1e3).toFixed(2)}s`}let L="something this page does not recognize",A={png:"a PNG (an animated PNG, most likely)",webp:"a WebP",jpg:"a JPG",mp4:"an MP4 or MOV",unknown:L};function H(e,t,a,r,s){let n=[];if(0===e.length)return{written:n,totalMs:0,shortDelay:0,raised:0};let l=e.length-1,i=Math.max(0,Math.min(Math.trunc(t),l)),o=Math.max(i,Math.min(Math.trunc(a),l)),d=Math.max(1,Math.min(Math.trunc(s),10)),c=0,u=0,h=0;for(let t=0;t<d;t++)for(let a=i;a<=o;a++){let s=e[a];if(!s)continue;0===t&&(0,$.L7)(s.storedCs)&&(u+=1);let l="played"===r?(0,$.T7)(s.storedCs):10*s.storedCs;l<10&&(l=10,h+=1),n.push({srcIndex:a,startMs:c,durMs:l}),c+=l}return{written:n,totalMs:c,shortDelay:u,raised:h}}function B(){let[e,t]=(0,l.useState)(null),[s,R]=(0,l.useState)([]),[S,I]=(0,l.useState)(P.timing),[z,B]=(0,l.useState)(P.format),[U,O]=(0,l.useState)(P.quality),[q,V]=(0,l.useState)(P.scale),[_,J]=(0,l.useState)(P.repeat),[K,Y]=(0,l.useState)(P.background),[Q,X]=(0,l.useState)(P.background),[Z,ee]=(0,l.useState)(0),[et,ea]=(0,l.useState)(0),[er,es]=(0,l.useState)(null),[en,el]=(0,l.useState)(0),[ei,eo]=(0,l.useState)(null),[ed,ec]=(0,l.useState)(!1),[eu,eh]=(0,l.useState)(""),[em,ef]=(0,l.useState)(0),[ep,eg]=(0,l.useState)(""),[ex,eb]=(0,l.useState)(""),[ew,ey]=(0,l.useState)(!1),ej=(0,l.useRef)(null),eN=(0,l.useRef)(null),ev=(0,l.useRef)(null),ek=(0,l.useRef)(null),eM=(0,l.useRef)([]);eM.current=s;let e$=(0,l.useRef)(null),eC=(0,l.useRef)(0),eT=(0,l.useRef)(!1),eF=(0,l.useRef)(!1);e$.current=er,(0,l.useEffect)(()=>(eW.current=eP,()=>{e$.current&&URL.revokeObjectURL(e$.current.url)}),[]),(0,l.useEffect)(()=>{if(!W(window.location.search))return;let e=G(window.location.search);I(e.timing),B(e.format),O(e.quality),V(e.scale),J(e.repeat),Y(e.background),X(e.background)},[]);let eR=(0,l.useMemo)(()=>{if(!e)return null;let t=q/100,a=Math.max(2,Math.round(e.width*t)),r=Math.max(2,Math.round(e.height*t)),s=a+a%2,n=r+r%2;return{drawW:a,drawH:r,outW:s,outH:n,padded:s!==a||n!==r}},[e,q]),eS=(0,l.useMemo)(()=>({played:H(s,Z,et,"played",_),stored:H(s,Z,et,"stored",_)}),[s,Z,et,_]),eI="played"===S?eS.played:eS.stored;(0,l.useEffect)(()=>{eT.current&&(eT.current=!1,eC.current+=1,ec(!1),eh(""),ef(0),eb("That setting changed while a conversion was running, so it was stopped. Press Convert to run it again.")),es(e=>(e&&URL.revokeObjectURL(e.url),null)),el(0)},[S,z,U,q,_,K,Z,et,s]),(0,l.useEffect)(()=>{if(!eR)return void eo(null);let e=!0;return(async()=>{try{let{canEncodeVideo:t}=await Promise.all([a.e(32971),a.e(61845)]).then(a.bind(a,32971)),[r,s]=await Promise.all([t("avc",{width:eR.outW,height:eR.outH}),t("vp9",{width:eR.outW,height:eR.outH})]);e&&eo({mp4:r,webm:s})}catch{e&&eo({mp4:!1,webm:!1})}})(),()=>{e=!1}},[eR]),(0,l.useEffect)(()=>{let t=ev.current;if(!t||!e||!er)return;let a=er.written;if(0===a.length)return;let r=a.length-1;for(let e=0;e<a.length;e++){let t=a[e];if(t&&en<t.startMs+t.durMs){r=e;break}}let s=a[r],n=s?eM.current[s.srcIndex]:void 0;if(!n)return;let l=(0,y.lH)(t,e.width,e.height);if(!l)return;l.fillStyle=er.receipt.background,l.fillRect(0,0,t.width,t.height);let i=ek.current;if(!i){let t=(0,y.$t)(e.width,e.height);if(!t)return;ek.current=i=t.canvas}let o=(0,y.lH)(i,e.width,e.height);if(!o)return;let d=o.createImageData(e.width,e.height);d.data.set(n.data),o.putImageData(d,0,0),l.drawImage(i,0,0)},[en,e,er]),(0,l.useEffect)(()=>{let e=eN.current;if(!e||!er||!eF.current)return;let t=en/1e3;Number.isFinite(t)&&Math.abs(e.currentTime-t)>.02&&(e.currentTime=t)},[en,er]);let ez=(0,l.useCallback)(async(e,r="")=>{let s=++eC.current;eT.current=!1,t(null),R([]),es(e=>(e&&URL.revokeObjectURL(e.url),null)),eg(""),eb(""),ef(0),ec(!0),eh("Reading the file...");try{if(e.size>0x5000000)throw Error(`size:That GIF is ${(0,N.z)(e.size)}, over the ${(0,N.z)(0x5000000)} ceiling this page works within. Nothing is uploaded, so the limit is your own memory rather than a server.`);let n=new Uint8Array(await e.arrayBuffer());if(eC.current!==s)return;let l=function(e){let t=t=>e[t]??0;return 71===t(0)&&73===t(1)&&70===t(2)&&56===t(3)?"gif":137===t(0)&&80===t(1)&&78===t(2)&&71===t(3)?"png":82===t(0)&&73===t(1)&&70===t(2)&&70===t(3)?"webp":255===t(0)&&216===t(1)?"jpg":102===t(4)&&116===t(5)&&121===t(6)&&112===t(7)?"mp4":"unknown"}(n);if("gif"!==l)throw Error(`sniff:The first few bytes of that file say it is ${A[l]??L}, not a GIF, whatever the name says. This page reads the frame table inside a real GIF.`);eh("Reading the frame table...");let{decode:i,decodeFrames:o}=await a.e(83259).then(a.bind(a,83259));if(eC.current!==s)return;let d=i(n),c=d.frames||[];
1if(0===c.length)throw Error("empty:No frames could be read out of that GIF.");let u=Math.max(1,d.width*d.height*4),h=Math.max(1,Math.floor(0x10000000/u)),m=Math.min(c.length,300,h),f=c.length-m,p=f<=0?"":h<300?"the memory ceiling":"the 300 frame ceiling";eh(`Rebuilding ${m} frames...`);let g=o(n,{gif:d,range:[0,m-1]});if(eC.current!==s)return;let x=[],b=!1;for(let e=0;e<m;e++){let t=g[e],a=c[e];t&&a&&(a.graphicControl?.transparent===!0&&(b=!0),x.push({data:t.data,storedCs:a.graphicControl?.delayTime??0}))}if(0===x.length)throw Error("empty:No frames could be read out of that GIF.");t({name:e.name.replace(/\.[^.]+$/,"")||"animation",bytes:e.size,width:d.width,height:d.height,framesInFile:c.length,framesRead:x.length,dropped:Math.max(0,f),capReason:p,transparent:b,loopCountRaw:d.loopCount??0,looped:!1!==d.looped}),R(x),ee(0),ea(x.length-1);let w=[];r&&w.push(r),f>0&&w.push(`This GIF holds ${c.length} frames and ${f} of them were dropped by ${p}. Only the first ${m} will be written, so the finished clip is shorter than the original.`),1===x.length&&w.push("This file holds a single frame, so it is a still picture rather than an animation. Converting it to a one frame video would be a pretend conversion. Save it as a PNG or a JPG instead, the links are below."),b&&w.push("This GIF has transparent areas. Video has no transparency at all, so pick the background color those areas should sit on before you convert."),eb(w.join(" "))}catch(r){if(eC.current!==s)return;let[e,...t]=(r instanceof Error?r.message:"").split(":"),a=t.join(":");eg((0,C.oh)(r,"size"===e||"sniff"===e||"empty"===e?a:"That file could not be opened as a GIF. It may be truncated, or saved by a program that writes a GIF the standard readers cannot follow."))}finally{eC.current===s&&(ec(!1),eh(""))}},[]),eW=(0,l.useRef)(null);function eP(e){let t=Array.from(e||[]),a=t[0];a&&ez(a,t.length>1?`Converting ${a.name}. One GIF at a time here, so the other ${t.length-1} file(s) were left alone.`:"")}async function eE(){let t=eM.current;if(!e||!eR||0===t.length||ed||1===t.length)return;let r=++eC.current;eT.current=!0,es(e=>(e&&URL.revokeObjectURL(e.url),null)),el(0),eg(""),eb(""),ec(!0),ef(0),eh("Checking what this browser can encode...");let s="webm"===z?"vp9":"avc",n=H(t,Z,et,S,_),l=n.written,i=H(t,Z,et,"played"===S?"stored":"played",_);try{if(0===l.length)throw Error("plain:There are no frames in that range to write.");let{Output:o,Mp4OutputFormat:d,WebMOutputFormat:c,BufferTarget:u,CanvasSource:h,canEncodeVideo:m,QUALITY_LOW:f,QUALITY_MEDIUM:p,QUALITY_HIGH:g,Input:x,BufferSource:b,ALL_FORMATS:w,EncodedPacketSink:j}=await Promise.all([a.e(32971),a.e(61845)]).then(a.bind(a,32971));if(eC.current!==r)return;let N=await m(s,{width:eR.outW,height:eR.outH});if(eC.current!==r)return;if(!N)throw Error("mp4"===z?`plain:This browser has no H.264 encoder at ${eR.outW} by ${eR.outH}, so it cannot write a real MP4 here. Switch the output to WebM, which this page will produce instead, or try a recent Chrome or Edge on a desktop.`:`plain:This browser has no VP9 encoder at ${eR.outW} by ${eR.outH}. Switch the output back to MP4, or try a recent Chrome, Edge or Firefox.`);let v=(0,y.$t)(e.width,e.height);if(!v)throw Error(`plain:${(0,y.m4)(e.width,e.height,"GIF")}`);let{canvas:k,ctx:M}=v,$=(0,y.$t)(eR.outW,eR.outH,{alpha:!1});if(!$)throw Error(`plain:${(0,y.m4)(eR.outW,eR.outH,"video")} Type a smaller output size and convert again.`);let{canvas:C,ctx:T}=$,F="low"===U?f:"medium"===U?p:g,R=new o({format:"webm"===z?new c:new d,target:new u}),I=new h(C,{codec:s,bitrate:F});if(R.addVideoTrack(I),await R.start(),eC.current!==r)return void await R.cancel();eh(`Writing frame 1 of ${l.length}...`);let W=M.createImageData(e.width,e.height),P=-1;for(let e=0;e<l.length;e++){let a=l[e];if(a){if(a.srcIndex!==P){let e=t[a.srcIndex];if(!e)throw Error("plain:A frame went missing partway through. Load the GIF again.");W.data.set(e.data),M.putImageData(W,0,0),T.fillStyle=K,T.fillRect(0,0,eR.outW,eR.outH),T.drawImage(k,0,0,eR.drawW,eR.drawH),P=a.srcIndex}if(await I.add(a.startMs/1e3,a.durMs/1e3),eC.current!==r||(e%5==0||e===l.length-1)&&(ef(Math.round((e+1)/l.length*100)),eh(`Writing frame ${e+1} of ${l.length}...`),await new Promise(e=>window.setTimeout(e,0)),eC.current!==r))return void await R.cancel()}}if(eh("Finishing the file..."),await R.finalize(),eC.current!==r)return;let E=R.target.buffer;if(!E)throw Error("plain:The conversion produced an empty file. Try a smaller output size.");let G=new Blob([E],{type:"webm"===z?"video/webm":"video/mp4"});eh("Checking the timing of the finished file...");
1let D=null,L=null,A=null,H="",B=null;try{let e=new x({formats:w,source:new b(E)});B=()=>e.dispose();let t=await e.getPrimaryVideoTrack();if(!t)throw Error("no-track");let a=new j(t),r=[],s=0;for await(let e of a.packets())r.push(e.timestamp),s=Math.max(s,e.timestamp+e.duration);if(r.sort((e,t)=>e-t),D=r.length,A=Math.round(1e3*s),r.length!==l.length)L=null,H=0===r.length?"The finished file gave back no frames to check, so there is no measured timing figure. Treat this file as unverified and play it before you use it.":`The finished file holds ${r.length} frames where ${l.length} were written, so the timing could not be checked against the plan. Play it before you use it.`;else{let e=0;for(let t=0;t<r.length;t++){let a=r[t],s=l[t];void 0!==a&&s&&(e=Math.max(e,Math.abs(1e3*a-s.startMs)))}L=e}}catch{D=null,L=null,A=null,H="The finished file could not be read back for a timing check in this browser, so no measured figure is shown below."}finally{B?.()}if(eC.current!==r)return;let O={framesWritten:l.length,durationMs:n.totalMs,otherPolicyMs:i.totalMs,policy:S,shortDelayFrames:n.shortDelay,raisedFrames:n.raised,repeat:_,drawW:eR.drawW,drawH:eR.drawH,outW:eR.outW,outH:eR.outH,padded:eR.padded,background:K,backgroundUsed:e.transparent,outBytes:G.size,inBytes:e.bytes,dropped:e.dropped,capReason:e.capReason,packetCount:D,maxDeviationMs:L,measuredDurationMs:A,readBackNote:H};es({url:URL.createObjectURL(G),blob:G,format:z,filename:`${e.name}.${z}`,written:l,receipt:O}),ef(100)}catch(t){if(eC.current!==r)return;let e=t instanceof Error?t.message:"";eg(e.startsWith("plain:")?e.slice(6):`The conversion stopped partway through. ${l.length} frames at ${eR.outW} by ${eR.outH} may be more than this browser will hold, so try a smaller output size or a shorter frame range.`)}finally{eC.current===r&&(eT.current=!1,ec(!1),eh(""))}}(0,l.useEffect)(()=>{function e(e){let t=e.target;if(t&&t.closest('input, textarea, [contenteditable="true"]'))return;let a=e.clipboardData?.files;a&&a.length>0&&(e.preventDefault(),eW.current?.(a))}return document.addEventListener("paste",e),()=>document.removeEventListener("paste",e)},[]);let eG=er?`<video src="${er.filename}" autoplay muted loop playsinline></video>`:"",eD=(0,l.useCallback)(()=>E({timing:S,format:z,quality:U,scale:q,repeat:_,background:K}),[S,z,U,q,_,K]),eL=null===(0,M.n9)(Q),eA=null!==e&&1===e.framesRead,eH=null!==e&&null!==eR&&!eA&&eI.written.length>0&&!ed,eB="h-9 rounded-md border border-input bg-background px-3 text-sm shadow-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",eU=er?.receipt;return(0,r.jsxs)("div",{className:"space-y-5",children:[(0,r.jsxs)("div",{onDrop:e=>{e.preventDefault(),ey(!1),eP(e.dataTransfer.files)},onDragOver:e=>{e.preventDefault(),ey(!0)},onDragLeave:()=>ey(!1),onClick:()=>ej.current?.click(),role:"button",tabIndex:0,onKeyDown:e=>{("Enter"===e.key||" "===e.key)&&(e.preventDefault(),ej.current?.click())},className:(0,j.cn)("flex cursor-pointer flex-col items-center justify-center rounded-lg border-2 border-dashed p-8 text-center transition-colors",ew?"border-primary bg-accent":"border-input hover:border-foreground
1/30 hover:bg-accent/50"),children:[(0,r.jsx)(i.A,{className:"mb-2 size-8 text-muted-foreground"}),(0,r.jsx)("p",{className:"font-medium",children:"Click to choose a GIF, or drag one into the box"}),(0,r.jsxs)("p",{className:"mt-1 flex items-center gap-1 text-sm text-muted-foreground",children:[(0,r.jsx)(o.A,{className:"size-4"})," You can paste one too. Nothing is uploaded."]}),(0,r.jsx)("input",{ref:ej,type:"file",accept:"image/gif,.gif",className:"hidden",onChange:e=>{eP(e.target.files),e.target.value=""}})]}),ed&&(0,r.jsxs)("div",{className:"rounded-lg border bg-card p-4",children:[(0,r.jsxs)("div",{className:"flex items-center justify-between gap-3",children:[(0,r.jsxs)("p",{className:"flex items-center gap-2 text-sm",children:[(0,r.jsx)(d.A,{className:"size-4 animate-spin"}),eu||"Working..."]}),(0,r.jsxs)(b.$,{variant:"ghost",size:"sm",onClick:function(){eC.current+=1,eT.current=!1,ec(!1),eh(""),ef(0),eb("Stopped. Your settings are still here, so you can change one and run it again.")},children:[(0,r.jsx)(c.A,{className:"mr-1 size-4"}),"Cancel"]})]}),em>0&&(0,r.jsx)("div",{className:"mt-2 h-1.5 w-full overflow-hidden rounded bg-muted",children:(0,r.jsx)("div",{className:"h-full bg-primary transition-all",style:{width:`${em}%`}})})]}),ep&&(0,r.jsxs)("p",{className:"flex items-start gap-2 text-sm text-destructive",children:[(0,r.jsx)(u.A,{className:"mt-0.5 size-4 shrink-0"}),(0,r.jsx)("span",{children:ep})]}),ex&&(0,r.jsx)("p",{className:"text-sm text-muted-foreground",children:ex}),eA&&(0,r.jsxs)("p",{className:"text-sm",children:["Try"," ",(0,r.jsx)(n(),{className:"underline",href:"/image/gif-to-png/",children:"GIF to PNG"})," ","or"," ",(0,r.jsx)(n(),{className:"underline",href:"/image/gif-to-jpg/",children:"GIF to JPG"})," ","for a still picture."]}),e&&!eA&&eR&&(0,r.jsxs)(r.Fragment,{children:[(0,r.jsxs)("div",{className:"rounded-lg border bg-card p-4",children:[(0,r.jsxs)("div",{className:"flex flex-wrap items-baseline justify-between gap-2",children:[(0,r.jsxs)("h2",{className:"text-sm font-semibold",children:[e.name,".gif, ",e.width," by ",e.height,", ",e.framesRead," frames, ",(0,N.z)(e.bytes)]}),(0,r.jsxs)(b.$,{variant:"ghost",size:"sm",onClick:function(){eC.current+=1,eT.current=!1,t(null),R([]),es(e=>(e&&URL.revokeObjectURL(e.url),null)),el(0),eg(""),eb(""),ec(!1),eh(""),ef(0)},children:[(0,r.jsx)(h.A,{className:"mr-1.5 size-4"}),"Start over"]})]}),(0,r.jsxs)("fieldset",{className:"mt-4",children:[(0,r.jsx)("legend",{className:"text-sm font-medium",children:"Which delays should the video use"}),(0,r.jsxs)("p",{className:"mt-1 text-xs text-muted-foreground",children:["A GIF stores each delay in hundredths of a second, and every browser throws away a stored 0 or 1 and waits ",$.B1,"ms instead. So the file and the animation you watched can disagree about how long it runs. ",eS.played.shortDelay," of the frames you are converting sit in that bracket."]}),(0,r.jsxs)("div",{className:"mt-2 grid gap-2 sm:grid-cols-2",children:[(0,r.jsxs)("label",{className:(0,j.cn)("flex cursor-pointer gap-2 rounded border p-3 text-sm","played"===S?"border-primary bg-accent":"bg-background"),children:[(0,r.jsx)("input",{type:"radio",name:"timing",className:"mt-1",checked:"played"===S,onChange:()=>I("played")}),(0,r.jsxs)("span",{children:[(0,r.jsx)("span",{className:"font-medium",children:"Match what a browser plays"}),(0,r.jsxs)("span",{className:"block text-xs text-muted-foreground",children:["Runs ",D(eS.played.totalMs),". Short delays are held at ",$.B1,"ms, the way you watched it."]})]})]}),(0,r.jsxs)("label",{className:(0,j.cn)("flex cursor-pointer gap-2 rounded border p-3 text-sm","stored"===S?"border-primary bg-accent":"bg-background"),children:[(0,r.jsx)("input",{type:"radio",name:"timing",className:"mt-1",checked:"stored"===S,onChange:()=>I("stored")}),(0,r.jsxs)("span",{children:[(0,r.jsx)("span",{className:"font-medium",children:"Match the numbers in the file"}),(0,r.jsxs)("span",{className:"block text-xs text-muted-foreground",children:["Runs ",D(eS.stored.totalMs),". Faster, and true to the file rather than to the playback."]})]})]})]})]}),(0,r.jsxs)("div",{className:"mt-4 grid gap-3 sm:grid-cols-2 lg:grid-cols-3",children:[(0,r.jsxs)("label",{className:"space-y-1 text-sm",children:[(0,r.jsx)("span",{className:"font-medium",children:"Output format"}),(0,r.jsxs)("select",{value:z,onChange:e=>B(e.target.value),className:(0,j.cn)(eB,"w-full"),children:[(0,r.jsx)("option",{value:"mp4",children:"MP4 (H.264)"}),(0,r.jsx)("option",{value:"webm",children:"WebM (VP9)"})]}),(0,r.jsx)("span",{className:"block text-xs text-muted-foreground",children:null===ei?"Checking which encoders this browser has...":`This browser can write MP4: ${ei.mp4?"yes":"no"}. WebM: ${ei.webm?"yes":"no"}.`})]}),(0,r.jsxs)("label",{className:"space-y-1 text-sm",children:[(0,r.jsx)("span",{className:"font-medium",children:"Quality"}),(0,r.jsxs)("select",{value:U,onChange:e=>O(e.target.value),className:(0,j.cn)(eB,"w-full"),children:[(0,r.jsx)("option",{value:"high",children:"High, closest to the original"}),(0,r.jsx)("option",{value:"medium",children:"Medium"}),(0,r.jsx)("option",{value:"low",children:"Low, smallest file"})]}),(0,r.jsx)("span",{className:"block text-xs text-muted-foreground",children:"The finished size is shown after the conversion, measured rather than predicted."})]}),(0,r.jsxs)("label",{className:"space-y-1 text-sm",children:[(0,r.jsx)("span",{className:"font-medium",children:"Size"}),(0,r.jsx)("select",{value:q,onChange:e=>V(Number(e.target.value)),className:(0,j.cn)(eB,"w-full"),children:T.map(t=>(0,r.jsxs)("option",{value:t,children:[t,"% (",Math.max(2,Math.round(e.width*(t/100)))," by"," ",Math.max(2,Math.round(e.height*(t/100))),")"]},t))}),(0,r.jsx)("span",{className:"block text-xs text-muted-foreground",children:eR.padded?`Video needs even sides, so ${eR.drawW} by ${eR.drawH} is padded to ${eR.outW} by ${eR.outH} with the background color.`:`Writing ${eR.outW} by ${eR.outH}.`})]}),(0,r.jsxs)("label",{className:"space-y-1 text-sm",children:[(0,r.jsx)("span",{className:"font-medium",children:"Backgroun
1d behind transparent areas"}),(0,r.jsxs)("span",{className:"flex items-center gap-2",children:[(0,r.jsx)("input",{type:"color",value:K,onChange:e=>Y(e.target.value),className:"h-9 w-14 cursor-pointer rounded border border-input bg-background","aria-label":"Background color behind transparent areas"}),(0,r.jsx)(M.Gp,{value:K,onChange:Y,onDraftChange:X,"aria-label":"Background color as a hex code"})]}),eL&&(0,r.jsx)("span",{className:"block text-xs text-amber-600 dark:text-amber-500",children:""===Q.replace(/^#/,"")?`The box is empty, so the color in use is still ${K}. Type six hex digits to change it.`:`That is not a full color yet, so ${K} is still the one in use. A hex code is three or six digits.`}),(0,r.jsx)("span",{className:"block text-xs text-muted-foreground",children:e.transparent?"This GIF is transparent in places. Video has no transparency, so those areas get this color.":"This GIF is fully opaque, so this only fills the padding strip if there is one."})]}),(0,r.jsxs)("label",{className:"space-y-1 text-sm",children:[(0,r.jsx)("span",{className:"font-medium",children:"Repeat the animation"}),(0,r.jsx)("select",{value:_,onChange:e=>J(Number(e.target.value)),className:(0,j.cn)(eB,"w-full"),children:F.map(e=>(0,r.jsx)("option",{value:e,children:1===e?"Once":`${e} times`},e))}),(0,r.jsxs)("span",{className:"block text-xs text-muted-foreground",children:["A video carries no loop flag, so this writes the frames again rather than looping them. The file stores a loop count of ",e.loopCountRaw,"."]})]}),(0,r.jsxs)("div",{className:"space-y-1 text-sm",children:[(0,r.jsx)("span",{className:"font-medium",children:"Frames to convert"}),(0,r.jsxs)("div",{className:"flex items-center gap-2",children:[(0,r.jsx)("input",{type:"number",min:1,max:e.framesRead,value:Z+1,onChange:t=>{let a=Math.max(1,Math.min(e.framesRead,Number(t.target.value)||1))-1;ee(a),a>et&&ea(a)},className:(0,j.cn)(eB,"w-20"),"aria-label":"First frame to convert"}),(0,r.jsx)("span",{className:"text-muted-foreground",children:"to"}),(0,r.jsx)("input",{type:"number",min:1,max:e.framesRead,value:et+1,onChange:t=>{let a=Math.max(1,Math.min(e.framesRead,Number(t.target.value)||1))-1;ea(a),a<Z&&ee(a)},className:(0,j.cn)(eB,"w-20"),"aria-label":"Last frame to convert"})]}),(0,r.jsxs)("span",{className:"block text-xs text-muted-foreground",children:[eI.written.length," frame(s) will be written, running ",D(eI.totalMs),"."]})]})]}),(0,r.jsxs)("div",{className:"mt-4 flex flex-wrap items-center gap-2",children:[(0,r.jsxs)(b.$,{onClick:eE,disabled:!eH,children:[ed?(0,r.jsx)(d.A,{className:"mr-1.5 size-4 animate-spin"}):(0,r.jsx)(m.A,{className:"mr-1.5 size-4"}),"Convert to ","webm"===z?"WebM":"MP4"]}),ei&&!ei.mp4&&"mp4"===z&&(0,r.jsx)("span",{className:"text-xs text-muted-foreground",children:"This browser reports no H.264 encoder, so the conversion will stop and say so rather than hand you a WebM named .mp4."})]})]}),er&&eU&&(0,r.jsxs)(r.Fragment,{children:[(0,r.jsxs)("div",{className:"rounded-lg border bg-card p-4",children:[(0,r.jsx)("h2",{className:"text-sm font-semibold",children:"Same moment, both files"}),(0,r.jsx)("p",{className:"mt-1 text-xs text-muted-foreground",children:"One slider drives both panes, so you are comparing the same instant rather than two players that have drifted apart. Drag it anywhere and the pictures should match."}),(0,r.jsxs)("div",{className:"mt-3 grid gap-3 sm:grid-cols-2",children:[(0,r.jsxs)("div",{className:"space-y-1",children:[(0,r.jsx)("div",{className:"text-xs font-medium",children:"Source GIF"}),(0,r.jsx)("div",{className:"flex h-64 items-center justify-center rounded border bg-muted p-1",children:(0,r.jsx)("canvas",{ref:ev,className:"max-h-full max-w-full"})})]}),(0,r.jsxs)("div",{className:"space-y-1",children:[(0,r.jsxs)("div",{className:"text-xs font-medium",children:["Converted ","webm"===er.format?"WebM":"MP4"]}),(0,r.jsx)("div",{className:"flex h-64 items-center justify-center rounded border bg-black p-1",children:(0,r.jsx)("video",{ref:eN,src:er.url,playsInline:!0,preload:"auto",controls:!0,onPlay:()=>{eF.current=!1},onTimeUpdate:e=>{eF.current||el(Math.round(1e3*e.currentTarget.currentTime))},className:"max-h-full max-w-full"})})]})]}),(0,r.jsxs)("label",{className:"mt-3 block text-xs font-medium",htmlFor:"gif-mp4-scrub",children:["Position, ",(en/1e3).toFixed(2),"s of ",D(eU.durationMs)]}),(0,r.jsx)("input",{id:"gif-mp4-scrub",type:"range",min:0,max:Math.max(1,eU.durationMs),step:10,value:Math.min(en,Math.max(1,eU.durationMs)),onChange:e=>{eF.current=!0,eN.current?.pause(),el(Number(e.target.value))},className:"mt-1 w-full"}),(0,r.jsxs)("div",{className:"mt-2 flex flex-wrap gap-2",children:[(0,r.jsxs)(b.$,{variant:"secondary",size:"sm",onClick:()=>{eF.current=!1;let e=eN.current;e&&(e.currentTime=0,e.play())},children:[(0,r.jsx)(f.A,{className:"mr-1.5 size-4"}),"Play the converted file"]}),(0,r.jsxs)(b.$,{onClick:()=>(0,v.WN)(er.blob,er.filename),children:[(0,r.jsx)(p.A,{className:"mr-1.5 size-4"}),"Download ",er.filename]})]})]}),(0,r.jsxs)("div",{className:"rounded-lg border bg-card p-4",children:[(0,r.jsx)("h2",{className:"text-sm font-semibold",children:"What was actually written"}),(0,r.jsx)("p",{className:"mt-1 text-xs text-muted-foreground",children:"Every number below is counted from the frames handed to the encoder, after every cap and every skip. Nothing here is an estimate."}),(0,r.jsxs)("dl",{className:"mt-3 grid gap-x-6 gap-y-1.5 text-sm sm:grid-cols-2",children:[(0,r.jsxs)("div",{className:"flex justify-between gap-3 border-b pb-1",children:[(0,r.jsx)("dt",{className:"text-muted-foreground",children:"Frames written"}),(0,r.jsxs)("dd",{className:"tabular-nums",children:[eU.framesWritten,eU.repeat>1?` (${eU.repeat} passes)`:""]})]}),(0,r.jsxs)("div",{className:"flex justify-between gap-3 border-b pb-1",children:[(0,r.jsx)("dt",{className:"text-muted-foreground",children:"Total length"}),(0,r.jsx)("dd",{className:"tabular-nums",children:D(eU.durationMs)})]}),(0,r.jsxs)("div",{className:"flex justify-between gap-3 border-b pb-1",children:[(0,r.jsx)("dt",{className:"text-muted-foreground",children:"Delay policy used"}),(0,r.jsx)("dd",{children:"played"===eU.policy?"What a browser plays":"The numbers in the file"})]}),(0,r.jsxs)("div",{className:"flex justify-between gap-3 border-b pb-1",children:[(0,r.jsx)("dt",{className:"text-muted-foreground",children:"The other policy would give"}),(0,r.jsx)("dd",{className:"tabular-nums",children:D(eU.otherPolicyMs)})]}),(0,r.jsxs)("div",{className:"flex justify-between gap-3 border-b pb-1",children:[(0,r.jsx)("dt",{className:"text-muted-foreground",children:"Frames storing a delay of 0 or 1"}),(0,r.jsx)("dd",{className:"tabular-nums",children:eU.shortDelayFrames})]}),(0,r.jsxs)("div",{className:"flex justify-between gap-3 border-b pb-1",children:[(0,r.jsxs)("dt",{className:"text-muted-foreground",children:["Frames raised to ",10,"ms"]}),(0,r.jsx)("dd",{className:"tabular-nums",children:eU.raisedFrames})]}),(0,r.jsxs)("div",{className:"flex justify-between gap-3 border-b pb-1",children:[(0,r.jsx)("dt",{className:"text-muted-foreground",children:"Output size on screen"}),(0,r.jsxs)("dd",{className:"tabular-nums",children:[eU.outW," by ",eU.outH,eU.padded?` (padded from ${eU.drawW} by ${eU.drawH})`:""]})]}),(0,r.jsxs)("div",{className:"flex justify-between gap-3 border-b pb-1",children:[(0,r.jsx)("dt",{className:"text-muted-foreground",children:"Backgroun
1d applied"}),(0,r.jsx)("dd",{children:eU.backgroundUsed?eU.background:`${eU.background}, padding only`})]}),(0,r.jsxs)("div",{className:"flex justify-between gap-3 border-b pb-1",children:[(0,r.jsx)("dt",{className:"text-muted-foreground",children:"File size"}),(0,r.jsxs)("dd",{className:"tabular-nums",children:[(0,N.z)(eU.outBytes)," from ",(0,N.z)(eU.inBytes)," (",eU.inBytes>0?`${Math.round(eU.outBytes/eU.inBytes*100)}%`:"n/a",")"]})]}),(0,r.jsxs)("div",{className:"flex justify-between gap-3 border-b pb-1",children:[(0,r.jsx)("dt",{className:"text-muted-foreground",children:"Frames dropped by a cap"}),(0,r.jsx)("dd",{className:"tabular-nums",children:eU.dropped>0?`${eU.dropped} by ${eU.capReason}`:"none"})]}),(0,r.jsxs)("div",{className:"flex justify-between gap-3 border-b pb-1",children:[(0,r.jsx)("dt",{className:"text-muted-foreground",children:"Frames found in the finished file"}),(0,r.jsx)("dd",{className:"tabular-nums",children:eU.packetCount??"not measured"})]}),(0,r.jsxs)("div",{className:"flex justify-between gap-3 border-b pb-1",children:[(0,r.jsx)("dt",{className:"text-muted-foreground",children:"Largest timing difference measured"}),(0,r.jsx)("dd",{className:"tabular-nums",children:null===eU.maxDeviationMs?"not measured":`${eU.maxDeviationMs.toFixed(2)}ms`})]})]}),eU.readBackNote&&(0,r.jsx)("p",{className:"mt-3 text-xs text-muted-foreground",children:eU.readBackNote}),null!==eU.maxDeviationMs&&null!==eU.measuredDurationMs&&(0,r.jsxs)("p",{className:"mt-3 text-xs text-muted-foreground",children:["That difference was read back out of the finished file rather than copied from the plan. The file itself reports a length of ",D(eU.measuredDurationMs),". A video stores times on its own clock, so a fraction of a millisecond of rounding is normal and nothing you will see."]})]}),(0,r.jsxs)("div",{className:"rounded-lg border bg-card p-4",children:[(0,r.jsx)("h2",{className:"text-sm font-semibold",children:"Putting it on a page in place of the GIF"}),(0,r.jsx)("p",{className:"mt-1 text-sm text-muted-foreground",children:"A video file carries no loop instruction, so it plays once unless the page asks it to repeat. This markup is what makes it behave like the GIF did. The muted and playsinline parts are what let it start on its own, especially on a phone."}),(0,r.jsx)("pre",{className:"mt-2 overflow-x-auto rounded border bg-muted p-3 text-xs",children:(0,r.jsx)("code",{children:eG})}),(0,r.jsx)(k.i,{value:eG,label:"Copy the markup",icon:(0,r.jsx)(g.A,{className:"mr-1.5 size-4"}),copiedIcon:(0,r.jsx)(x.A,{className:"mr-1.5 size-4"}),variant:"secondary",size:"sm",className:"mt-2"})]})]})]}),(0,r.jsx)(w.ToolActions,{getParams:eD,title:"GIF to MP4 Converter",queryIsImpersonal:"the timing, format, quality, size and repeat count you chose, plus the background color you picked"})]})}},51974:(e,t,a)=>{a.d(t,{B1:()=>r,L7:()=>n,T7:()=>s,y8:()=>l});let r=100;function s(e){return e<=1?r:10*e}function n(e){return e<=1}function l(e){let t=0;for(let a of e)t+=a;return 10*Math.max(0,Math.round(t/10))}},68206:(e,t,a)=>{a.d(t,{Gp:()=>d,n9:()=>o});var r=a(95155),s=a(12115),n=a(33789),l=a(25016);let i=/^#?[0-9a-fA-F]{0,6}$/;function o(e){let t=e.trim().replace(/^#/,"");if(!/^[0-9a-fA-F]{3}$|^[0-9a-fA-F]{6}$/.test(t))return null;let a=3===t.length?t.split("").map(e=>e+e).join(""):t;return`#${a.toLowerCase()}`}function d({value:e,onChange:t,onDraftChange:a,id:d,className:c,...u}){let[h,m]=(0,s.useState)(e),f=(0,s.useRef)(!1),p=(0,s.useRef)(a);p.current=a;let g=(0,s.useCallback)(e=>{m(e),p.current?.(e)},[]);(0,s.useEffect)(()=>{f.current||g(e)},[e,g]);let x=(0,s.useCallback)(a=>{if(!i.test(a))return;g(a);let r=o(a);r&&r!==e.toLowerCase()&&t(r)},[t,g,e]);return(0,r.jsx)(n.p,{id:d,value:h,onFocus:()=>{f.current=!0},onChange:e=>x(e.target.value),onBlur:()=>{f.current=!1,g(e)},onKeyDown:e=>{"Enter"===e.key&&e.currentTarget.blur()},className:(0,l.cn)("w-28 font-mono text-sm",c),maxLength:7,spellCheck:!1,...u})}}}]);

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.