diff --git a/bin/cli.js b/bin/cli.js index dc4e933..a00fa27 100755 --- a/bin/cli.js +++ b/bin/cli.js @@ -1,23 +1,25 @@ #!/usr/bin/env node -import{createRequire as Mu}from"node:module";var Vu=Object.create;var{getPrototypeOf:yu,defineProperty:RD,getOwnPropertyNames:xu}=Object;var zu=Object.prototype.hasOwnProperty;var s=(u,D,F)=>{F=u!=null?Vu(yu(u)):{};let C=D||!u||!u.__esModule?RD(F,"default",{value:u,enumerable:!0}):F;for(let E of xu(u))if(!zu.call(C,E))RD(C,E,{get:()=>u[E],enumerable:!0});return C};var I=(u,D)=>()=>(D||u((D={exports:{}}).exports,D),D.exports);var v=Mu(import.meta.url);var OD=I((EC,jD)=>{class wD{constructor(u,D,F){this.etaBufferLength=u||100,this.valueBuffer=[F],this.timeBuffer=[D],this.eta="0"}update(u,D,F){this.valueBuffer.push(D),this.timeBuffer.push(u),this.calculate(F-D)}getTime(){return this.eta}calculate(u){let D=this.valueBuffer.length,F=Math.min(this.etaBufferLength,D),C=this.valueBuffer[D-1]-this.valueBuffer[D-F],E=this.timeBuffer[D-1]-this.timeBuffer[D-F],A=C/E;this.valueBuffer=this.valueBuffer.slice(-this.etaBufferLength),this.timeBuffer=this.timeBuffer.slice(-this.etaBufferLength);let B=Math.ceil(u/A/1000);if(isNaN(B))this.eta="NULL";else if(!isFinite(B))this.eta="INF";else if(B>1e7)this.eta="INF";else if(B<0)this.eta=0;else this.eta=B}}jD.exports=wD});var e=I((BC,SD)=>{var w=v("readline");class TD{constructor(u){this.stream=u,this.linewrap=!0,this.dy=0}cursorSave(){if(!this.stream.isTTY)return;this.stream.write("\x1B7")}cursorRestore(){if(!this.stream.isTTY)return;this.stream.write("\x1B8")}cursor(u){if(!this.stream.isTTY)return;if(u)this.stream.write("\x1B[?25h");else this.stream.write("\x1B[?25l")}cursorTo(u=null,D=null){if(!this.stream.isTTY)return;w.cursorTo(this.stream,u,D)}cursorRelative(u=null,D=null){if(!this.stream.isTTY)return;this.dy=this.dy+D,w.moveCursor(this.stream,u,D)}cursorRelativeReset(){if(!this.stream.isTTY)return;w.moveCursor(this.stream,0,-this.dy),w.cursorTo(this.stream,0,null),this.dy=0}clearRight(){if(!this.stream.isTTY)return;w.clearLine(this.stream,1)}clearLine(){if(!this.stream.isTTY)return;w.clearLine(this.stream,0)}clearBottom(){if(!this.stream.isTTY)return;w.clearScreenDown(this.stream)}newline(){this.stream.write(` -`),this.dy++}write(u,D=!1){if(this.linewrap===!0&&D===!1)this.stream.write(u.substr(0,this.getWidth()));else this.stream.write(u)}lineWrapping(u){if(!this.stream.isTTY)return;if(this.linewrap=u,u)this.stream.write("\x1B[?7h");else this.stream.write("\x1B[?7l")}isTTY(){return this.stream.isTTY===!0}getWidth(){return this.stream.columns||(this.stream.isTTY?80:200)}}SD.exports=TD});var vD=I((AC,bD)=>{bD.exports=({onlyFirst:u=!1}={})=>{let D=["[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)","(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-ntqry=><~]))"].join("|");return new RegExp(D,u?void 0:"g")}});var PD=I((qC,hD)=>{var nu=vD();hD.exports=(u)=>typeof u==="string"?u.replace(nu(),""):u});var gD=I((ZC,DD)=>{var fD=(u)=>{if(Number.isNaN(u))return!1;if(u>=4352&&(u<=4447||u===9001||u===9002||11904<=u&&u<=12871&&u!==12351||12880<=u&&u<=19903||19968<=u&&u<=42182||43360<=u&&u<=43388||44032<=u&&u<=55203||63744<=u&&u<=64255||65040<=u&&u<=65049||65072<=u&&u<=65131||65281<=u&&u<=65376||65504<=u&&u<=65510||110592<=u&&u<=110593||127488<=u&&u<=127569||131072<=u&&u<=262141))return!0;return!1};DD.exports=fD;DD.exports.default=fD});var mD=I((QC,cD)=>{cD.exports=function(){return/\uD83C\uDFF4\uDB40\uDC67\uDB40\uDC62(?:\uDB40\uDC65\uDB40\uDC6E\uDB40\uDC67|\uDB40\uDC73\uDB40\uDC63\uDB40\uDC74|\uDB40\uDC77\uDB40\uDC6C\uDB40\uDC73)\uDB40\uDC7F|\uD83D\uDC68(?:\uD83C\uDFFC\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68\uD83C\uDFFB|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFE])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFE\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFD])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFC])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83D\uDC68|(?:\uD83D[\uDC68\uDC69])\u200D(?:\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67]))|\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67])|(?:\uD83D[\uDC68\uDC69])\u200D(?:\uD83D[\uDC66\uDC67])|[\u2695\u2696\u2708]\uFE0F|\uD83D[\uDC66\uDC67]|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|(?:\uD83C\uDFFB\u200D[\u2695\u2696\u2708]|\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708])\uFE0F|\uD83C\uDFFB\u200D(?:\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C[\uDFFB-\uDFFF])|(?:\uD83E\uDDD1\uD83C\uDFFB\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFC\u200D\uD83E\uDD1D\u200D\uD83D\uDC69)\uD83C\uDFFB|\uD83E\uDDD1(?:\uD83C\uDFFF\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1(?:\uD83C[\uDFFB-\uDFFF])|\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1)|(?:\uD83E\uDDD1\uD83C\uDFFE\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFF\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB-\uDFFE])|(?:\uD83E\uDDD1\uD83C\uDFFC\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFD\u200D\uD83E\uDD1D\u200D\uD83D\uDC69)(?:\uD83C[\uDFFB\uDFFC])|\uD83D\uDC69(?:\uD83C\uDFFE\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFD\uDFFF])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFC\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFD-\uDFFF])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFB\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFC-\uDFFF])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D(?:\uD83D[\uDC68\uDC69])|\uD83D[\uDC68\uDC69])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD]))|\uD83D\uDC69\u200D\uD83D\uDC69\u200D(?:\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67]))|(?:\uD83E\uDDD1\uD83C\uDFFD\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFE\u200D\uD83E\uDD1D\u200D\uD83D\uDC69)(?:\uD83C[\uDFFB-\uDFFD])|\uD83D\uDC69\u200D\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC69\u200D\uD83D\uDC69\u200D(?:\uD83D[\uDC66\uDC67])|(?:\uD83D\uDC41\uFE0F\u200D\uD83D\uDDE8|\uD83D\uDC69(?:\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708]|\uD83C\uDFFB\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])|(?:(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)\uFE0F|\uD83D\uDC6F|\uD83E[\uDD3C\uDDDE\uDDDF])\u200D[\u2640\u2642]|(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)(?:\uD83C[\uDFFB-\uDFFF])\u200D[\u2640\u2642]|(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD6-\uDDDD])(?:(?:\uD83C[\uDFFB-\uDFFF])\u200D[\u2640\u2642]|\u200D[\u2640\u2642])|\uD83C\uDFF4\u200D\u2620)\uFE0F|\uD83D\uDC69\u200D\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67])|\uD83C\uDFF3\uFE0F\u200D\uD83C\uDF08|\uD83D\uDC15\u200D\uD83E\uDDBA|\uD83D\uDC69\u200D\uD83D\uDC66|\uD83D\uDC69\u200D\uD83D\uDC67|\uD83C\uDDFD\uD83C\uDDF0|\uD83C\uDDF4\uD83C\uDDF2|\uD83C\uDDF6\uD83C\uDDE6|[#\*0-9]\uFE0F\u20E3|\uD83C\uDDE7(?:\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEF\uDDF1-\uDDF4\uDDF6-\uDDF9\uDDFB\uDDFC\uDDFE\uDDFF])|\uD83C\uDDF9(?:\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDED\uDDEF-\uDDF4\uDDF7\uDDF9\uDDFB\uDDFC\uDDFF])|\uD83C\uDDEA(?:\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDED\uDDF7-\uDDFA])|\uD83E\uDDD1(?:\uD83C[\uDFFB-\uDFFF])|\uD83C\uDDF7(?:\uD83C[\uDDEA\uDDF4\uDDF8\uDDFA\uDDFC])|\uD83D\uDC69(?:\uD83C[\uDFFB-\uDFFF])|\uD83C\uDDF2(?:\uD83C[\uDDE6\uDDE8-\uDDED\uDDF0-\uDDFF])|\uD83C\uDDE6(?:\uD83C[\uDDE8-\uDDEC\uDDEE\uDDF1\uDDF2\uDDF4\uDDF6-\uDDFA\uDDFC\uDDFD\uDDFF])|\uD83C\uDDF0(?:\uD83C[\uDDEA\uDDEC-\uDDEE\uDDF2\uDDF3\uDDF5\uDDF7\uDDFC\uDDFE\uDDFF])|\uD83C\uDDED(?:\uD83C[\uDDF0\uDDF2\uDDF3\uDDF7\uDDF9\uDDFA])|\uD83C\uDDE9(?:\uD83C[\uDDEA\uDDEC\uDDEF\uDDF0\uDDF2\uDDF4\uDDFF])|\uD83C\uDDFE(?:\uD83C[\uDDEA\uDDF9])|\uD83C\uDDEC(?:\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEE\uDDF1-\uDDF3\uDDF5-\uDDFA\uDDFC\uDDFE])|\uD83C\uDDF8(?:\uD83C[\uDDE6-\uDDEA\uDDEC-\uDDF4\uDDF7-\uDDF9\uDDFB\uDDFD-\uDDFF])|\uD83C\uDDEB(?:\uD83C[\uDDEE-\uDDF0\uDDF2\uDDF4\uDDF7])|\uD83C\uDDF5(?:\uD83C[\uDDE6\uDDEA-\uDDED\uDDF0-\uDDF3\uDDF7-\uDDF9\uDDFC\uDDFE])|\uD83C\uDDFB(?:\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDEE\uDDF3\uDDFA])|\uD83C\uDDF3(?:\uD83C[\uDDE6\uDDE8\uDDEA-\uDDEC\uDDEE\uDDF1\uDDF4\uDDF5\uDDF7\uDDFA\uDDFF])|\uD83C\uDDE8(?:\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDEE\uDDF0-\uDDF5\uDDF7\uDDFA-\uDDFF])|\uD83C\uDDF1(?:\uD83C[\uDDE6-\uDDE8\uDDEE\uDDF0\uDDF7-\uDDFB\uDDFE])|\uD83C\uDDFF(?:\uD83C[\uDDE6\uDDF2\uDDFC])|\uD83C\uDDFC(?:\uD83C[\uDDEB\uDDF8])|\uD83C\uDDFA(?:\uD83C[\uDDE6\uDDEC\uDDF2\uDDF3\uDDF8\uDDFE\uDDFF])|\uD83C\uDDEE(?:\uD83C[\uDDE8-\uDDEA\uDDF1-\uDDF4\uDDF6-\uDDF9])|\uD83C\uDDEF(?:\uD83C[\uDDEA\uDDF2\uDDF4\uDDF5])|(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD6-\uDDDD])(?:\uD83C[\uDFFB-\uDFFF])|(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)(?:\uD83C[\uDFFB-\uDFFF])|(?:[\u261D\u270A-\u270D]|\uD83C[\uDF85\uDFC2\uDFC7]|\uD83D[\uDC42\uDC43\uDC46-\uDC50\uDC66\uDC67\uDC6B-\uDC6D\uDC70\uDC72\uDC74-\uDC76\uDC78\uDC7C\uDC83\uDC85\uDCAA\uDD74\uDD7A\uDD90\uDD95\uDD96\uDE4C\uDE4F\uDEC0\uDECC]|\uD83E[\uDD0F\uDD18-\uDD1C\uDD1E\uDD1F\uDD30-\uDD36\uDDB5\uDDB6\uDDBB\uDDD2-\uDDD5])(?:\uD83C[\uDFFB-\uDFFF])|(?:[\u231A\u231B\u23E9-\u23EC\u23F0\u23F3\u25FD\u25FE\u2614\u2615\u2648-\u2653\u267F\u2693\u26A1\u26AA\u26AB\u26BD\u26BE\u26C4\u26C5\u26CE\u26D4\u26EA\u26F2\u26F3\u26F5\u26FA\u26FD\u2705\u270A\u270B\u2728\u274C\u274E\u2753-\u2755\u2757\u2795-\u2797\u27B0\u27BF\u2B1B\u2B1C\u2B50\u2B55]|\uD83C[\uDC04\uDCCF\uDD8E\uDD91-\uDD9A\uDDE6-\uDDFF\uDE01\uDE1A\uDE2F\uDE32-\uDE36\uDE38-\uDE3A\uDE50\uDE51\uDF00-\uDF20\uDF2D-\uDF35\uDF37-\uDF7C\uDF7E-\uDF93\uDFA0-\uDFCA\uDFCF-\uDFD3\uDFE0-\uDFF0\uDFF4\uDFF8-\uDFFF]|\uD83D[\uDC00-\uDC3E\uDC40\uDC42-\uDCFC\uDCFF-\uDD3D\uDD4B-\uDD4E\uDD50-\uDD67\uDD7A\uDD95\uDD96\uDDA4\uDDFB-\uDE4F\uDE80-\uDEC5\uDECC\uDED0-\uDED2\uDED5\uDEEB\uDEEC\uDEF4-\uDEFA\uDFE0-\uDFEB]|\uD83E[\uDD0D-\uDD3A\uDD3C-\uDD45\uDD47-\uDD71\uDD73-\uDD76\uDD7A-\uDDA2\uDDA5-\uDDAA\uDDAE-\uDDCA\uDDCD-\uDDFF\uDE70-\uDE73\uDE78-\uDE7A\uDE80-\uDE82\uDE90-\uDE95])|(?:[#\*0-9\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u231A\u231B\u2328\u23CF\u23E9-\u23F3\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB-\u25FE\u2600-\u2604\u260E\u2611\u2614\u2615\u2618\u261D\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u2648-\u2653\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u267F\u2692-\u2697\u2699\u269B\u269C\u26A0\u26A1\u26AA\u26AB\u26B0\u26B1\u26BD\u26BE\u26C4\u26C5\u26C8\u26CE\u26CF\u26D1\u26D3\u26D4\u26E9\u26EA\u26F0-\u26F5\u26F7-\u26FA\u26FD\u2702\u2705\u2708-\u270D\u270F\u2712\u2714\u2716\u271D\u2721\u2728\u2733\u2734\u2744\u2747\u274C\u274E\u2753-\u2755\u2757\u2763\u2764\u2795-\u2797\u27A1\u27B0\u27BF\u2934\u2935\u2B05-\u2B07\u2B1B\u2B1C\u2B50\u2B55\u3030\u303D\u3297\u3299]|\uD83C[\uDC04\uDCCF\uDD70\uDD71\uDD7E\uDD7F\uDD8E\uDD91-\uDD9A\uDDE6-\uDDFF\uDE01\uDE02\uDE1A\uDE2F\uDE32-\uDE3A\uDE50\uDE51\uDF00-\uDF21\uDF24-\uDF93\uDF96\uDF97\uDF99-\uDF9B\uDF9E-\uDFF0\uDFF3-\uDFF5\uDFF7-\uDFFF]|\uD83D[\uDC00-\uDCFD\uDCFF-\uDD3D\uDD49-\uDD4E\uDD50-\uDD67\uDD6F\uDD70\uDD73-\uDD7A\uDD87\uDD8A-\uDD8D\uDD90\uDD95\uDD96\uDDA4\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA-\uDE4F\uDE80-\uDEC5\uDECB-\uDED2\uDED5\uDEE0-\uDEE5\uDEE9\uDEEB\uDEEC\uDEF0\uDEF3-\uDEFA\uDFE0-\uDFEB]|\uD83E[\uDD0D-\uDD3A\uDD3C-\uDD45\uDD47-\uDD71\uDD73-\uDD76\uDD7A-\uDDA2\uDDA5-\uDDAA\uDDAE-\uDDCA\uDDCD-\uDDFF\uDE70-\uDE73\uDE78-\uDE7A\uDE80-\uDE82\uDE90-\uDE95])\uFE0F|(?:[\u261D\u26F9\u270A-\u270D]|\uD83C[\uDF85\uDFC2-\uDFC4\uDFC7\uDFCA-\uDFCC]|\uD83D[\uDC42\uDC43\uDC46-\uDC50\uDC66-\uDC78\uDC7C\uDC81-\uDC83\uDC85-\uDC87\uDC8F\uDC91\uDCAA\uDD74\uDD75\uDD7A\uDD90\uDD95\uDD96\uDE45-\uDE47\uDE4B-\uDE4F\uDEA3\uDEB4-\uDEB6\uDEC0\uDECC]|\uD83E[\uDD0F\uDD18-\uDD1F\uDD26\uDD30-\uDD39\uDD3C-\uDD3E\uDDB5\uDDB6\uDDB8\uDDB9\uDDBB\uDDCD-\uDDCF\uDDD1-\uDDDD])/g}});var lD=I((XC,uD)=>{var pu=PD(),au=gD(),su=mD(),dD=(u)=>{if(typeof u!=="string"||u.length===0)return 0;if(u=pu(u),u.length===0)return 0;u=u.replace(su()," ");let D=0;for(let F=0;F=127&&C<=159)continue;if(C>=768&&C<=879)continue;if(C>65535)F++;D+=au(C)?2:1}return D};uD.exports=dD;uD.exports.default=dD});var FD=I((YC,nD)=>{nD.exports=function(D,F,C){if(F.autopadding!==!0)return D;function E(A,B){return(F.autopaddingChar+A).slice(-B)}switch(C){case"percentage":return E(D,3);default:return D}}});var CD=I((JC,pD)=>{pD.exports=function(D,F){let C=Math.round(D*F.barsize),E=F.barsize-C;return F.barCompleteString.substr(0,C)+F.barGlue+F.barIncompleteString.substr(0,E)}});var ED=I((KC,aD)=>{aD.exports=function(D,F,C){function E(B){if(C)return C*Math.round(B/C);else return B}function A(B){return(F.autopaddingChar+B).slice(-2)}if(D>3600)return A(Math.floor(D/3600))+"h"+A(E(D%3600/60))+"m";else if(D>60)return A(Math.floor(D/60))+"m"+A(E(D%60))+"s";else if(D>10)return A(E(D))+"s";else return A(D)+"s"}});var BD=I((LC,sD)=>{var ru=lD(),iu=FD(),ou=CD(),tu=ED();sD.exports=function(D,F,C){let E=D.format,A=D.formatTime||tu,B=D.formatValue||iu,q=D.formatBar||ou,Q=Math.floor(F.progress*100)+"",J=F.stopTime||Date.now(),L=Math.round((J-F.startTime)/1000),G=Object.assign({},C,{bar:q(F.progress,D),percentage:B(Q,D,"percentage"),total:B(F.total,D,"total"),value:B(F.value,D,"value"),eta:B(F.eta,D,"eta"),eta_formatted:A(F.eta,D,5),duration:B(L,D,"duration"),duration_formatted:A(L,D,1)});E=E.replace(/\{(\w+)\}/g,function(Z,R){if(typeof G[R]<"u")return G[R];return Z});let X=Math.max(0,F.maxWidth-ru(E)-2),Y=Math.floor(X/2);switch(D.align){case"right":E=X>0?" ".repeat(X)+E:E;break;case"center":E=Y>0?" ".repeat(Y)+E:E;break;case"left":default:break}return E}});var d=I((GC,rD)=>{function K(u,D){if(typeof u>"u"||u===null)return D;else return u}rD.exports={parse:function(D,F){let C={},E=Object.assign({},F,D);return C.throttleTime=1000/K(E.fps,10),C.stream=K(E.stream,process.stderr),C.terminal=K(E.terminal,null),C.clearOnComplete=K(E.clearOnComplete,!1),C.stopOnComplete=K(E.stopOnComplete,!1),C.barsize=K(E.barsize,40),C.align=K(E.align,"left"),C.hideCursor=K(E.hideCursor,!1),C.linewrap=K(E.linewrap,!1),C.barGlue=K(E.barGlue,""),C.barCompleteChar=K(E.barCompleteChar,"="),C.barIncompleteChar=K(E.barIncompleteChar,"-"),C.format=K(E.format,"progress [{bar}] {percentage}% | ETA: {eta}s | {value}/{total}"),C.formatTime=K(E.formatTime,null),C.formatValue=K(E.formatValue,null),C.formatBar=K(E.formatBar,null),C.etaBufferLength=K(E.etaBuffer,10),C.etaAsynchronousUpdate=K(E.etaAsynchronousUpdate,!1),C.progressCalculationRelative=K(E.progressCalculationRelative,!1),C.synchronousUpdate=K(E.synchronousUpdate,!0),C.noTTYOutput=K(E.noTTYOutput,!1),C.notTTYSchedule=K(E.notTTYSchedule,2000),C.emptyOnZero=K(E.emptyOnZero,!1),C.forceRedraw=K(E.forceRedraw,!1),C.autopadding=K(E.autopadding,!1),C.gracefulExit=K(E.gracefulExit,!1),C},assignDerivedOptions:function(D){return D.barCompleteString=D.barCompleteChar.repeat(D.barsize+1),D.barIncompleteString=D.barIncompleteChar.repeat(D.barsize+1),D.autopaddingChar=D.autopadding?K(D.autopaddingChar," "):"",D}}});var AD=I((IC,oD)=>{var iD=OD(),eu=e(),DF=BD(),uF=d(),FF=v("events");oD.exports=class extends FF{constructor(D){super();this.options=uF.assignDerivedOptions(D),this.terminal=this.options.terminal?this.options.terminal:new eu(this.options.stream),this.value=0,this.startValue=0,this.total=100,this.lastDrawnString=null,this.startTime=null,this.stopTime=null,this.lastRedraw=Date.now(),this.eta=new iD(this.options.etaBufferLength,0,0),this.payload={},this.isActive=!1,this.formatter=typeof this.options.format==="function"?this.options.format:DF}render(D=!1){let F={progress:this.getProgress(),eta:this.eta.getTime(),startTime:this.startTime,stopTime:this.stopTime,total:this.total,value:this.value,maxWidth:this.terminal.getWidth()};if(this.options.etaAsynchronousUpdate)this.updateETA();let C=this.formatter(this.options,F,this.payload);if(D||this.options.forceRedraw||this.options.noTTYOutput&&!this.terminal.isTTY()||this.lastDrawnString!=C)this.emit("redraw-pre"),this.terminal.cursorTo(0,null),this.terminal.write(C),this.terminal.clearRight(),this.lastDrawnString=C,this.lastRedraw=Date.now(),this.emit("redraw-post")}start(D,F,C){this.value=F||0,this.total=typeof D<"u"&&D>=0?D:100,this.startValue=F||0,this.payload=C||{},this.startTime=Date.now(),this.stopTime=null,this.lastDrawnString="",this.eta=new iD(this.options.etaBufferLength,this.startTime,this.value),this.isActive=!0,this.emit("start",D,F)}stop(){this.isActive=!1,this.stopTime=Date.now(),this.emit("stop",this.total,this.value)}update(D,F={}){if(typeof D==="number")this.value=D,this.eta.update(Date.now(),D,this.total);let C=(typeof D==="object"?D:F)||{};this.emit("update",this.total,this.value);for(let E in C)this.payload[E]=C[E];if(this.value>=this.getTotal()&&this.options.stopOnComplete)this.stop()}getProgress(){let D=this.value/this.total;if(this.options.progressCalculationRelative)D=(this.value-this.startValue)/(this.total-this.startValue);if(isNaN(D))D=this.options&&this.options.emptyOnZero?0:1;return D=Math.min(Math.max(D,0),1),D}increment(D=1,F={}){if(typeof D==="object")this.update(this.value+1,D);else this.update(this.value+D,F)}getTotal(){return this.total}setTotal(D){if(typeof D<"u"&&D>=0)this.total=D}updateETA(){this.eta.update(Date.now(),this.value,this.total)}}});var eD=I((RC,tD)=>{var CF=AD(),EF=d();tD.exports=class extends CF{constructor(D,F){super(EF.parse(D,F));if(this.timer=null,this.options.noTTYOutput&&this.terminal.isTTY()===!1)this.options.synchronousUpdate=!1;this.schedulingRate=this.terminal.isTTY()?this.options.throttleTime:this.options.notTTYSchedule,this.sigintCallback=null}render(){if(this.timer)clearTimeout(this.timer),this.timer=null;if(super.render(),this.options.noTTYOutput&&this.terminal.isTTY()===!1)this.terminal.newline();this.timer=setTimeout(this.render.bind(this),this.schedulingRate)}update(D,F){if(!this.timer)return;if(super.update(D,F),this.options.synchronousUpdate&&this.lastRedraw+this.options.throttleTime*2{var BF=e(),AF=AD(),qF=d(),ZF=v("events");Du.exports=class extends ZF{constructor(D,F){super();this.bars=[],this.options=qF.parse(D,F),this.options.synchronousUpdate=!1,this.terminal=this.options.terminal?this.options.terminal:new BF(this.options.stream),this.timer=null,this.isActive=!1,this.schedulingRate=this.terminal.isTTY()?this.options.throttleTime:this.options.notTTYSchedule,this.loggingBuffer=[],this.sigintCallback=null}create(D,F,C,E={}){let A=new AF(Object.assign({},this.options,{terminal:this.terminal},E));if(this.bars.push(A),this.options.noTTYOutput===!1&&this.terminal.isTTY()===!1)return A;if(this.sigintCallback===null&&this.options.gracefulExit)this.sigintCallback=this.stop.bind(this),process.once("SIGINT",this.sigintCallback),process.once("SIGTERM",this.sigintCallback);if(!this.isActive){if(this.options.hideCursor===!0)this.terminal.cursor(!1);if(this.options.linewrap===!1)this.terminal.lineWrapping(!1);this.timer=setTimeout(this.update.bind(this),this.schedulingRate)}return this.isActive=!0,A.start(D,F,C),this.emit("start"),A}remove(D){let F=this.bars.indexOf(D);if(F<0)return!1;return this.bars.splice(F,1),this.update(),this.terminal.newline(),this.terminal.clearBottom(),!0}update(){if(this.timer)clearTimeout(this.timer),this.timer=null;if(this.emit("update-pre"),this.terminal.cursorRelativeReset(),this.emit("redraw-pre"),this.loggingBuffer.length>0){this.terminal.clearLine();while(this.loggingBuffer.length>0)this.terminal.write(this.loggingBuffer.shift(),!0)}for(let D=0;D0)this.terminal.newline();this.bars[D].render()}if(this.emit("redraw-post"),this.options.noTTYOutput&&this.terminal.isTTY()===!1)this.terminal.newline(),this.terminal.newline();if(this.timer=setTimeout(this.update.bind(this),this.schedulingRate),this.emit("update-post"),this.options.stopOnComplete&&!this.bars.find((D)=>D.isActive))this.stop()}stop(){if(clearTimeout(this.timer),this.timer=null,this.sigintCallback)process.removeListener("SIGINT",this.sigintCallback),process.removeListener("SIGTERM",this.sigintCallback),this.sigintCallback=null;if(this.isActive=!1,this.options.hideCursor===!0)this.terminal.cursor(!0);if(this.options.linewrap===!1)this.terminal.lineWrapping(!0);if(this.terminal.cursorRelativeReset(),this.emit("stop-pre-clear"),this.options.clearOnComplete)this.terminal.clearBottom();else{for(let D=0;D0)this.terminal.newline();this.bars[D].render(),this.bars[D].stop()}this.terminal.newline()}this.emit("stop")}log(D){this.loggingBuffer.push(D)}}});var Cu=I((UC,Fu)=>{Fu.exports={format:"progress [{bar}] {percentage}% | ETA: {eta}s | {value}/{total}",barCompleteChar:"=",barIncompleteChar:"-"}});var Bu=I((kC,Eu)=>{Eu.exports={format:" {bar} {percentage}% | ETA: {eta}s | {value}/{total}",barCompleteChar:"█",barIncompleteChar:"░"}});var qu=I((_C,Au)=>{Au.exports={format:" \x1B[90m{bar}\x1B[0m {percentage}% | ETA: {eta}s | {value}/{total}",barCompleteChar:"█",barIncompleteChar:"░"}});var Qu=I((HC,Zu)=>{Zu.exports={format:" {bar}■ {percentage}% | ETA: {eta}s | {value}/{total}",barCompleteChar:"■",barIncompleteChar:" "}});var Yu=I((WC,Xu)=>{var QF=Cu(),XF=Bu(),YF=qu(),JF=Qu();Xu.exports={legacy:QF,shades_classic:XF,shades_grey:YF,rect:JF}});var Lu=I((VC,Ku)=>{var Ju=eD(),KF=uu(),LF=Yu(),GF=BD(),IF=FD(),RF=CD(),$F=ED();Ku.exports={Bar:Ju,SingleBar:Ju,MultiBar:KF,Presets:LF,Format:{Formatter:GF,BarFormat:RF,ValueFormat:IF,TimeFormat:$F}}});import{join as MD,basename as cu,extname as mu}from"node:path";import{randomUUID as du}from"node:crypto";import{rm as ND}from"node:fs/promises";import{spawn as h}from"node:child_process";async function j(){return new Promise((u)=>{let D=h("ffmpeg",["-version"]);D.on("error",()=>u(!1)),D.on("close",(F)=>u(F===0))})}async function O(){return new Promise((u)=>{let D=h("MP4Box",["-version"]);D.on("error",()=>u(!1)),D.on("close",(F)=>u(F===0))})}async function T(){return new Promise((u)=>{let D=h("ffmpeg",["-hide_banner","-encoders"]),F="";D.stdout.on("data",(C)=>{F+=C.toString()}),D.on("error",()=>u(!1)),D.on("close",(C)=>{if(C!==0)u(!1);else u(F.includes("h264_nvenc")||F.includes("hevc_nvenc"))})})}async function M(u,D,F){return new Promise((C,E)=>{let A=h("ffmpeg",u),B="";A.stderr.on("data",(q)=>{let Q=q.toString();if(B+=Q,D&&F){let J=Q.match(/time=(\d{2}):(\d{2}):(\d{2}\.\d{2})/);if(J){let L=parseInt(J[1]),G=parseInt(J[2]),X=parseFloat(J[3]),Y=L*3600+G*60+X,Z=Math.min(100,Y/F*100);D(Z)}}}),A.on("error",(q)=>{E(Error(`FFmpeg error: ${q.message}`))}),A.on("close",(q)=>{if(q===0)C();else E(Error(`FFmpeg failed with exit code ${q} -${B}`))})})}async function r(u){return new Promise((D,F)=>{let C=h("MP4Box",u),E="",A="";C.stdout.on("data",(B)=>{E+=B.toString()}),C.stderr.on("data",(B)=>{A+=B.toString()}),C.on("error",(B)=>{F(Error(`MP4Box error: ${B.message}`))}),C.on("close",(B)=>{if(B===0)D();else F(Error(`MP4Box failed with exit code ${B} -${A||E}`))})})}import{spawn as Nu}from"node:child_process";async function S(u){return new Promise((D,F)=>{let C=Nu("ffprobe",["-v","error","-show_entries","stream=width,height,duration,r_frame_rate,codec_name,codec_type,bit_rate","-show_entries","format=duration","-of","json",u]),E="";C.stdout.on("data",(A)=>{E+=A.toString()}),C.on("error",(A)=>{F(Error(`ffprobe error: ${A.message}`))}),C.on("close",(A)=>{if(A!==0){F(Error(`ffprobe failed with exit code ${A}`));return}try{let B=JSON.parse(E),q=B.streams.find((Z)=>Z.codec_type==="video"),Q=B.streams.find((Z)=>Z.codec_type==="audio"&&Z.bit_rate),J=B.format;if(!q){F(Error("No video stream found in input file"));return}let L=30;if(q.r_frame_rate){let[Z,R]=q.r_frame_rate.split("/").map(Number);if(Z&&R&&R!==0)L=Z/R}let G=parseFloat(q.duration||J.duration||"0"),X=Q?.bit_rate?Math.round(parseInt(Q.bit_rate)/1000):void 0,Y=q.bit_rate?Math.round(parseInt(q.bit_rate)/1000):void 0;D({width:q.width,height:q.height,duration:G,fps:L,codec:q.codec_name,audioBitrate:X,videoBitrate:Y})}catch(B){F(Error(`Failed to parse ffprobe output: ${B}`))}})})}function g(u,D=256){if(!u)return`${D}k`;let F=Math.min(u,D);if(F<=64)return"64k";if(F<=96)return"96k";if(F<=128)return"128k";if(F<=192)return"192k";return"256k"}function c(u){let D=Math.floor(u/3600),F=Math.floor(u%3600/60),C=u%60;return`${String(D).padStart(2,"0")}:${String(F).padStart(2,"0")}:${C.toFixed(3).padStart(6,"0")}`}import{mkdir as wu,access as ju,constants as Ou}from"node:fs/promises";async function b(u){try{await ju(u,Ou.F_OK)}catch{await wu(u,{recursive:!0})}}function Tu(u,D){let F=u*D;if(F<=230400)return 0.08;if(F<=409920)return 0.075;if(F<=921600)return 0.07;if(F<=2073600)return 0.065;if(F<=3686400)return 0.06;return 0.055}function x(u,D,F=30,C){let E=Tu(u,D),A=Math.round(u*D*F*E/1000);if(C&&A>C)A=C;return`${A}k`}var i=[{name:"360p",width:640,height:360,videoBitrate:x(640,360,30),audioBitrate:"192k"},{name:"480p",width:854,height:480,videoBitrate:x(854,480,30),audioBitrate:"192k"},{name:"720p",width:1280,height:720,videoBitrate:x(1280,720,30),audioBitrate:"192k"},{name:"1080p",width:1920,height:1080,videoBitrate:x(1920,1080,30),audioBitrate:"256k"},{name:"1440p",width:2560,height:1440,videoBitrate:x(2560,1440,30),audioBitrate:"256k"},{name:"2160p",width:3840,height:2160,videoBitrate:x(3840,2160,30),audioBitrate:"256k"}];function o(u,D,F=30,C){let E=[],A=i.filter((B)=>{return B.width<=u&&B.height<=D});for(let B of A)E.push({...B,videoBitrate:x(B.width,B.height,30,C)});if(F>=45)for(let B of A)E.push(m(B,60,C));if(F>=75)for(let B of A)E.push(m(B,90,C));if(F>=95)for(let B of A)E.push(m(B,120,C));return E}function m(u,D,F){return{...u,name:`${u.name}-${D}`,videoBitrate:x(u.width,u.height,D,F)}}function $D(u){let F=u.trim().match(/^(\d+)p?(?:[@-](\d+))?$/i);if(!F)return null;let C=F[1]+"p",E=F[2]?parseInt(F[2]):30;return{resolution:C,fps:E}}function UD(u,D=30,F){let C=i.find((E)=>E.name===u);if(!C)return null;if(D===30)return{...C,videoBitrate:x(C.width,C.height,30,F)};return m(C,D,F)}function Su(u,D,F,C){let E=$D(u);if(!E)return`Invalid profile format: ${u}. Use format like: 360, 720@60, 1080-60`;let A=UD(E.resolution,E.fps);if(!A)return`Unknown resolution: ${E.resolution}. Available: 360, 480, 720, 1080, 1440, 2160`;if(A.width>D||A.height>F)return`Source resolution (${D}x${F}) is lower than ${u} (${A.width}x${A.height})`;if(E.fps>C)return`Source FPS (${C}) is lower than requested ${E.fps} FPS in ${u}`;return null}function kD(u,D,F,C,E){let A=[],B=[];for(let q of u){let Q=Su(q,D,F,C);if(Q){B.push(Q);continue}let J=$D(q);if(!J)continue;let L=UD(J.resolution,J.fps,E);if(L)A.push(L)}return{profiles:A,errors:B}}import{join as z}from"node:path";import{readdir as bu,unlink as _D,rmdir as vu,writeFile as HD}from"node:fs/promises";async function WD(u,D,F="00:00:01"){let C=z(D,"poster.jpg"),E=/^\d+(\.\d+)?$/.test(F)?F:F;return await M(["-ss",E,"-i",u,"-vframes","1","-q:v","2","-y",C]),C}async function VD(u,D,F,C){let{width:E,height:A,interval:B,columns:q}=C,Q=z(D,".thumbnails_temp");await b(Q),await HD(z(Q,".keep"),"");let J=z(Q,"thumb_%04d.jpg");await M(["-i",u,"-vf",`fps=1/${B},scale=${E}:${A}`,"-q:v","5",J]);let G=(await bu(Q)).filter((_)=>_.startsWith("thumb_")&&_.endsWith(".jpg")).sort();if(G.length===0)throw Error("No thumbnails generated");let X=G.length,Y=Math.ceil(X/q),Z=z(D,"thumbnails.jpg"),R=`tile=${q}x${Y}`;await M(["-i",J,"-filter_complex",R,"-q:v","5",Z]);let U=z(D,"thumbnails.vtt"),$=hu(X,B,E,A,q,"thumbnails.jpg");await HD(U,$);for(let _ of G)await _D(z(Q,_));return await _D(z(Q,".keep")),await vu(Q),{spritePath:Z,vttPath:U}}function hu(u,D,F,C,E,A){let B=`WEBVTT +import{createRequire as Pu}from"node:module";var Tu=Object.create;var{getPrototypeOf:bu,defineProperty:xD,getOwnPropertyNames:vu}=Object;var hu=Object.prototype.hasOwnProperty;var DD=(u,D,F)=>{F=u!=null?Tu(bu(u)):{};let C=D||!u||!u.__esModule?xD(F,"default",{value:u,enumerable:!0}):F;for(let E of vu(u))if(!hu.call(C,E))xD(C,E,{get:()=>u[E],enumerable:!0});return C};var k=(u,D)=>()=>(D||u((D={exports:{}}).exports,D),D.exports);var l=Pu(import.meta.url);var mD=k((GC,gD)=>{class fD{constructor(u,D,F){this.etaBufferLength=u||100,this.valueBuffer=[F],this.timeBuffer=[D],this.eta="0"}update(u,D,F){this.valueBuffer.push(D),this.timeBuffer.push(u),this.calculate(F-D)}getTime(){return this.eta}calculate(u){let D=this.valueBuffer.length,F=Math.min(this.etaBufferLength,D),C=this.valueBuffer[D-1]-this.valueBuffer[D-F],E=this.timeBuffer[D-1]-this.timeBuffer[D-F],A=C/E;this.valueBuffer=this.valueBuffer.slice(-this.etaBufferLength),this.timeBuffer=this.timeBuffer.slice(-this.etaBufferLength);let B=Math.ceil(u/A/1000);if(isNaN(B))this.eta="NULL";else if(!isFinite(B))this.eta="INF";else if(B>1e7)this.eta="INF";else if(B<0)this.eta=0;else this.eta=B}}gD.exports=fD});var BD=k(($C,lD)=>{var y=l("readline");class cD{constructor(u){this.stream=u,this.linewrap=!0,this.dy=0}cursorSave(){if(!this.stream.isTTY)return;this.stream.write("\x1B7")}cursorRestore(){if(!this.stream.isTTY)return;this.stream.write("\x1B8")}cursor(u){if(!this.stream.isTTY)return;if(u)this.stream.write("\x1B[?25h");else this.stream.write("\x1B[?25l")}cursorTo(u=null,D=null){if(!this.stream.isTTY)return;y.cursorTo(this.stream,u,D)}cursorRelative(u=null,D=null){if(!this.stream.isTTY)return;this.dy=this.dy+D,y.moveCursor(this.stream,u,D)}cursorRelativeReset(){if(!this.stream.isTTY)return;y.moveCursor(this.stream,0,-this.dy),y.cursorTo(this.stream,0,null),this.dy=0}clearRight(){if(!this.stream.isTTY)return;y.clearLine(this.stream,1)}clearLine(){if(!this.stream.isTTY)return;y.clearLine(this.stream,0)}clearBottom(){if(!this.stream.isTTY)return;y.clearScreenDown(this.stream)}newline(){this.stream.write(` +`),this.dy++}write(u,D=!1){if(this.linewrap===!0&&D===!1)this.stream.write(u.substr(0,this.getWidth()));else this.stream.write(u)}lineWrapping(u){if(!this.stream.isTTY)return;if(this.linewrap=u,u)this.stream.write("\x1B[?7h");else this.stream.write("\x1B[?7l")}isTTY(){return this.stream.isTTY===!0}getWidth(){return this.stream.columns||(this.stream.isTTY?80:200)}}lD.exports=cD});var nD=k((RC,dD)=>{dD.exports=({onlyFirst:u=!1}={})=>{let D=["[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)","(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-ntqry=><~]))"].join("|");return new RegExp(D,u?void 0:"g")}});var aD=k((UC,pD)=>{var uF=nD();pD.exports=(u)=>typeof u==="string"?u.replace(uF(),""):u});var rD=k((kC,AD)=>{var sD=(u)=>{if(Number.isNaN(u))return!1;if(u>=4352&&(u<=4447||u===9001||u===9002||11904<=u&&u<=12871&&u!==12351||12880<=u&&u<=19903||19968<=u&&u<=42182||43360<=u&&u<=43388||44032<=u&&u<=55203||63744<=u&&u<=64255||65040<=u&&u<=65049||65072<=u&&u<=65131||65281<=u&&u<=65376||65504<=u&&u<=65510||110592<=u&&u<=110593||127488<=u&&u<=127569||131072<=u&&u<=262141))return!0;return!1};AD.exports=sD;AD.exports.default=sD});var oD=k((_C,iD)=>{iD.exports=function(){return/\uD83C\uDFF4\uDB40\uDC67\uDB40\uDC62(?:\uDB40\uDC65\uDB40\uDC6E\uDB40\uDC67|\uDB40\uDC73\uDB40\uDC63\uDB40\uDC74|\uDB40\uDC77\uDB40\uDC6C\uDB40\uDC73)\uDB40\uDC7F|\uD83D\uDC68(?:\uD83C\uDFFC\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68\uD83C\uDFFB|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFE])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFE\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFD])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFC])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83D\uDC68|(?:\uD83D[\uDC68\uDC69])\u200D(?:\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67]))|\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67])|(?:\uD83D[\uDC68\uDC69])\u200D(?:\uD83D[\uDC66\uDC67])|[\u2695\u2696\u2708]\uFE0F|\uD83D[\uDC66\uDC67]|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|(?:\uD83C\uDFFB\u200D[\u2695\u2696\u2708]|\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708])\uFE0F|\uD83C\uDFFB\u200D(?:\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C[\uDFFB-\uDFFF])|(?:\uD83E\uDDD1\uD83C\uDFFB\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFC\u200D\uD83E\uDD1D\u200D\uD83D\uDC69)\uD83C\uDFFB|\uD83E\uDDD1(?:\uD83C\uDFFF\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1(?:\uD83C[\uDFFB-\uDFFF])|\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1)|(?:\uD83E\uDDD1\uD83C\uDFFE\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFF\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB-\uDFFE])|(?:\uD83E\uDDD1\uD83C\uDFFC\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFD\u200D\uD83E\uDD1D\u200D\uD83D\uDC69)(?:\uD83C[\uDFFB\uDFFC])|\uD83D\uDC69(?:\uD83C\uDFFE\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFD\uDFFF])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFC\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFD-\uDFFF])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFB\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFC-\uDFFF])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D(?:\uD83D[\uDC68\uDC69])|\uD83D[\uDC68\uDC69])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD]))|\uD83D\uDC69\u200D\uD83D\uDC69\u200D(?:\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67]))|(?:\uD83E\uDDD1\uD83C\uDFFD\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFE\u200D\uD83E\uDD1D\u200D\uD83D\uDC69)(?:\uD83C[\uDFFB-\uDFFD])|\uD83D\uDC69\u200D\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC69\u200D\uD83D\uDC69\u200D(?:\uD83D[\uDC66\uDC67])|(?:\uD83D\uDC41\uFE0F\u200D\uD83D\uDDE8|\uD83D\uDC69(?:\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708]|\uD83C\uDFFB\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])|(?:(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)\uFE0F|\uD83D\uDC6F|\uD83E[\uDD3C\uDDDE\uDDDF])\u200D[\u2640\u2642]|(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)(?:\uD83C[\uDFFB-\uDFFF])\u200D[\u2640\u2642]|(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD6-\uDDDD])(?:(?:\uD83C[\uDFFB-\uDFFF])\u200D[\u2640\u2642]|\u200D[\u2640\u2642])|\uD83C\uDFF4\u200D\u2620)\uFE0F|\uD83D\uDC69\u200D\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67])|\uD83C\uDFF3\uFE0F\u200D\uD83C\uDF08|\uD83D\uDC15\u200D\uD83E\uDDBA|\uD83D\uDC69\u200D\uD83D\uDC66|\uD83D\uDC69\u200D\uD83D\uDC67|\uD83C\uDDFD\uD83C\uDDF0|\uD83C\uDDF4\uD83C\uDDF2|\uD83C\uDDF6\uD83C\uDDE6|[#\*0-9]\uFE0F\u20E3|\uD83C\uDDE7(?:\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEF\uDDF1-\uDDF4\uDDF6-\uDDF9\uDDFB\uDDFC\uDDFE\uDDFF])|\uD83C\uDDF9(?:\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDED\uDDEF-\uDDF4\uDDF7\uDDF9\uDDFB\uDDFC\uDDFF])|\uD83C\uDDEA(?:\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDED\uDDF7-\uDDFA])|\uD83E\uDDD1(?:\uD83C[\uDFFB-\uDFFF])|\uD83C\uDDF7(?:\uD83C[\uDDEA\uDDF4\uDDF8\uDDFA\uDDFC])|\uD83D\uDC69(?:\uD83C[\uDFFB-\uDFFF])|\uD83C\uDDF2(?:\uD83C[\uDDE6\uDDE8-\uDDED\uDDF0-\uDDFF])|\uD83C\uDDE6(?:\uD83C[\uDDE8-\uDDEC\uDDEE\uDDF1\uDDF2\uDDF4\uDDF6-\uDDFA\uDDFC\uDDFD\uDDFF])|\uD83C\uDDF0(?:\uD83C[\uDDEA\uDDEC-\uDDEE\uDDF2\uDDF3\uDDF5\uDDF7\uDDFC\uDDFE\uDDFF])|\uD83C\uDDED(?:\uD83C[\uDDF0\uDDF2\uDDF3\uDDF7\uDDF9\uDDFA])|\uD83C\uDDE9(?:\uD83C[\uDDEA\uDDEC\uDDEF\uDDF0\uDDF2\uDDF4\uDDFF])|\uD83C\uDDFE(?:\uD83C[\uDDEA\uDDF9])|\uD83C\uDDEC(?:\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEE\uDDF1-\uDDF3\uDDF5-\uDDFA\uDDFC\uDDFE])|\uD83C\uDDF8(?:\uD83C[\uDDE6-\uDDEA\uDDEC-\uDDF4\uDDF7-\uDDF9\uDDFB\uDDFD-\uDDFF])|\uD83C\uDDEB(?:\uD83C[\uDDEE-\uDDF0\uDDF2\uDDF4\uDDF7])|\uD83C\uDDF5(?:\uD83C[\uDDE6\uDDEA-\uDDED\uDDF0-\uDDF3\uDDF7-\uDDF9\uDDFC\uDDFE])|\uD83C\uDDFB(?:\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDEE\uDDF3\uDDFA])|\uD83C\uDDF3(?:\uD83C[\uDDE6\uDDE8\uDDEA-\uDDEC\uDDEE\uDDF1\uDDF4\uDDF5\uDDF7\uDDFA\uDDFF])|\uD83C\uDDE8(?:\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDEE\uDDF0-\uDDF5\uDDF7\uDDFA-\uDDFF])|\uD83C\uDDF1(?:\uD83C[\uDDE6-\uDDE8\uDDEE\uDDF0\uDDF7-\uDDFB\uDDFE])|\uD83C\uDDFF(?:\uD83C[\uDDE6\uDDF2\uDDFC])|\uD83C\uDDFC(?:\uD83C[\uDDEB\uDDF8])|\uD83C\uDDFA(?:\uD83C[\uDDE6\uDDEC\uDDF2\uDDF3\uDDF8\uDDFE\uDDFF])|\uD83C\uDDEE(?:\uD83C[\uDDE8-\uDDEA\uDDF1-\uDDF4\uDDF6-\uDDF9])|\uD83C\uDDEF(?:\uD83C[\uDDEA\uDDF2\uDDF4\uDDF5])|(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD6-\uDDDD])(?:\uD83C[\uDFFB-\uDFFF])|(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)(?:\uD83C[\uDFFB-\uDFFF])|(?:[\u261D\u270A-\u270D]|\uD83C[\uDF85\uDFC2\uDFC7]|\uD83D[\uDC42\uDC43\uDC46-\uDC50\uDC66\uDC67\uDC6B-\uDC6D\uDC70\uDC72\uDC74-\uDC76\uDC78\uDC7C\uDC83\uDC85\uDCAA\uDD74\uDD7A\uDD90\uDD95\uDD96\uDE4C\uDE4F\uDEC0\uDECC]|\uD83E[\uDD0F\uDD18-\uDD1C\uDD1E\uDD1F\uDD30-\uDD36\uDDB5\uDDB6\uDDBB\uDDD2-\uDDD5])(?:\uD83C[\uDFFB-\uDFFF])|(?:[\u231A\u231B\u23E9-\u23EC\u23F0\u23F3\u25FD\u25FE\u2614\u2615\u2648-\u2653\u267F\u2693\u26A1\u26AA\u26AB\u26BD\u26BE\u26C4\u26C5\u26CE\u26D4\u26EA\u26F2\u26F3\u26F5\u26FA\u26FD\u2705\u270A\u270B\u2728\u274C\u274E\u2753-\u2755\u2757\u2795-\u2797\u27B0\u27BF\u2B1B\u2B1C\u2B50\u2B55]|\uD83C[\uDC04\uDCCF\uDD8E\uDD91-\uDD9A\uDDE6-\uDDFF\uDE01\uDE1A\uDE2F\uDE32-\uDE36\uDE38-\uDE3A\uDE50\uDE51\uDF00-\uDF20\uDF2D-\uDF35\uDF37-\uDF7C\uDF7E-\uDF93\uDFA0-\uDFCA\uDFCF-\uDFD3\uDFE0-\uDFF0\uDFF4\uDFF8-\uDFFF]|\uD83D[\uDC00-\uDC3E\uDC40\uDC42-\uDCFC\uDCFF-\uDD3D\uDD4B-\uDD4E\uDD50-\uDD67\uDD7A\uDD95\uDD96\uDDA4\uDDFB-\uDE4F\uDE80-\uDEC5\uDECC\uDED0-\uDED2\uDED5\uDEEB\uDEEC\uDEF4-\uDEFA\uDFE0-\uDFEB]|\uD83E[\uDD0D-\uDD3A\uDD3C-\uDD45\uDD47-\uDD71\uDD73-\uDD76\uDD7A-\uDDA2\uDDA5-\uDDAA\uDDAE-\uDDCA\uDDCD-\uDDFF\uDE70-\uDE73\uDE78-\uDE7A\uDE80-\uDE82\uDE90-\uDE95])|(?:[#\*0-9\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u231A\u231B\u2328\u23CF\u23E9-\u23F3\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB-\u25FE\u2600-\u2604\u260E\u2611\u2614\u2615\u2618\u261D\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u2648-\u2653\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u267F\u2692-\u2697\u2699\u269B\u269C\u26A0\u26A1\u26AA\u26AB\u26B0\u26B1\u26BD\u26BE\u26C4\u26C5\u26C8\u26CE\u26CF\u26D1\u26D3\u26D4\u26E9\u26EA\u26F0-\u26F5\u26F7-\u26FA\u26FD\u2702\u2705\u2708-\u270D\u270F\u2712\u2714\u2716\u271D\u2721\u2728\u2733\u2734\u2744\u2747\u274C\u274E\u2753-\u2755\u2757\u2763\u2764\u2795-\u2797\u27A1\u27B0\u27BF\u2934\u2935\u2B05-\u2B07\u2B1B\u2B1C\u2B50\u2B55\u3030\u303D\u3297\u3299]|\uD83C[\uDC04\uDCCF\uDD70\uDD71\uDD7E\uDD7F\uDD8E\uDD91-\uDD9A\uDDE6-\uDDFF\uDE01\uDE02\uDE1A\uDE2F\uDE32-\uDE3A\uDE50\uDE51\uDF00-\uDF21\uDF24-\uDF93\uDF96\uDF97\uDF99-\uDF9B\uDF9E-\uDFF0\uDFF3-\uDFF5\uDFF7-\uDFFF]|\uD83D[\uDC00-\uDCFD\uDCFF-\uDD3D\uDD49-\uDD4E\uDD50-\uDD67\uDD6F\uDD70\uDD73-\uDD7A\uDD87\uDD8A-\uDD8D\uDD90\uDD95\uDD96\uDDA4\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA-\uDE4F\uDE80-\uDEC5\uDECB-\uDED2\uDED5\uDEE0-\uDEE5\uDEE9\uDEEB\uDEEC\uDEF0\uDEF3-\uDEFA\uDFE0-\uDFEB]|\uD83E[\uDD0D-\uDD3A\uDD3C-\uDD45\uDD47-\uDD71\uDD73-\uDD76\uDD7A-\uDDA2\uDDA5-\uDDAA\uDDAE-\uDDCA\uDDCD-\uDDFF\uDE70-\uDE73\uDE78-\uDE7A\uDE80-\uDE82\uDE90-\uDE95])\uFE0F|(?:[\u261D\u26F9\u270A-\u270D]|\uD83C[\uDF85\uDFC2-\uDFC4\uDFC7\uDFCA-\uDFCC]|\uD83D[\uDC42\uDC43\uDC46-\uDC50\uDC66-\uDC78\uDC7C\uDC81-\uDC83\uDC85-\uDC87\uDC8F\uDC91\uDCAA\uDD74\uDD75\uDD7A\uDD90\uDD95\uDD96\uDE45-\uDE47\uDE4B-\uDE4F\uDEA3\uDEB4-\uDEB6\uDEC0\uDECC]|\uD83E[\uDD0F\uDD18-\uDD1F\uDD26\uDD30-\uDD39\uDD3C-\uDD3E\uDDB5\uDDB6\uDDB8\uDDB9\uDDBB\uDDCD-\uDDCF\uDDD1-\uDDDD])/g}});var eD=k((IC,qD)=>{var FF=aD(),CF=rD(),EF=oD(),tD=(u)=>{if(typeof u!=="string"||u.length===0)return 0;if(u=FF(u),u.length===0)return 0;u=u.replace(EF()," ");let D=0;for(let F=0;F=127&&C<=159)continue;if(C>=768&&C<=879)continue;if(C>65535)F++;D+=CF(C)?2:1}return D};qD.exports=tD;qD.exports.default=tD});var ZD=k((HC,Du)=>{Du.exports=function(D,F,C){if(F.autopadding!==!0)return D;function E(A,B){return(F.autopaddingChar+A).slice(-B)}switch(C){case"percentage":return E(D,3);default:return D}}});var QD=k((WC,uu)=>{uu.exports=function(D,F){let C=Math.round(D*F.barsize),E=F.barsize-C;return F.barCompleteString.substr(0,C)+F.barGlue+F.barIncompleteString.substr(0,E)}});var XD=k((VC,Fu)=>{Fu.exports=function(D,F,C){function E(B){if(C)return C*Math.round(B/C);else return B}function A(B){return(F.autopaddingChar+B).slice(-2)}if(D>3600)return A(Math.floor(D/3600))+"h"+A(E(D%3600/60))+"m";else if(D>60)return A(Math.floor(D/60))+"m"+A(E(D%60))+"s";else if(D>10)return A(E(D))+"s";else return A(D)+"s"}});var YD=k((zC,Cu)=>{var BF=eD(),AF=ZD(),qF=QD(),ZF=XD();Cu.exports=function(D,F,C){let E=D.format,A=D.formatTime||ZF,B=D.formatValue||AF,q=D.formatBar||qF,Y=Math.floor(F.progress*100)+"",K=F.stopTime||Date.now(),Q=Math.round((K-F.startTime)/1000),L=Object.assign({},C,{bar:q(F.progress,D),percentage:B(Y,D,"percentage"),total:B(F.total,D,"total"),value:B(F.value,D,"value"),eta:B(F.eta,D,"eta"),eta_formatted:A(F.eta,D,5),duration:B(Q,D,"duration"),duration_formatted:A(Q,D,1)});E=E.replace(/\{(\w+)\}/g,function(X,J){if(typeof L[J]<"u")return L[J];return X});let G=Math.max(0,F.maxWidth-BF(E)-2),Z=Math.floor(G/2);switch(D.align){case"right":E=G>0?" ".repeat(G)+E:E;break;case"center":E=Z>0?" ".repeat(Z)+E:E;break;case"left":default:break}return E}});var s=k((xC,Eu)=>{function $(u,D){if(typeof u>"u"||u===null)return D;else return u}Eu.exports={parse:function(D,F){let C={},E=Object.assign({},F,D);return C.throttleTime=1000/$(E.fps,10),C.stream=$(E.stream,process.stderr),C.terminal=$(E.terminal,null),C.clearOnComplete=$(E.clearOnComplete,!1),C.stopOnComplete=$(E.stopOnComplete,!1),C.barsize=$(E.barsize,40),C.align=$(E.align,"left"),C.hideCursor=$(E.hideCursor,!1),C.linewrap=$(E.linewrap,!1),C.barGlue=$(E.barGlue,""),C.barCompleteChar=$(E.barCompleteChar,"="),C.barIncompleteChar=$(E.barIncompleteChar,"-"),C.format=$(E.format,"progress [{bar}] {percentage}% | ETA: {eta}s | {value}/{total}"),C.formatTime=$(E.formatTime,null),C.formatValue=$(E.formatValue,null),C.formatBar=$(E.formatBar,null),C.etaBufferLength=$(E.etaBuffer,10),C.etaAsynchronousUpdate=$(E.etaAsynchronousUpdate,!1),C.progressCalculationRelative=$(E.progressCalculationRelative,!1),C.synchronousUpdate=$(E.synchronousUpdate,!0),C.noTTYOutput=$(E.noTTYOutput,!1),C.notTTYSchedule=$(E.notTTYSchedule,2000),C.emptyOnZero=$(E.emptyOnZero,!1),C.forceRedraw=$(E.forceRedraw,!1),C.autopadding=$(E.autopadding,!1),C.gracefulExit=$(E.gracefulExit,!1),C},assignDerivedOptions:function(D){return D.barCompleteString=D.barCompleteChar.repeat(D.barsize+1),D.barIncompleteString=D.barIncompleteChar.repeat(D.barsize+1),D.autopaddingChar=D.autopadding?$(D.autopaddingChar," "):"",D}}});var JD=k((MC,Au)=>{var Bu=mD(),QF=BD(),XF=YD(),YF=s(),JF=l("events");Au.exports=class extends JF{constructor(D){super();this.options=YF.assignDerivedOptions(D),this.terminal=this.options.terminal?this.options.terminal:new QF(this.options.stream),this.value=0,this.startValue=0,this.total=100,this.lastDrawnString=null,this.startTime=null,this.stopTime=null,this.lastRedraw=Date.now(),this.eta=new Bu(this.options.etaBufferLength,0,0),this.payload={},this.isActive=!1,this.formatter=typeof this.options.format==="function"?this.options.format:XF}render(D=!1){let F={progress:this.getProgress(),eta:this.eta.getTime(),startTime:this.startTime,stopTime:this.stopTime,total:this.total,value:this.value,maxWidth:this.terminal.getWidth()};if(this.options.etaAsynchronousUpdate)this.updateETA();let C=this.formatter(this.options,F,this.payload);if(D||this.options.forceRedraw||this.options.noTTYOutput&&!this.terminal.isTTY()||this.lastDrawnString!=C)this.emit("redraw-pre"),this.terminal.cursorTo(0,null),this.terminal.write(C),this.terminal.clearRight(),this.lastDrawnString=C,this.lastRedraw=Date.now(),this.emit("redraw-post")}start(D,F,C){this.value=F||0,this.total=typeof D<"u"&&D>=0?D:100,this.startValue=F||0,this.payload=C||{},this.startTime=Date.now(),this.stopTime=null,this.lastDrawnString="",this.eta=new Bu(this.options.etaBufferLength,this.startTime,this.value),this.isActive=!0,this.emit("start",D,F)}stop(){this.isActive=!1,this.stopTime=Date.now(),this.emit("stop",this.total,this.value)}update(D,F={}){if(typeof D==="number")this.value=D,this.eta.update(Date.now(),D,this.total);let C=(typeof D==="object"?D:F)||{};this.emit("update",this.total,this.value);for(let E in C)this.payload[E]=C[E];if(this.value>=this.getTotal()&&this.options.stopOnComplete)this.stop()}getProgress(){let D=this.value/this.total;if(this.options.progressCalculationRelative)D=(this.value-this.startValue)/(this.total-this.startValue);if(isNaN(D))D=this.options&&this.options.emptyOnZero?0:1;return D=Math.min(Math.max(D,0),1),D}increment(D=1,F={}){if(typeof D==="object")this.update(this.value+1,D);else this.update(this.value+D,F)}getTotal(){return this.total}setTotal(D){if(typeof D<"u"&&D>=0)this.total=D}updateETA(){this.eta.update(Date.now(),this.value,this.total)}}});var Zu=k((NC,qu)=>{var KF=JD(),LF=s();qu.exports=class extends KF{constructor(D,F){super(LF.parse(D,F));if(this.timer=null,this.options.noTTYOutput&&this.terminal.isTTY()===!1)this.options.synchronousUpdate=!1;this.schedulingRate=this.terminal.isTTY()?this.options.throttleTime:this.options.notTTYSchedule,this.sigintCallback=null}render(){if(this.timer)clearTimeout(this.timer),this.timer=null;if(super.render(),this.options.noTTYOutput&&this.terminal.isTTY()===!1)this.terminal.newline();this.timer=setTimeout(this.render.bind(this),this.schedulingRate)}update(D,F){if(!this.timer)return;if(super.update(D,F),this.options.synchronousUpdate&&this.lastRedraw+this.options.throttleTime*2{var GF=BD(),$F=JD(),RF=s(),UF=l("events");Qu.exports=class extends UF{constructor(D,F){super();this.bars=[],this.options=RF.parse(D,F),this.options.synchronousUpdate=!1,this.terminal=this.options.terminal?this.options.terminal:new GF(this.options.stream),this.timer=null,this.isActive=!1,this.schedulingRate=this.terminal.isTTY()?this.options.throttleTime:this.options.notTTYSchedule,this.loggingBuffer=[],this.sigintCallback=null}create(D,F,C,E={}){let A=new $F(Object.assign({},this.options,{terminal:this.terminal},E));if(this.bars.push(A),this.options.noTTYOutput===!1&&this.terminal.isTTY()===!1)return A;if(this.sigintCallback===null&&this.options.gracefulExit)this.sigintCallback=this.stop.bind(this),process.once("SIGINT",this.sigintCallback),process.once("SIGTERM",this.sigintCallback);if(!this.isActive){if(this.options.hideCursor===!0)this.terminal.cursor(!1);if(this.options.linewrap===!1)this.terminal.lineWrapping(!1);this.timer=setTimeout(this.update.bind(this),this.schedulingRate)}return this.isActive=!0,A.start(D,F,C),this.emit("start"),A}remove(D){let F=this.bars.indexOf(D);if(F<0)return!1;return this.bars.splice(F,1),this.update(),this.terminal.newline(),this.terminal.clearBottom(),!0}update(){if(this.timer)clearTimeout(this.timer),this.timer=null;if(this.emit("update-pre"),this.terminal.cursorRelativeReset(),this.emit("redraw-pre"),this.loggingBuffer.length>0){this.terminal.clearLine();while(this.loggingBuffer.length>0)this.terminal.write(this.loggingBuffer.shift(),!0)}for(let D=0;D0)this.terminal.newline();this.bars[D].render()}if(this.emit("redraw-post"),this.options.noTTYOutput&&this.terminal.isTTY()===!1)this.terminal.newline(),this.terminal.newline();if(this.timer=setTimeout(this.update.bind(this),this.schedulingRate),this.emit("update-post"),this.options.stopOnComplete&&!this.bars.find((D)=>D.isActive))this.stop()}stop(){if(clearTimeout(this.timer),this.timer=null,this.sigintCallback)process.removeListener("SIGINT",this.sigintCallback),process.removeListener("SIGTERM",this.sigintCallback),this.sigintCallback=null;if(this.isActive=!1,this.options.hideCursor===!0)this.terminal.cursor(!0);if(this.options.linewrap===!1)this.terminal.lineWrapping(!0);if(this.terminal.cursorRelativeReset(),this.emit("stop-pre-clear"),this.options.clearOnComplete)this.terminal.clearBottom();else{for(let D=0;D0)this.terminal.newline();this.bars[D].render(),this.bars[D].stop()}this.terminal.newline()}this.emit("stop")}log(D){this.loggingBuffer.push(D)}}});var Ju=k((wC,Yu)=>{Yu.exports={format:"progress [{bar}] {percentage}% | ETA: {eta}s | {value}/{total}",barCompleteChar:"=",barIncompleteChar:"-"}});var Lu=k((OC,Ku)=>{Ku.exports={format:" {bar} {percentage}% | ETA: {eta}s | {value}/{total}",barCompleteChar:"█",barIncompleteChar:"░"}});var $u=k((yC,Gu)=>{Gu.exports={format:" \x1B[90m{bar}\x1B[0m {percentage}% | ETA: {eta}s | {value}/{total}",barCompleteChar:"█",barIncompleteChar:"░"}});var Uu=k((SC,Ru)=>{Ru.exports={format:" {bar}■ {percentage}% | ETA: {eta}s | {value}/{total}",barCompleteChar:"■",barIncompleteChar:" "}});var _u=k((TC,ku)=>{var kF=Ju(),_F=Lu(),IF=$u(),HF=Uu();ku.exports={legacy:kF,shades_classic:_F,shades_grey:IF,rect:HF}});var Wu=k((bC,Hu)=>{var Iu=Zu(),WF=Xu(),VF=_u(),zF=YD(),xF=ZD(),MF=QD(),NF=XD();Hu.exports={Bar:Iu,SingleBar:Iu,MultiBar:WF,Presets:VF,Format:{Formatter:zF,BarFormat:MF,ValueFormat:xF,TimeFormat:NF}}});import{join as hD,basename as ou,extname as tu}from"node:path";import{randomUUID as eu}from"node:crypto";import{rm as PD}from"node:fs/promises";import{spawn as S}from"node:child_process";async function T(){return new Promise((u)=>{let D=S("ffmpeg",["-version"]);D.on("error",()=>u(!1)),D.on("close",(F)=>u(F===0))})}async function b(){return new Promise((u)=>{let D=S("MP4Box",["-version"]);D.on("error",()=>u(!1)),D.on("close",(F)=>u(F===0))})}async function v(){return new Promise((u)=>{let D=S("ffmpeg",["-hide_banner","-encoders"]),F="";D.stdout.on("data",(C)=>{F+=C.toString()}),D.on("error",()=>u(!1)),D.on("close",(C)=>{if(C!==0)u(!1);else u(F.includes("h264_nvenc")||F.includes("hevc_nvenc"))})})}async function h(){return new Promise((u)=>{let D=S("ffmpeg",["-hide_banner","-encoders"]),F="";D.stdout.on("data",(C)=>{F+=C.toString()}),D.on("error",()=>u({available:!1})),D.on("close",(C)=>{if(C!==0)u({available:!1});else if(F.includes("av1_nvenc"))u({available:!0,encoder:"av1_nvenc"});else if(F.includes("av1_qsv"))u({available:!0,encoder:"av1_qsv"});else if(F.includes("av1_amf"))u({available:!0,encoder:"av1_amf"});else u({available:!1})})})}async function w(u,D,F){return new Promise((C,E)=>{let A=S("ffmpeg",u),B="";A.stderr.on("data",(q)=>{let Y=q.toString();if(B+=Y,D&&F){let K=Y.match(/time=(\d{2}):(\d{2}):(\d{2}\.\d{2})/);if(K){let Q=parseInt(K[1]),L=parseInt(K[2]),G=parseFloat(K[3]),Z=Q*3600+L*60+G,X=Math.min(100,Z/F*100);D(X)}}}),A.on("error",(q)=>{E(Error(`FFmpeg error: ${q.message}`))}),A.on("close",(q)=>{if(q===0)C();else E(Error(`FFmpeg failed with exit code ${q} +${B}`))})})}async function uD(u){return new Promise((D,F)=>{let C=S("MP4Box",u),E="",A="";C.stdout.on("data",(B)=>{E+=B.toString()}),C.stderr.on("data",(B)=>{A+=B.toString()}),C.on("error",(B)=>{F(Error(`MP4Box error: ${B.message}`))}),C.on("close",(B)=>{if(B===0)D();else F(Error(`MP4Box failed with exit code ${B} +${A||E}`))})})}import{spawn as fu}from"node:child_process";async function P(u){return new Promise((D,F)=>{let C=fu("ffprobe",["-v","error","-show_entries","stream=width,height,duration,r_frame_rate,codec_name,codec_type,bit_rate","-show_entries","format=duration","-of","json",u]),E="";C.stdout.on("data",(A)=>{E+=A.toString()}),C.on("error",(A)=>{F(Error(`ffprobe error: ${A.message}`))}),C.on("close",(A)=>{if(A!==0){F(Error(`ffprobe failed with exit code ${A}`));return}try{let B=JSON.parse(E),q=B.streams.find((X)=>X.codec_type==="video"),Y=B.streams.find((X)=>X.codec_type==="audio"&&X.bit_rate),K=B.format;if(!q){F(Error("No video stream found in input file"));return}let Q=30;if(q.r_frame_rate){let[X,J]=q.r_frame_rate.split("/").map(Number);if(X&&J&&J!==0)Q=X/J}let L=parseFloat(q.duration||K.duration||"0"),G=Y?.bit_rate?Math.round(parseInt(Y.bit_rate)/1000):void 0,Z=q.bit_rate?Math.round(parseInt(q.bit_rate)/1000):void 0;D({width:q.width,height:q.height,duration:L,fps:Q,codec:q.codec_name,audioBitrate:G,videoBitrate:Z})}catch(B){F(Error(`Failed to parse ffprobe output: ${B}`))}})})}function n(u,D=256){if(!u)return`${D}k`;let F=Math.min(u,D);if(F<=64)return"64k";if(F<=96)return"96k";if(F<=128)return"128k";if(F<=192)return"192k";return"256k"}function p(u){let D=Math.floor(u/3600),F=Math.floor(u%3600/60),C=u%60;return`${String(D).padStart(2,"0")}:${String(F).padStart(2,"0")}:${C.toFixed(3).padStart(6,"0")}`}import{mkdir as gu,access as mu,constants as cu}from"node:fs/promises";async function f(u){try{await mu(u,cu.F_OK)}catch{await gu(u,{recursive:!0})}}function lu(u,D){let F=u*D;if(F<=230400)return 0.08;if(F<=409920)return 0.075;if(F<=921600)return 0.07;if(F<=2073600)return 0.065;if(F<=3686400)return 0.06;return 0.055}function M(u,D,F=30,C){let E=lu(u,D),A=Math.round(u*D*F*E/1000);if(C&&A>C)A=C;return`${A}k`}var FD=[{name:"360p",width:640,height:360,videoBitrate:M(640,360,30),audioBitrate:"192k"},{name:"480p",width:854,height:480,videoBitrate:M(854,480,30),audioBitrate:"192k"},{name:"720p",width:1280,height:720,videoBitrate:M(1280,720,30),audioBitrate:"192k"},{name:"1080p",width:1920,height:1080,videoBitrate:M(1920,1080,30),audioBitrate:"256k"},{name:"1440p",width:2560,height:1440,videoBitrate:M(2560,1440,30),audioBitrate:"256k"},{name:"2160p",width:3840,height:2160,videoBitrate:M(3840,2160,30),audioBitrate:"256k"}];function CD(u,D,F=30,C){let E=[],A=FD.filter((B)=>{return B.width<=u&&B.height<=D});for(let B of A)E.push({...B,videoBitrate:M(B.width,B.height,30,C)});if(F>=45)for(let B of A)E.push(a(B,60,C));if(F>=75)for(let B of A)E.push(a(B,90,C));if(F>=95)for(let B of A)E.push(a(B,120,C));return E}function a(u,D,F){return{...u,name:`${u.name}-${D}`,videoBitrate:M(u.width,u.height,D,F)}}function MD(u){let F=u.trim().match(/^(\d+)p?(?:[@-](\d+))?$/i);if(!F)return null;let C=F[1]+"p",E=F[2]?parseInt(F[2]):30;return{resolution:C,fps:E}}function ND(u,D=30,F){let C=FD.find((E)=>E.name===u);if(!C)return null;if(D===30)return{...C,videoBitrate:M(C.width,C.height,30,F)};return a(C,D,F)}function du(u,D,F,C){let E=MD(u);if(!E)return`Invalid profile format: ${u}. Use format like: 360, 720@60, 1080-60`;let A=ND(E.resolution,E.fps);if(!A)return`Unknown resolution: ${E.resolution}. Available: 360, 480, 720, 1080, 1440, 2160`;if(A.width>D||A.height>F)return`Source resolution (${D}x${F}) is lower than ${u} (${A.width}x${A.height})`;if(E.fps>C)return`Source FPS (${C}) is lower than requested ${E.fps} FPS in ${u}`;return null}function jD(u,D,F,C,E){let A=[],B=[];for(let q of u){let Y=du(q,D,F,C);if(Y){B.push(Y);continue}let K=MD(q);if(!K)continue;let Q=ND(K.resolution,K.fps,E);if(Q)A.push(Q)}return{profiles:A,errors:B}}import{join as j}from"node:path";import{readdir as nu,unlink as wD,rmdir as pu,writeFile as OD}from"node:fs/promises";async function yD(u,D,F="00:00:01"){let C=j(D,"poster.jpg"),E=/^\d+(\.\d+)?$/.test(F)?F:F;return await w(["-ss",E,"-i",u,"-vframes","1","-q:v","2","-y",C]),C}async function SD(u,D,F,C){let{width:E,height:A,interval:B,columns:q}=C,Y=j(D,".thumbnails_temp");await f(Y),await OD(j(Y,".keep"),"");let K=j(Y,"thumb_%04d.jpg");await w(["-i",u,"-vf",`fps=1/${B},scale=${E}:${A}`,"-q:v","5",K]);let L=(await nu(Y)).filter((U)=>U.startsWith("thumb_")&&U.endsWith(".jpg")).sort();if(L.length===0)throw Error("No thumbnails generated");let G=L.length,Z=Math.ceil(G/q),X=j(D,"thumbnails.jpg"),J=`tile=${q}x${Z}`;await w(["-i",K,"-filter_complex",J,"-q:v","5",X]);let W=j(D,"thumbnails.vtt"),I=au(G,B,E,A,q,"thumbnails.jpg");await OD(W,I);for(let U of L)await wD(j(Y,U));return await wD(j(Y,".keep")),await pu(Y),{spritePath:X,vttPath:W}}function au(u,D,F,C,E,A){let B=`WEBVTT -`;for(let q=0;q ${c(J)} -`,B+=`${A}#xywh=${X},${Y},${F},${C} +`;for(let q=0;q ${p(K)} +`,B+=`${A}#xywh=${G},${Z},${F},${C} -`}return B}import{join as Pu}from"node:path";async function yD(u,D,F,C,E,A,B,q,Q,J,L){let G=Pu(D,`video_${F.name}.mp4`),X=["-y","-i",u,"-c:v",C];if(C==="h264_nvenc")X.push("-rc:v","vbr"),X.push("-preset",E),X.push("-2pass","0");else X.push("-preset",E);X.push("-b:v",F.videoBitrate,"-maxrate",F.videoBitrate,"-bufsize",`${parseInt(F.videoBitrate)*2}k`);let Y=Math.round(q*B);X.push("-g",String(Y),"-keyint_min",String(Y),"-sc_threshold","0");let Z=[`scale=${F.width}:${F.height}`];if(J){if(J.deinterlace)Z.push("yadif");if(J.denoise)Z.push("hqdn3d");if(J.customFilters)Z.push(...J.customFilters)}X.push("-vf",Z.join(","));let R=parseInt(F.audioBitrate)||256,U=g(Q,R);if(X.push("-c:a","aac","-b:a",U),J?.audioNormalize)X.push("-af","loudnorm");return X.push("-f","mp4",G),await M(X,L,A),G}async function xD(u,D,F,C,E,A,B,q,Q,J,L,G,X){let Y=new Map;if(J&&F.length>1)for(let Z=0;ZyD(u,D,_,C,E,A,B,q,Q,G,(V)=>{if(X)X(_.name,V)}));(await Promise.all(U)).forEach((_,V)=>{let a=R[V];Y.set(a.name,_)})}else for(let Z of F){let R=await yD(u,D,Z,C,E,A,B,q,Q,G,(U)=>{if(X)X(Z.name,U)});Y.set(Z.name,R)}return Y}import{join as N}from"node:path";async function zD(u,D,F,C){let E=N(D,"manifest.mpd"),A=["-dash",String(C*1000),"-frag",String(C*1000),"-rap","-segment-name","$RepresentationID$_$Number$","-out",E];for(let B of F){let q=u.get(B.name);if(!q)throw Error(`MP4 file not found for profile: ${B.name}`);if(A.push(`${q}#video:id=${B.name}`),B===F[0])A.push(`${q}#audio:id=audio`)}return await r(A),await fu(D,F),await gu(E,F),E}async function fu(u,D){let{readdir:F,rename:C,mkdir:E}=await import("node:fs/promises");for(let q of D){let Q=N(u,q.name);await E(Q,{recursive:!0})}let A=N(u,"audio");await E(A,{recursive:!0});let B=await F(u);for(let q of B){if(q==="manifest.mpd")continue;if(q.startsWith("audio_")||q==="audio_init.m4s"){let Q=N(u,q),J=N(A,q);await C(Q,J);continue}for(let Q of D)if(q.startsWith(`${Q.name}_`)){let J=N(u,q),L=N(u,Q.name,q);await C(J,L);break}}}async function gu(u,D){let{readFile:F,writeFile:C}=await import("node:fs/promises"),E=await F(u,"utf-8");E=E.replace(/media="\$RepresentationID\$_\$Number\$\.m4s"/g,'media="$RepresentationID$/$RepresentationID$_$Number$.m4s"'),E=E.replace(/initialization="\$RepresentationID\$_\.mp4"/g,'initialization="$RepresentationID$/$RepresentationID$_.mp4"'),await C(u,E,"utf-8")}async function t(u){let{input:D,outputDir:F,segmentDuration:C=2,profiles:E,customProfiles:A,useNvenc:B,generateThumbnails:q=!0,thumbnailConfig:Q={},generatePoster:J=!0,posterTimecode:L="00:00:01",parallel:G=!0,onProgress:X}=u,Y=MD("/tmp",`dash-converter-${du()}`);await b(Y);try{return await lu(D,F,Y,C,E,A,B,q,Q,J,L,G,X)}finally{try{await ND(Y,{recursive:!0,force:!0})}catch(Z){console.warn(`Warning: Failed to cleanup temp directory: ${Y}`)}}}async function lu(u,D,F,C,E,A,B,q,Q,J,L,G,X){if(!await j())throw Error("FFmpeg is not installed or not in PATH");if(!await O())throw Error("MP4Box is not installed or not in PATH. Install gpac package.");let Y=(k,y,GD,f)=>{if(X)X({stage:k,percent:y,message:GD,currentProfile:f})};Y("analyzing",0,"Analyzing input video...");let Z=await S(u),R=B!==!1?await T():!1,U=B===!0?!0:B===!1?!1:R;if(B===!0&&!R)throw Error("NVENC requested but not available. Check NVIDIA drivers and GPU support.");let $;if(A&&A.length>0){let k=kD(A,Z.width,Z.height,Z.fps,Z.videoBitrate);if(k.errors.length>0){console.warn(` -⚠️ Profile warnings:`);for(let y of k.errors)console.warn(` - ${y}`);console.warn("")}if($=k.profiles,$.length===0)throw Error("No valid profiles found in custom list. Check warnings above.")}else if(E)$=E;else $=o(Z.width,Z.height,Z.fps,Z.videoBitrate);if($.length===0)throw Error("No suitable profiles found for input video resolution");let _=cu(u,mu(u)),V=MD(D,_);try{await ND(V,{recursive:!0,force:!0})}catch(k){}await b(V),Y("analyzing",20,`Using ${U?"NVENC":"CPU"} encoding`,void 0);let a=U?"h264_nvenc":"libx264",Uu=U?"p4":"medium",ku=U?3:2;Y("encoding",25,`Stage 1: Encoding ${$.length} profiles to MP4...`);let YD=await xD(u,F,$,a,Uu,Z.duration,C,Z.fps||25,Z.audioBitrate,G,ku,void 0,(k,y)=>{let f=25+$.findIndex((Wu)=>Wu.name===k)/$.length*40,ID=y/100*(40/$.length);if(Y("encoding",f+ID,`Encoding ${k}...`,k),X)X({stage:"encoding",percent:f+ID,currentProfile:k,profilePercent:y,message:`Encoding ${k}...`})});Y("encoding",65,"Stage 1 complete: All profiles encoded"),Y("encoding",70,"Stage 2: Creating DASH with MP4Box...");let _u=await zD(YD,V,$,C),Hu=Array.from(YD.values());Y("encoding",80,"Stage 2 complete: DASH created");let JD,KD;if(q){Y("thumbnails",80,"Generating thumbnail sprites...");let k={width:Q.width||160,height:Q.height||90,interval:Q.interval||1,columns:Q.columns||10},y=await VD(u,V,Z.duration,k);JD=y.spritePath,KD=y.vttPath,Y("thumbnails",90,"Thumbnails generated")}let LD;if(J)Y("thumbnails",92,"Generating poster image..."),LD=await WD(u,V,L),Y("thumbnails",95,"Poster generated");return Y("manifest",95,"Finalizing manifest..."),Y("complete",100,"Conversion complete!"),{manifestPath:_u,videoPaths:Hu,thumbnailSpritePath:JD,thumbnailVttPath:KD,posterPath:LD,duration:Z.duration,profiles:$,usedNvenc:U}}var QD=s(Lu(),1);import{statSync as UF}from"node:fs";var H=process.argv.slice(2),n,p,XD=[];for(let u=0;uC.trim()).filter((C)=>C.length>0)}else if(H[u]==="-p"||H[u]==="--poster")p=H[u+1],u++;else if(!H[u].startsWith("-"))XD.push(H[u]);var P=XD[0],Gu=XD[1]||".";if(!P)console.error("❌ Usage: dvc-cli [output-dir] [-r resolutions] [-p poster-timecode]"),console.error(` -Examples:`),console.error(" dvc-cli video.mp4"),console.error(" dvc-cli video.mp4 ./output"),console.error(" dvc-cli video.mp4 -r 360,480,720"),console.error(" dvc-cli video.mp4 -r 720@60,1080@60,2160@60"),console.error(" dvc-cli video.mp4 -p 00:00:05"),console.error(" dvc-cli video.mp4 ./output -r 720,1080 -p 10"),process.exit(1);console.log(`\uD83D\uDD0D Checking system... -`);var Iu=await j(),Ru=await T(),$u=await O();console.log(`FFmpeg: ${Iu?"✅":"❌"}`);console.log(`NVENC: ${Ru?"✅ (GPU acceleration)":"⚠️ (CPU only)"}`);console.log(`MP4Box: ${$u?"✅":"❌"} -`);if(!Iu)console.error("❌ FFmpeg not found. Please install FFmpeg first."),process.exit(1);if(!$u)console.error("❌ MP4Box not found. Please install: sudo pacman -S gpac"),process.exit(1);console.log(`\uD83D\uDCCA Analyzing video... -`);var W=await S(P),kF=UF(P),_F=(kF.size/1048576).toFixed(2);console.log("\uD83D\uDCF9 Video Information:");console.log(` File: ${P}`);console.log(` Size: ${_F} MB`);console.log(` Resolution: ${W.width}x${W.height}`);console.log(` FPS: ${W.fps.toFixed(2)}`);console.log(` Duration: ${Math.floor(W.duration/60)}m ${Math.floor(W.duration%60)}s`);console.log(` Codec: ${W.codec}`);if(W.videoBitrate)console.log(` Video Bitrate: ${(W.videoBitrate/1000).toFixed(2)} Mbps`);if(W.audioBitrate)console.log(` Audio Bitrate: ${W.audioBitrate} kbps`);console.log(` -\uD83D\uDCC1 Output: ${Gu}`);if(n)console.log(`\uD83C\uDFAF Custom profiles: ${n.join(", ")}`);if(p)console.log(`\uD83D\uDDBC️ Poster timecode: ${p}`);console.log(` +`}return B}import{join as su}from"node:path";async function TD(u,D,F,C,E,A,B,q,Y,K,Q,L){let G=su(D,`video_${K}_${F.name}.mp4`),Z=["-y","-i",u,"-c:v",C];if(C==="h264_nvenc")Z.push("-rc:v","vbr"),Z.push("-preset",E),Z.push("-2pass","0");else if(C==="av1_nvenc")Z.push("-rc:v","vbr"),Z.push("-preset",E),Z.push("-2pass","0");else if(C==="av1_qsv")Z.push("-preset",E),Z.push("-global_quality","23");else if(C==="av1_amf")Z.push("-quality","balanced"),Z.push("-rc","vbr_latency");else if(C==="libsvtav1")Z.push("-preset",E),Z.push("-svtav1-params","tune=0:enable-overlays=1");else Z.push("-preset",E);let X=K==="av1"?0.6:1,J=Math.round(parseInt(F.videoBitrate)*X),W=`${J}k`;Z.push("-b:v",W,"-maxrate",W,"-bufsize",`${J*2}k`);let I=Math.round(q*B);Z.push("-g",String(I),"-keyint_min",String(I),"-sc_threshold","0");let U=[`scale=${F.width}:${F.height}`];if(Q){if(Q.deinterlace)U.push("yadif");if(Q.denoise)U.push("hqdn3d");if(Q.customFilters)U.push(...Q.customFilters)}Z.push("-vf",U.join(","));let N=parseInt(F.audioBitrate)||256,V=n(Y,N);if(Z.push("-c:a","aac","-b:a",V),Q?.audioNormalize)Z.push("-af","loudnorm");return Z.push("-f","mp4",G),await w(Z,L,A),G}async function bD(u,D,F,C,E,A,B,q,Y,K,Q,L,G,Z){let X=new Map;if(K&&F.length>1)for(let J=0;JTD(u,D,N,C,E,A,B,q,Y,L,G,(V)=>{if(Z)Z(N.name,V)}));(await Promise.all(I)).forEach((N,V)=>{let x=W[V];X.set(x.name,N)})}else for(let J of F){let W=await TD(u,D,J,C,E,A,B,q,Y,L,G,(I)=>{if(Z)Z(J.name,I)});X.set(J.name,W)}return X}import{join as O}from"node:path";async function vD(u,D,F,C,E){let A=O(D,"manifest.mpd"),B=["-dash",String(C*1000),"-frag",String(C*1000),"-rap","-segment-timeline","-segment-name","$RepresentationID$_$Number$","-out",A],q=!0;for(let[Y,K]of u.entries())for(let Q of F){let L=K.get(Q.name);if(!L)throw Error(`MP4 file not found for profile: ${Q.name}, codec: ${Y}`);let G=E==="dual"?`${Q.name}-${Y}`:Q.name;if(B.push(`${L}#video:id=${G}`),q)B.push(`${L}#audio:id=audio`),q=!1}return await uD(B),await ru(D,F,E),await iu(A,F,E),A}async function ru(u,D,F){let{readdir:C,rename:E,mkdir:A}=await import("node:fs/promises"),B=[];if(F==="h264"||F==="dual")B.push("h264");if(F==="av1"||F==="dual")B.push("av1");let q=[];for(let Q of B)for(let L of D){let G=F==="dual"?`${L.name}-${Q}`:L.name;q.push(G);let Z=O(u,G);await A(Z,{recursive:!0})}let Y=O(u,"audio");await A(Y,{recursive:!0});let K=await C(u);for(let Q of K){if(Q==="manifest.mpd")continue;if(Q.startsWith("audio_")||Q==="audio_init.m4s"){let L=O(u,Q),G=O(Y,Q);await E(L,G);continue}for(let L of q)if(Q.startsWith(`${L}_`)){let G=O(u,Q),Z=O(u,L,Q);await E(G,Z);break}}}async function iu(u,D,F){let{readFile:C,writeFile:E}=await import("node:fs/promises"),A=await C(u,"utf-8");A=A.replace(/media="\$RepresentationID\$_\$Number\$\.m4s"/g,'media="$RepresentationID$/$RepresentationID$_$Number$.m4s"'),A=A.replace(/initialization="\$RepresentationID\$_\.mp4"/g,'initialization="$RepresentationID$/$RepresentationID$_.mp4"'),await E(u,A,"utf-8")}async function ED(u){let{input:D,outputDir:F,segmentDuration:C=2,profiles:E,customProfiles:A,codec:B="dual",useNvenc:q,generateThumbnails:Y=!0,thumbnailConfig:K={},generatePoster:Q=!0,posterTimecode:L="00:00:01",parallel:G=!0,onProgress:Z}=u,X=hD("/tmp",`dash-converter-${eu()}`);await f(X);try{return await DF(D,F,X,C,E,A,B,q,Y,K,Q,L,G,Z)}finally{try{await PD(X,{recursive:!0,force:!0})}catch(J){console.warn(`Warning: Failed to cleanup temp directory: ${X}`)}}}async function DF(u,D,F,C,E,A,B,q,Y,K,Q,L,G,Z){if(!await T())throw Error("FFmpeg is not installed or not in PATH");if(!await b())throw Error("MP4Box is not installed or not in PATH. Install gpac package.");let X=(R,_,m,e)=>{if(Z)Z({stage:R,percent:_,message:m,currentProfile:e})};X("analyzing",0,"Analyzing input video...");let J=await P(u),W=q!==!1?await v():!1,I=q===!0?!0:q===!1?!1:W;if(q===!0&&!W)throw Error("NVENC requested but not available. Check NVIDIA drivers and GPU support.");let U;if(A&&A.length>0){let R=jD(A,J.width,J.height,J.fps,J.videoBitrate);if(R.errors.length>0){console.warn(` +⚠️ Profile warnings:`);for(let _ of R.errors)console.warn(` - ${_}`);console.warn("")}if(U=R.profiles,U.length===0)throw Error("No valid profiles found in custom list. Check warnings above.")}else if(E)U=E;else U=CD(J.width,J.height,J.fps,J.videoBitrate);if(U.length===0)throw Error("No suitable profiles found for input video resolution");let N=ou(u,tu(u)),V=hD(D,N);try{await PD(V,{recursive:!0,force:!0})}catch(R){}await f(V);let x=[];if(B==="h264"||B==="dual"){let R=I?"h264_nvenc":"libx264",_=I?"p4":"medium";x.push({type:"h264",codec:R,preset:_})}if(B==="av1"||B==="dual"){let R=await h(),_=R.available?R.encoder:"libsvtav1",m=R.available?_==="av1_nvenc"?"p4":"medium":"8";x.push({type:"av1",codec:_,preset:m})}let Nu=x.map((R)=>R.type.toUpperCase()).join(" + ");X("analyzing",20,`Using ${Nu} encoding (${I?"GPU":"CPU"})`,void 0);let ju=I?3:2,t=new Map;for(let R=0;R{let yF=U.findIndex((Su)=>Su.name===c),VD=25+HD*40,zD=WD/100*(40*Ou/U.length);if(X("encoding",VD+zD,`Encoding ${_.toUpperCase()} ${c}...`,`${_}-${c}`),Z)Z({stage:"encoding",percent:VD+zD,currentProfile:`${_}-${c}`,profilePercent:WD,message:`Encoding ${_.toUpperCase()} ${c}...`})});t.set(_,yu)}X("encoding",65,"Stage 1 complete: All codecs and profiles encoded"),X("encoding",70,"Stage 2: Creating DASH with MP4Box...");let wu=await vD(t,V,U,C,B),UD=[];for(let R of t.values())UD.push(...Array.from(R.values()));X("encoding",80,"Stage 2 complete: DASH created");let kD,_D;if(Y){X("thumbnails",80,"Generating thumbnail sprites...");let R={width:K.width||160,height:K.height||90,interval:K.interval||1,columns:K.columns||10},_=await SD(u,V,J.duration,R);kD=_.spritePath,_D=_.vttPath,X("thumbnails",90,"Thumbnails generated")}let ID;if(Q)X("thumbnails",92,"Generating poster image..."),ID=await yD(u,V,L),X("thumbnails",95,"Poster generated");return X("manifest",95,"Finalizing manifest..."),X("complete",100,"Conversion complete!"),{manifestPath:wu,videoPaths:UD,thumbnailSpritePath:kD,thumbnailVttPath:_D,posterPath:ID,duration:J.duration,profiles:U,usedNvenc:I,codecType:B}}var GD=DD(Wu(),1);import{statSync as jF}from"node:fs";var H=process.argv.slice(2),i,o,g="dual",RD=[];for(let u=0;uC.trim()).filter((C)=>C.length>0)}else if(H[u]==="-p"||H[u]==="--poster")o=H[u+1],u++;else if(H[u]==="-c"||H[u]==="--codec"){let D=H[u+1];if(D==="av1"||D==="h264"||D==="dual")g=D;else console.error(`❌ Invalid codec: ${D}. Valid options: av1, h264, dual`),process.exit(1);u++}else if(!H[u].startsWith("-"))RD.push(H[u]);var d=RD[0],Vu=RD[1]||".";if(!d)console.error("❌ Usage: dvc-cli [output-dir] [-r resolutions] [-c codec] [-p poster-timecode]"),console.error(` +Options:`),console.error(" -r, --resolutions Video resolutions (e.g., 360,480,720 or 720@60,1080@60)"),console.error(" -c, --codec Video codec: av1, h264, or dual (default: dual)"),console.error(" -p, --poster Poster timecode (e.g., 00:00:05 or 10)"),console.error(` +Examples:`),console.error(" dvc-cli video.mp4"),console.error(" dvc-cli video.mp4 ./output"),console.error(" dvc-cli video.mp4 -r 360,480,720"),console.error(" dvc-cli video.mp4 -c av1"),console.error(" dvc-cli video.mp4 -c h264"),console.error(" dvc-cli video.mp4 -c dual"),console.error(" dvc-cli video.mp4 -r 720@60,1080@60,2160@60 -c av1"),console.error(" dvc-cli video.mp4 -p 00:00:05"),console.error(" dvc-cli video.mp4 ./output -r 720,1080 -c dual -p 10"),process.exit(1);console.log(`\uD83D\uDD0D Checking system... +`);var zu=await T(),xu=await v(),$D=await h(),Mu=await b();console.log(`FFmpeg: ${zu?"✅":"❌"}`);console.log(`NVENC (H.264): ${xu?"✅ (GPU acceleration)":"⚠️ (CPU only)"}`);if($D.available)console.log(`AV1 Encoder: ✅ ${$D.encoder} (GPU acceleration)`);else console.log("AV1 Encoder: ⚠️ (not available, will use CPU fallback)");console.log(`MP4Box: ${Mu?"✅":"❌"} +`);if(!zu)console.error("❌ FFmpeg not found. Please install FFmpeg first."),process.exit(1);if(!Mu)console.error("❌ MP4Box not found. Please install: sudo pacman -S gpac"),process.exit(1);if((g==="av1"||g==="dual")&&!$D.available)console.error("⚠️ Warning: AV1 encoding requested but no hardware AV1 encoder found."),console.error(" CPU-based AV1 encoding (libsvtav1) will be VERY slow."),console.error(` Consider using --codec h264 for faster encoding. +`);console.log(`\uD83D\uDCCA Analyzing video... +`);var z=await P(d),wF=jF(d),OF=(wF.size/1048576).toFixed(2);console.log("\uD83D\uDCF9 Video Information:");console.log(` File: ${d}`);console.log(` Size: ${OF} MB`);console.log(` Resolution: ${z.width}x${z.height}`);console.log(` FPS: ${z.fps.toFixed(2)}`);console.log(` Duration: ${Math.floor(z.duration/60)}m ${Math.floor(z.duration%60)}s`);console.log(` Codec: ${z.codec}`);if(z.videoBitrate)console.log(` Video Bitrate: ${(z.videoBitrate/1000).toFixed(2)} Mbps`);if(z.audioBitrate)console.log(` Audio Bitrate: ${z.audioBitrate} kbps`);console.log(` +\uD83D\uDCC1 Output: ${Vu}`);console.log(`\uD83C\uDFAC Codec: ${g}${g==="dual"?" (AV1 + H.264 for maximum compatibility)":""}`);if(i)console.log(`\uD83C\uDFAF Custom profiles: ${i.join(", ")}`);if(o)console.log(`\uD83D\uDDBC️ Poster timecode: ${o}`);console.log(` \uD83D\uDE80 Starting conversion... -`);var l=new QD.default.MultiBar({format:"{stage} | {bar} | {percentage}% | {name}",barCompleteChar:"█",barIncompleteChar:"░",hideCursor:!0,clearOnComplete:!1,stopOnComplete:!0},QD.default.Presets.shades_classic),qD={},ZD=null;try{let u=await t({input:P,outputDir:Gu,customProfiles:n,posterTimecode:p,segmentDuration:2,useNvenc:Ru,generateThumbnails:!0,generatePoster:!0,parallel:!0,onProgress:(D)=>{let F=D.stage==="encoding"?"Encoding":D.stage==="thumbnails"?"Thumbnails":D.stage==="manifest"?"Manifest":D.stage==="analyzing"?"Analyzing":"Complete";if(D.stage==="encoding"&&D.currentProfile){if(!qD[D.currentProfile])qD[D.currentProfile]=l.create(100,0,{stage:"Encode",name:D.currentProfile});let C=D.profilePercent??D.percent;qD[D.currentProfile].update(C,{stage:"Encode",name:D.currentProfile})}if(!ZD)ZD=l.create(100,0,{stage:F,name:"Overall"});ZD.update(D.percent,{stage:F,name:D.message||"Overall"})}});if(l.stop(),console.log(` +`);var r=new GD.default.MultiBar({format:"{stage} | {bar} | {percentage}% | {name}",barCompleteChar:"█",barIncompleteChar:"░",hideCursor:!0,clearOnComplete:!1,stopOnComplete:!0},GD.default.Presets.shades_classic),KD={},LD=null;try{let u=await ED({input:d,outputDir:Vu,customProfiles:i,posterTimecode:o,codec:g,segmentDuration:2,useNvenc:xu,generateThumbnails:!0,generatePoster:!0,parallel:!0,onProgress:(D)=>{let F=D.stage==="encoding"?"Encoding":D.stage==="thumbnails"?"Thumbnails":D.stage==="manifest"?"Manifest":D.stage==="analyzing"?"Analyzing":"Complete";if(D.stage==="encoding"&&D.currentProfile){if(!KD[D.currentProfile])KD[D.currentProfile]=r.create(100,0,{stage:"Encode",name:D.currentProfile});let C=D.profilePercent??D.percent;KD[D.currentProfile].update(C,{stage:"Encode",name:D.currentProfile})}if(!LD)LD=r.create(100,0,{stage:F,name:"Overall"});LD.update(D.percent,{stage:F,name:D.message||"Overall"})}});if(r.stop(),console.log(` ✅ Conversion completed successfully! -`),console.log("\uD83D\uDCCA Results:"),console.log(` Manifest: ${u.manifestPath}`),console.log(` Duration: ${u.duration.toFixed(2)}s`),console.log(` Profiles: ${u.profiles.map((D)=>D.name).join(", ")}`),console.log(` Encoder: ${u.usedNvenc?"⚡ NVENC (GPU)":"\uD83D\uDD27 libx264 (CPU)"}`),u.posterPath)console.log(` Poster: ${u.posterPath}`);if(u.thumbnailSpritePath)console.log(` Thumbnails: ${u.thumbnailSpritePath}`),console.log(` VTT file: ${u.thumbnailVttPath}`);console.log(` -\uD83C\uDF89 Done! You can now use the manifest file in your video player.`)}catch(u){l.stop(),console.error(` +`),console.log("\uD83D\uDCCA Results:"),console.log(` Manifest: ${u.manifestPath}`),console.log(` Duration: ${u.duration.toFixed(2)}s`),console.log(` Profiles: ${u.profiles.map((D)=>D.name).join(", ")}`),console.log(` Codec: ${u.codecType}${u.codecType==="dual"?" (AV1 + H.264)":""}`),console.log(` Encoder: ${u.usedNvenc?"⚡ GPU accelerated":"\uD83D\uDD27 CPU"}`),u.posterPath)console.log(` Poster: ${u.posterPath}`);if(u.thumbnailSpritePath)console.log(` Thumbnails: ${u.thumbnailSpritePath}`),console.log(` VTT file: ${u.thumbnailVttPath}`);console.log(` +\uD83C\uDF89 Done! You can now use the manifest file in your video player.`)}catch(u){r.stop(),console.error(` ❌ Error during conversion:`),console.error(u),process.exit(1)} diff --git a/src/cli.ts b/src/cli.ts index c04a7d0..7668113 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -10,14 +10,16 @@ * dvc-cli ./video.mp4 ./output -r 720,1080 */ -import { convertToDash, checkFFmpeg, checkNvenc, checkMP4Box, getVideoMetadata } from './index'; +import { convertToDash, checkFFmpeg, checkNvenc, checkMP4Box, checkAV1Support, getVideoMetadata } from './index'; import cliProgress from 'cli-progress'; import { statSync } from 'node:fs'; +import type { CodecType } from './types'; // Parse arguments const args = process.argv.slice(2); let customProfiles: string[] | undefined; let posterTimecode: string | undefined; +let codecType: CodecType = 'dual'; // Default to dual codec const positionalArgs: string[] = []; // First pass: extract flags and their values @@ -43,6 +45,15 @@ for (let i = 0; i < args.length; i++) { } else if (args[i] === '-p' || args[i] === '--poster') { posterTimecode = args[i + 1]; i++; // Skip next arg + } else if (args[i] === '-c' || args[i] === '--codec') { + const codec = args[i + 1]; + if (codec === 'av1' || codec === 'h264' || codec === 'dual') { + codecType = codec; + } else { + console.error(`❌ Invalid codec: ${codec}. Valid options: av1, h264, dual`); + process.exit(1); + } + i++; // Skip next arg } else if (!args[i].startsWith('-')) { // Positional argument positionalArgs.push(args[i]); @@ -54,14 +65,21 @@ const input = positionalArgs[0]; const outputDir = positionalArgs[1] || '.'; // Текущая директория по умолчанию if (!input) { - console.error('❌ Usage: dvc-cli [output-dir] [-r resolutions] [-p poster-timecode]'); + console.error('❌ Usage: dvc-cli [output-dir] [-r resolutions] [-c codec] [-p poster-timecode]'); + console.error('\nOptions:'); + console.error(' -r, --resolutions Video resolutions (e.g., 360,480,720 or 720@60,1080@60)'); + console.error(' -c, --codec Video codec: av1, h264, or dual (default: dual)'); + console.error(' -p, --poster Poster timecode (e.g., 00:00:05 or 10)'); console.error('\nExamples:'); console.error(' dvc-cli video.mp4'); console.error(' dvc-cli video.mp4 ./output'); console.error(' dvc-cli video.mp4 -r 360,480,720'); - console.error(' dvc-cli video.mp4 -r 720@60,1080@60,2160@60'); + console.error(' dvc-cli video.mp4 -c av1'); + console.error(' dvc-cli video.mp4 -c h264'); + console.error(' dvc-cli video.mp4 -c dual'); + console.error(' dvc-cli video.mp4 -r 720@60,1080@60,2160@60 -c av1'); console.error(' dvc-cli video.mp4 -p 00:00:05'); - console.error(' dvc-cli video.mp4 ./output -r 720,1080 -p 10'); + console.error(' dvc-cli video.mp4 ./output -r 720,1080 -c dual -p 10'); process.exit(1); } @@ -69,10 +87,16 @@ console.log('🔍 Checking system...\n'); const hasFFmpeg = await checkFFmpeg(); const hasNvenc = await checkNvenc(); +const av1Support = await checkAV1Support(); const hasMP4Box = await checkMP4Box(); console.log(`FFmpeg: ${hasFFmpeg ? '✅' : '❌'}`); -console.log(`NVENC: ${hasNvenc ? '✅ (GPU acceleration)' : '⚠️ (CPU only)'}`); +console.log(`NVENC (H.264): ${hasNvenc ? '✅ (GPU acceleration)' : '⚠️ (CPU only)'}`); +if (av1Support.available) { + console.log(`AV1 Encoder: ✅ ${av1Support.encoder} (GPU acceleration)`); +} else { + console.log(`AV1 Encoder: ⚠️ (not available, will use CPU fallback)`); +} console.log(`MP4Box: ${hasMP4Box ? '✅' : '❌'}\n`); if (!hasFFmpeg) { @@ -85,6 +109,13 @@ if (!hasMP4Box) { process.exit(1); } +// Validate codec selection +if ((codecType === 'av1' || codecType === 'dual') && !av1Support.available) { + console.error(`⚠️ Warning: AV1 encoding requested but no hardware AV1 encoder found.`); + console.error(` CPU-based AV1 encoding (libsvtav1) will be VERY slow.`); + console.error(` Consider using --codec h264 for faster encoding.\n`); +} + // Get video metadata and file size console.log('📊 Analyzing video...\n'); const metadata = await getVideoMetadata(input); @@ -105,6 +136,7 @@ if (metadata.audioBitrate) { console.log(` Audio Bitrate: ${metadata.audioBitrate} kbps`); } console.log(`\n📁 Output: ${outputDir}`); +console.log(`🎬 Codec: ${codecType}${codecType === 'dual' ? ' (AV1 + H.264 for maximum compatibility)' : ''}`); if (customProfiles) { console.log(`🎯 Custom profiles: ${customProfiles.join(', ')}`); } @@ -133,6 +165,7 @@ try { outputDir, customProfiles, posterTimecode, + codec: codecType, segmentDuration: 2, useNvenc: hasNvenc, generateThumbnails: true, @@ -182,7 +215,8 @@ try { console.log(` Manifest: ${result.manifestPath}`); console.log(` Duration: ${result.duration.toFixed(2)}s`); console.log(` Profiles: ${result.profiles.map(p => p.name).join(', ')}`); - console.log(` Encoder: ${result.usedNvenc ? '⚡ NVENC (GPU)' : '🔧 libx264 (CPU)'}`); + console.log(` Codec: ${result.codecType}${result.codecType === 'dual' ? ' (AV1 + H.264)' : ''}`); + console.log(` Encoder: ${result.usedNvenc ? '⚡ GPU accelerated' : '🔧 CPU'}`); if (result.posterPath) { console.log(` Poster: ${result.posterPath}`); diff --git a/src/core/converter.ts b/src/core/converter.ts index e77e582..2edb011 100644 --- a/src/core/converter.ts +++ b/src/core/converter.ts @@ -6,12 +6,14 @@ import type { DashConvertResult, VideoProfile, ThumbnailConfig, - ConversionProgress + ConversionProgress, + CodecType } from '../types'; import { checkFFmpeg, checkMP4Box, checkNvenc, + checkAV1Support, getVideoMetadata, ensureDir } from '../utils'; @@ -33,6 +35,7 @@ export async function convertToDash( segmentDuration = 2, profiles: userProfiles, customProfiles, + codec = 'dual', useNvenc, generateThumbnails = true, thumbnailConfig = {}, @@ -54,6 +57,7 @@ export async function convertToDash( segmentDuration, userProfiles, customProfiles, + codec, useNvenc, generateThumbnails, thumbnailConfig, @@ -82,6 +86,7 @@ async function convertToDashInternal( segmentDuration: number, userProfiles: VideoProfile[] | undefined, customProfiles: string[] | undefined, + codec: CodecType, useNvenc: boolean | undefined, generateThumbnails: boolean, thumbnailConfig: ThumbnailConfig, @@ -177,61 +182,92 @@ async function convertToDashInternal( await ensureDir(videoOutputDir); - reportProgress('analyzing', 20, `Using ${willUseNvenc ? 'NVENC' : 'CPU'} encoding`, undefined); + // Determine which codecs to use based on codec parameter + const codecs: Array<{ type: 'h264' | 'av1'; codec: string; preset: string }> = []; + + if (codec === 'h264' || codec === 'dual') { + const h264Codec = willUseNvenc ? 'h264_nvenc' : 'libx264'; + const h264Preset = willUseNvenc ? 'p4' : 'medium'; + codecs.push({ type: 'h264', codec: h264Codec, preset: h264Preset }); + } + + if (codec === 'av1' || codec === 'dual') { + // Check for AV1 hardware encoder + const av1Support = await checkAV1Support(); + const av1Codec = av1Support.available ? av1Support.encoder! : 'libsvtav1'; + const av1Preset = av1Support.available ? (av1Codec === 'av1_nvenc' ? 'p4' : 'medium') : '8'; + codecs.push({ type: 'av1', codec: av1Codec, preset: av1Preset }); + } + + const codecNames = codecs.map(c => c.type.toUpperCase()).join(' + '); + reportProgress('analyzing', 20, `Using ${codecNames} encoding (${willUseNvenc ? 'GPU' : 'CPU'})`, undefined); - // Video codec selection - const videoCodec = willUseNvenc ? 'h264_nvenc' : 'libx264'; - const codecPreset = willUseNvenc ? 'p4' : 'medium'; const maxConcurrent = willUseNvenc ? 3 : 2; - // STAGE 1: Encode profiles to MP4 (parallel - heavy work) - reportProgress('encoding', 25, `Stage 1: Encoding ${profiles.length} profiles to MP4...`); + // STAGE 1: Encode profiles to MP4 for each codec (parallel - heavy work) + const codecMP4Paths = new Map<'h264' | 'av1', Map>(); - const tempMP4Paths = await encodeProfilesToMP4( - input, - tempDir, - profiles, - videoCodec, - codecPreset, - metadata.duration, - segmentDuration, - metadata.fps || 25, // Use detected FPS or default to 25 - metadata.audioBitrate, // Source audio bitrate for smart selection - parallel, - maxConcurrent, - undefined, // optimizations - for future use - (profileName, percent) => { - const profileIndex = profiles.findIndex(p => p.name === profileName); - const baseProgress = 25 + (profileIndex / profiles.length) * 40; - const profileProgress = (percent / 100) * (40 / profiles.length); - reportProgress('encoding', baseProgress + profileProgress, `Encoding ${profileName}...`, profileName); - - // Also report individual profile progress - if (onProgress) { - onProgress({ - stage: 'encoding', - percent: baseProgress + profileProgress, - currentProfile: profileName, - profilePercent: percent, // Actual profile progress 0-100 - message: `Encoding ${profileName}...` - }); + for (let codecIndex = 0; codecIndex < codecs.length; codecIndex++) { + const { type, codec: videoCodec, preset: codecPreset } = codecs[codecIndex]; + const codecProgress = codecIndex / codecs.length; + const codecProgressRange = 1 / codecs.length; + + reportProgress('encoding', 25 + codecProgress * 40, `Stage 1: Encoding ${type.toUpperCase()} (${profiles.length} profiles)...`); + + const tempMP4Paths = await encodeProfilesToMP4( + input, + tempDir, + profiles, + videoCodec, + codecPreset, + metadata.duration, + segmentDuration, + metadata.fps || 25, + metadata.audioBitrate, + parallel, + maxConcurrent, + type, // Pass codec type to differentiate output files + undefined, // optimizations - for future use + (profileName, percent) => { + const profileIndex = profiles.findIndex(p => p.name === profileName); + const baseProgress = 25 + codecProgress * 40; + const profileProgress = (percent / 100) * (40 * codecProgressRange / profiles.length); + reportProgress('encoding', baseProgress + profileProgress, `Encoding ${type.toUpperCase()} ${profileName}...`, `${type}-${profileName}`); + + // Also report individual profile progress + if (onProgress) { + onProgress({ + stage: 'encoding', + percent: baseProgress + profileProgress, + currentProfile: `${type}-${profileName}`, + profilePercent: percent, + message: `Encoding ${type.toUpperCase()} ${profileName}...` + }); + } } - } - ); + ); + + codecMP4Paths.set(type, tempMP4Paths); + } - reportProgress('encoding', 65, 'Stage 1 complete: All profiles encoded'); + reportProgress('encoding', 65, 'Stage 1 complete: All codecs and profiles encoded'); // STAGE 2: Package to DASH using MP4Box (light work, fast) reportProgress('encoding', 70, `Stage 2: Creating DASH with MP4Box...`); const manifestPath = await packageToDash( - tempMP4Paths, + codecMP4Paths, videoOutputDir, profiles, - segmentDuration + segmentDuration, + codec ); - const videoPaths = Array.from(tempMP4Paths.values()); + // Collect all video paths from all codecs + const videoPaths: string[] = []; + for (const mp4Paths of codecMP4Paths.values()) { + videoPaths.push(...Array.from(mp4Paths.values())); + } reportProgress('encoding', 80, 'Stage 2 complete: DASH created'); @@ -293,7 +329,8 @@ async function convertToDashInternal( posterPath, duration: metadata.duration, profiles, - usedNvenc: willUseNvenc + usedNvenc: willUseNvenc, + codecType: codec }; } diff --git a/src/core/encoding.ts b/src/core/encoding.ts index dfd12de..74cabbd 100644 --- a/src/core/encoding.ts +++ b/src/core/encoding.ts @@ -16,10 +16,11 @@ export async function encodeProfileToMP4( segmentDuration: number, fps: number, sourceAudioBitrate: number | undefined, + codecType: 'h264' | 'av1', optimizations?: VideoOptimizations, onProgress?: (percent: number) => void ): Promise { - const outputPath = join(tempDir, `video_${profile.name}.mp4`); + const outputPath = join(tempDir, `video_${codecType}_${profile.name}.mp4`); const args = [ '-y', @@ -27,20 +28,44 @@ export async function encodeProfileToMP4( '-c:v', videoCodec ]; - // Add NVENC specific options + // Add codec-specific options if (videoCodec === 'h264_nvenc') { + // NVIDIA H.264 args.push('-rc:v', 'vbr'); args.push('-preset', preset); args.push('-2pass', '0'); + } else if (videoCodec === 'av1_nvenc') { + // NVIDIA AV1 + args.push('-rc:v', 'vbr'); + args.push('-preset', preset); + args.push('-2pass', '0'); + } else if (videoCodec === 'av1_qsv') { + // Intel QSV AV1 + args.push('-preset', preset); + args.push('-global_quality', '23'); // Quality level for QSV + } else if (videoCodec === 'av1_amf') { + // AMD AMF AV1 + args.push('-quality', 'balanced'); + args.push('-rc', 'vbr_latency'); + } else if (videoCodec === 'libsvtav1') { + // CPU-based SVT-AV1 + args.push('-preset', preset); // 0-13, 8 is medium speed + args.push('-svtav1-params', 'tune=0:enable-overlays=1'); } else { + // Default (libx264, libx265, etc.) args.push('-preset', preset); } // Video encoding parameters + // AV1 is ~40% more efficient than H.264 at same quality (Netflix/YouTube standard) + const bitrateMultiplier = codecType === 'av1' ? 0.6 : 1.0; + const targetBitrate = Math.round(parseInt(profile.videoBitrate) * bitrateMultiplier); + const bitrateString = `${targetBitrate}k`; + args.push( - '-b:v', profile.videoBitrate, - '-maxrate', profile.videoBitrate, - '-bufsize', `${parseInt(profile.videoBitrate) * 2}k` + '-b:v', bitrateString, + '-maxrate', bitrateString, + '-bufsize', `${targetBitrate * 2}k` ); // Set GOP size for DASH segments @@ -105,6 +130,7 @@ export async function encodeProfilesToMP4( sourceAudioBitrate: number | undefined, parallel: boolean, maxConcurrent: number, + codecType: 'h264' | 'av1', optimizations?: VideoOptimizations, onProgress?: (profileName: string, percent: number) => void ): Promise> { @@ -125,6 +151,7 @@ export async function encodeProfilesToMP4( segmentDuration, fps, sourceAudioBitrate, + codecType, optimizations, (percent) => { if (onProgress) { @@ -153,6 +180,7 @@ export async function encodeProfilesToMP4( segmentDuration, fps, sourceAudioBitrate, + codecType, optimizations, (percent) => { if (onProgress) { diff --git a/src/core/packaging.ts b/src/core/packaging.ts index f4ffc73..468ef85 100644 --- a/src/core/packaging.ts +++ b/src/core/packaging.ts @@ -1,17 +1,18 @@ import { join } from 'node:path'; import { execMP4Box } from '../utils'; -import type { VideoProfile } from '../types'; +import type { VideoProfile, CodecType } from '../types'; /** * Package MP4 files into DASH format using MP4Box * Stage 2: Light work - just packaging, no encoding - * Creates one master MPD manifest with all profiles + * Creates one master MPD manifest with all profiles and codecs */ export async function packageToDash( - mp4Files: Map, + codecMP4Files: Map<'h264' | 'av1', Map>, outputDir: string, profiles: VideoProfile[], - segmentDuration: number + segmentDuration: number, + codecType: CodecType ): Promise { const manifestPath = join(outputDir, 'manifest.mpd'); @@ -20,22 +21,32 @@ export async function packageToDash( '-dash', String(segmentDuration * 1000), // MP4Box expects milliseconds '-frag', String(segmentDuration * 1000), '-rap', // Force segments to start with random access points + '-segment-timeline', // Use SegmentTimeline for accurate segment durations '-segment-name', '$RepresentationID$_$Number$', '-out', manifestPath ]; - // Add all MP4 files with their profile IDs - for (const profile of profiles) { - const mp4Path = mp4Files.get(profile.name); - if (!mp4Path) { - throw new Error(`MP4 file not found for profile: ${profile.name}`); - } - - // Add video track with representation ID - args.push(`${mp4Path}#video:id=${profile.name}`); - // Add audio track (shared across all profiles) - if (profile === profiles[0]) { - args.push(`${mp4Path}#audio:id=audio`); + // Add all MP4 files for each codec + let firstFile = true; + + for (const [codec, mp4Files] of codecMP4Files.entries()) { + for (const profile of profiles) { + const mp4Path = mp4Files.get(profile.name); + if (!mp4Path) { + throw new Error(`MP4 file not found for profile: ${profile.name}, codec: ${codec}`); + } + + // Representation ID includes codec: e.g., "720p-h264", "720p-av1" + const representationId = codecType === 'dual' ? `${profile.name}-${codec}` : profile.name; + + // Add video track with representation ID + args.push(`${mp4Path}#video:id=${representationId}`); + + // Add audio track only once (shared across all profiles and codecs) + if (firstFile) { + args.push(`${mp4Path}#audio:id=audio`); + firstFile = false; + } } } @@ -44,10 +55,10 @@ export async function packageToDash( // MP4Box creates files in the same directory as output MPD // Move segment files to profile subdirectories for clean structure - await organizeSegments(outputDir, profiles); + await organizeSegments(outputDir, profiles, codecType); // Update MPD to reflect new file structure with subdirectories - await updateManifestPaths(manifestPath, profiles); + await updateManifestPaths(manifestPath, profiles, codecType); return manifestPath; } @@ -58,14 +69,27 @@ export async function packageToDash( */ async function organizeSegments( outputDir: string, - profiles: VideoProfile[] + profiles: VideoProfile[], + codecType: CodecType ): Promise { const { readdir, rename, mkdir } = await import('node:fs/promises'); - // Create profile subdirectories - for (const profile of profiles) { - const profileDir = join(outputDir, profile.name); - await mkdir(profileDir, { recursive: true }); + // For dual-codec mode, create codec-specific subdirectories (e.g., "720p-h264/", "720p-av1/") + // For single-codec mode, use simple profile names (e.g., "720p/") + const codecs: Array<'h264' | 'av1'> = []; + if (codecType === 'h264' || codecType === 'dual') codecs.push('h264'); + if (codecType === 'av1' || codecType === 'dual') codecs.push('av1'); + + const representationIds: string[] = []; + + for (const codec of codecs) { + for (const profile of profiles) { + const repId = codecType === 'dual' ? `${profile.name}-${codec}` : profile.name; + representationIds.push(repId); + + const profileDir = join(outputDir, repId); + await mkdir(profileDir, { recursive: true }); + } } // Create audio subdirectory @@ -90,11 +114,11 @@ async function organizeSegments( continue; } - // Move video segment files to their profile directories - for (const profile of profiles) { - if (file.startsWith(`${profile.name}_`)) { + // Move video segment files to their representation directories + for (const repId of representationIds) { + if (file.startsWith(`${repId}_`)) { const oldPath = join(outputDir, file); - const newPath = join(outputDir, profile.name, file); + const newPath = join(outputDir, repId, file); await rename(oldPath, newPath); break; } @@ -107,7 +131,8 @@ async function organizeSegments( */ async function updateManifestPaths( manifestPath: string, - profiles: VideoProfile[] + profiles: VideoProfile[], + codecType: CodecType ): Promise { const { readFile, writeFile } = await import('node:fs/promises'); diff --git a/src/index.ts b/src/index.ts index a20b510..e354f32 100644 --- a/src/index.ts +++ b/src/index.ts @@ -9,7 +9,8 @@ export type { ThumbnailConfig, ConversionProgress, VideoMetadata, - VideoOptimizations + VideoOptimizations, + CodecType } from './types'; // Utility exports @@ -17,6 +18,7 @@ export { checkFFmpeg, checkMP4Box, checkNvenc, + checkAV1Support, getVideoMetadata, selectAudioBitrate } from './utils'; diff --git a/src/types/index.ts b/src/types/index.ts index 7d81a96..7c76ea7 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -1,3 +1,8 @@ +/** + * Video codec type for encoding + */ +export type CodecType = 'av1' | 'h264' | 'dual'; + /** * Configuration options for DASH conversion */ @@ -17,6 +22,9 @@ export interface DashConvertOptions { /** Custom resolution profiles as strings (e.g., ['360p', '480p', '720p@60']) */ customProfiles?: string[]; + /** Video codec to use: 'av1', 'h264', or 'dual' for both (default: 'dual') */ + codec?: CodecType; + /** Enable NVENC hardware acceleration (auto-detect if undefined) */ useNvenc?: boolean; @@ -123,6 +131,9 @@ export interface DashConvertResult { /** Whether NVENC was used */ usedNvenc: boolean; + + /** Codec type used for encoding */ + codecType: CodecType; } /** diff --git a/src/utils/index.ts b/src/utils/index.ts index ca3f1bb..1082958 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -3,6 +3,7 @@ export { checkFFmpeg, checkMP4Box, checkNvenc, + checkAV1Support, execFFmpeg, execMP4Box } from './system'; diff --git a/src/utils/system.ts b/src/utils/system.ts index ad2511d..c1118b7 100644 --- a/src/utils/system.ts +++ b/src/utils/system.ts @@ -45,6 +45,42 @@ export async function checkNvenc(): Promise { }); } +/** + * Check if AV1 hardware encoding is available + * Supports: NVENC (RTX 40xx), QSV (Intel 11+), AMF (AMD RX 7000) + */ +export async function checkAV1Support(): Promise<{ + available: boolean; + encoder?: 'av1_nvenc' | 'av1_qsv' | 'av1_amf'; +}> { + return new Promise((resolve) => { + const proc = spawn('ffmpeg', ['-hide_banner', '-encoders']); + let output = ''; + + proc.stdout.on('data', (data) => { + output += data.toString(); + }); + + proc.on('error', () => resolve({ available: false })); + proc.on('close', (code) => { + if (code !== 0) { + resolve({ available: false }); + } else { + // Check for hardware AV1 encoders in order of preference + if (output.includes('av1_nvenc')) { + resolve({ available: true, encoder: 'av1_nvenc' }); + } else if (output.includes('av1_qsv')) { + resolve({ available: true, encoder: 'av1_qsv' }); + } else if (output.includes('av1_amf')) { + resolve({ available: true, encoder: 'av1_amf' }); + } else { + resolve({ available: false }); + } + } + }); + }); +} + /** * Execute FFmpeg command with progress tracking */